Spring Boot ve Caching
Merhabalar, bugün sizlere Caching’ten ve Redis’ten bahsedeğim.
Caching, sistemin gelen her request için veritabanına gitmesini engeller. Eğer bir sorgunun sonucu cache’de varsa, daha önceden edinilmişse, bunu cache’dan getirerek veritabanı trafiği oluşmasını önler. Vereceğimiz şartlara göre cache’deki verinin veritabanına aktarılması da mümkündür.
Çok fazla sorgulama yapılan uygulamalarda sorgu caching’i yaparak önemli bir performans artışı sağlanabilmektedir.
Hangi veriler önbelleğe alınmalıdır?
Bir kaç örnek verecek olursam:
— Bir e-ticaret sitesinde bulunan ürünlerin listesi.
— Sıklıkla değiştirilmeyen veriler.
— Sık kullanılan herhangi bir veritabanı okuma sorgusu(sonuç her aramada en azından belirli bir süre için değişmez.)
Caching Türleri
In-memory caching
Uygulamanın performansını artırmak için en sık kullanılan caching türüdür. Memcached ve Redis gibi in-memory cacheler, uygulamanız ve veri depolama alanınız arasındaki key-value depolarıdır. Veriler RAM’de tutulduğundan, tipik veritabanlarından çok daha hızlıdır.
Database Caching
Veritabanları genellikle genel bir kullanım durumu için optimize edilmiş varsayılan bir yapılandırmada bir miktar önbelleğe alma(caching) içerir. Bu ayarları belirli kullanım modelleri için değiştirmek performansı daha da artırabilir. Bu alanda popüler olanlardan biri, Hibernate veya herhangi bir ORM frameworkünün birinci seviye önbelleğidir(cache).
Web Server Caching
Web serverlar da istekleri önbelleğe alabilir ve uygulama sunucularına başvurmak zorunda kalmadan yanıtları geri verebilir.
CDN Caching
Cacheler, istemci(client) tarafında (işletim sistemi veya tarayıcı), sunucu(server) tarafında veya farklı bir önbellek katmanında bulunabilir.
Cache Provider(Önbellek Sağlayıcıları)
- JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, …)
- EhCache 2.x
- Hazelcast
- Infinispan
- Couchbase
- Redis
- Caffeine
- Simple cache
Spring Boot ve Caching
Şimdiiii projemizi yapmaya başlayalım. Bu örnekte Spring Boot da varsayılan caching i nasıl etkinleştirebileceğimizi göreceğiz. Son olarak, aynı yöntemin tekrarlanan çağrısı üzerinde uygulama performansını test edeceğiz.
Öncelikle Spring Initializr dan bir Spring Boot projesi oluşturalım.
Eveett şimdi kodumuzu yazmaya başlayabiliriz. Öncelikle application.yml dosyamızda database ayarlarını yapalım.
Daha sonra Person adında bir class oluşturalım.
Ardından Repository classımızı oluşturalım.
Ardından service classımızı oluşturalım.
@Cacheable
anotasyonu, ilk metod çağrısından sonra cevabı önbelleğe alır ve sonraki çağrılarda önbellekten cevap dönmemizi sağlar. Böylece, persons
listesini her istediğimizde 2 saniye beklemek zorunda kalmayız. Anotasyona value olarak persons
değerini veriyoruz. (Daha sonra bu önbelleği yönetebilmemiz için lazım olacak.)
@CachePut, @Cacheable ve @CacheEvict
anotasyonlarında bulunan key değeri, önbellekte hangi değerle işlem yapacağımızı bildirir. Bu key değerini setlemek için SpEL expression kullanılabilir.
Bazen, bir data her zaman önbelleğe almak için uygun olmayabilir. @CachePut, @Cacheable ve @CacheEvict
anotasyonlarında bulunan condition parametresi, true veya false olarak değerlendirilen bir SpEL ifadesini alan koşullu parametre aracılığıyla bu tür işlevselliği destekler. True ise, data cache’e alınır değilse, data cache’e alınmamış gibi davranır.
@CachePut, @Cacheable ve @CacheEvict
anotasyonlarında bulunan unless parametresi aracılığıyla, condition parametresinden farklı olarak yapılan girdiden ziyade çıktıya göre cache’e almayı kontrol edebiliriz.
@CacheEvict
anotasyonunda bulunan allEntries parametresi, cache(ler) içindeki tüm entrylerin kaldırılıp kaldırılmayacağını belirtir.
SpEL Expression
Ardından bu classımızı çağıracak apimizin olduğu controller classımızı oluşturalım.
Şimdi Application classımıza “@EnableCaching” anotasyonunu ekleyerek sonuçlarımızı kontrol edelim…
NOT: İstediğimiz zaman bu özelliği devre dışı bırakmak istersek Caching ile işaretlediğimiz tüm anotasyonları silmemize gerek yok. Spring Boot uygulamamızın application.yml dosyasına aşağıdaki kodu yazmamız yeterlidir.
Postman aracılığıyla apilerimizi test edelim… Öncelikle bir kaç tane person create edelim ardından tüm personları getirecek olan apiyi test edelim.
Şimdi ilgili name’e ait olan person’ı getirelim ve sonuçlarımızı görelim.
Şimdi conditionlara uymayan bir person için deneme yapalım.( condition = “#name.length() > 4”, unless = “#result.age < 24”)
…/person/cacheClear veya …/person/delete/all apisine istek attığımızda cache de bulunan dataları silebiliriz.
Şimdi Redis’e gelelim :)
Spring Boot ve Redis
Redis, bir NoSQL veritabanıdır. Kullanıldığı yaygın alanlardan birisi Caching işlemleridir. Gecikmeyi azaltmak, uygulamanın verimini artırmak için bir in-memory cache(önbellek) olanağı sağlar.
NOT: Redis için, 64 bitlik bir sistemde veri depolama konusunda bir sınırlama yoktur, ancak 32 bit sistemde yalnızca 3 GB depolayabilir.
Projemizi yazmaya başlamadan önce docker image’i ayağa kaldıralım. Bunun için terminali açıp “ docker run -p 6379:6379 — name fd-redis -d redis” komutunu yazalım. Komut çalıştırıldığında Docker Hub’dan Redis image’ı çekilmiş ve ayağa kaldırılmış olacak.
Bunu yapmadan önce Docker ile alakalı yazıma göz atabilirsiniz.
“docker ps” komutu ile ayakta olan container’ları listeleyelim.
Şimdi kodumuzu yazmaya başlayabiliriz…
Öncelikle Spring Initializr dan bir Spring Boot projesi oluşturalım.
Projeyi indirdikten sonra build.gradle dosyasına “implementation group: ‘redis.clients’, name: ‘jedis’, version: ‘2.8.0’” ekleyelim. Bu sayede Spring Boot’un Redis’e bağlanması için gerekli bir dependency eklemiş olduk.
Spring Boot Redis Configuration
1- Java Tabanlı Configuration
Redis bağlantı ayarlarını tanımlamak için bir konfigürasyon sınıfı oluşturmamız gerekiyor.
RedisConfig adında bir class oluşturalım.
2- Property File Tabanlı Configuration
Spring Boot uygulamasında redis önbelleğini yapılandırmak için gereken application.yml içeriği:
Şimdi Application classımıza “@EnableCaching” anotasyonunu ekleyerek sonuçlarımızı kontrol edelim…
Diğer tüm kodları Github profilimde bulabilirsiniz :)
Postman aracılığıyla apilerimizi test edelim…
2. isteğimizi atıp sonuçları görelim.