Spring Boot&Caching 3 – Memcached

Merhabalar.

Bu yazıda bir Spring Boot projesinde Memcached ile cache’lemenin nasıl yapıldığını anlatmaya çalışacağım.

AMAÇ:

Bu yazıda Spring Boot ve Memcached’in nasıl beraber kullanılacağının gösterilmesi amaçlanmaktadır.

VERİ SETİ:

Veritabanımda driver tablomda şu şekilde 10 kayıt bulunmakta. Şimdi yapacağımız örnekte ben id ile bir sorgulama yapacağım ve Memcached ile cache’lemenin bu sorgulamadaki performans etkisini inceleyeceğiz.

ÖRNEK KODLAR:

Şimdi bir önceki yazımız olan Spring Boot&Caching 2 – Redis yazısının üzerine bu yazımızı inşa edeceğiz.

İlk olarak pom.xml’de spring-boot-starter-data-redis bağımlılığını kaldırıp yerine aşağıdaki 2 bağımlılığı ekliyoruz. Bu 2 bağımlılık bir Spring Boot uygulamasının Memcached’e bağlantı ve veri koyma ayarlarının yapılması için gerekli.

        <dependency>
            <groupId>com.google.code.simple-spring-memcached</groupId>
            <artifactId>spymemcached-provider</artifactId>
            <version>4.0.0</version>
        </dependency>

        <dependency>
            <groupId>com.google.code.simple-spring-memcached</groupId>
            <artifactId>spring-cache</artifactId>
            <version>4.0.0</version>
        </dependency>

Akabinde aşağıdaki MemCacheConfig sınıfımızı yazıyoruz. Bu sınıf yukarıdaki bağımlılıkları kullanarak MemCache’e bağlantı kuracak.

package com.ilkaygunel.config;

import com.google.code.ssm.Cache; 
import com.google.code.ssm.CacheFactory;
import com.google.code.ssm.config.AbstractSSMConfiguration;
import com.google.code.ssm.config.DefaultAddressProvider;
import com.google.code.ssm.providers.spymemcached.MemcacheClientFactoryImpl;
import com.google.code.ssm.providers.spymemcached.SpymemcachedConfiguration;
import com.google.code.ssm.spring.ExtendedSSMCacheManager;
import com.google.code.ssm.spring.SSMCache;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;

@Configuration
public class MemCacheConfig extends AbstractSSMConfiguration {

    @Bean
    @Override
    public CacheFactory defaultMemcachedClient() {
        String serverString = "localhost:11211";

        final SpymemcachedConfiguration conf = new SpymemcachedConfiguration();
        conf.setUseBinaryProtocol(true);

        final CacheFactory cf = new CacheFactory();
        cf.setCacheClientFactory(new MemcacheClientFactoryImpl());
        cf.setAddressProvider(new DefaultAddressProvider(serverString));
        cf.setConfiguration(conf);
        cf.setCacheName("drivers");
        return cf;
    }

    @Bean
    public CacheManager cacheManager() throws Exception {
        ExtendedSSMCacheManager cacheManager = new ExtendedSSMCacheManager();
        Cache cache = this.defaultMemcachedClient().getObject();
        cacheManager.setCaches(Arrays.asList(new SSMCache(cache, 0, false)));
        return cacheManager;
    }

}

Sınıf içerisindeki defaultMemcachedClient metodu AbstractSSMConfiguration sıfından zorunlu olarak kalıttığımız metottur. defaultMemcachedClient metodu ile hangi adrese bağlantı kuracağımızı belirliyoruz ve bir CacheFactory objesi oluşturup dönüyoruz. Bu metot içerisinde önemli olan bir nokta setCacheName metodunun çağırıldığı kısım. MemCached kullanılırken cache kümesinin önceden tanıtılması ve oluşturulması gerekiyor. Bu nedenle uygulama ayağa kalkarken ilgili cache kümesinin ismini kayda geçiriyoruz. Eğer herhangi bir isim kayda geçirmezsek MemCached default isminde bir cache kümesini kayda geçiriyor.

Diğer metodumuz olan cacheManager metodumuz ise arka planda cache’e veri koyma, cache’den veri getirme vs operasyonlarını yönetecek.

Memcached’e özel yapacağımız ayarlamalar bu kadar. Gerisi önceki yazı ile aynı. Şimdi demo yapalım.

DEMO:

Şimdi http://localhost:8080/driver/driver/4 adresine istek gönderiyorum ve 4 id’li driver’ı getiriyorum. Ardından aynı isteği 2 kez daha tekrarlıyorum ve loga baktığımda ilk getirme işleminin 475 ms kadar sürdüğünü, peşinden yapılan iki isteğin ise 10 ve 5 ms sürdüğünü görüyorum.

2023-03-26 14:34:37.913 INFO 15059 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-03-26 14:34:37.924 INFO 15059 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2023-03-26 14:34:37.928 INFO 15059 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 4 ms
2023-03-26 14:34:38.400 INFO 15059 --- [nio-8080-exec-2] com.google.code.ssm.spring.SSMCache : Cache miss. Get by key 4 from cache drivers
2023-03-26 14:34:38.630 INFO 15059 --- [nio-8080-exec-2] com.google.code.ssm.spring.SSMCache : Put 'com.ilkaygunel.entities.Driver@3d085f5c' under key 4 to cache drivers
2023-03-26 14:34:38.649 INFO 15059 --- [nio-8080-exec-2] com.ilkaygunel.api.DriverController : Elapsed Time in getDriverById: 475 ms
2023-03-26 14:34:52.769 INFO 15059 --- [nio-8080-exec-3] com.google.code.ssm.spring.SSMCache : Cache hit. Get by key 4 from cache drivers value 'com.ilkaygunel.entities.Driver@5b134cb4'
2023-03-26 14:34:52.770 INFO 15059 --- [nio-8080-exec-3] com.ilkaygunel.api.DriverController : Elapsed Time in getDriverById: 10 ms
2023-03-26 14:35:01.084 INFO 15059 --- [nio-8080-exec-4] com.google.code.ssm.spring.SSMCache : Cache hit. Get by key 4 from cache drivers value 'com.ilkaygunel.entities.Driver@5c8620a7'
2023-03-26 14:35:01.084 INFO 15059 --- [nio-8080-exec-4] com.ilkaygunel.api.DriverController : Elapsed Time in getDriverById: 5 ms

Memcache’de tutulan verileri kontrol ettiğimde 4 id’li sürücüyü çektiğim için onun cache içerisinde yer aldığını görüyorum.

Şimdi, http://localhost:8080/driver/driver/2 adresine istek gönderiyorum ve ilk istek 213 ms sürüyor. Sonraki isteklerde ise süre 18 ms’ye kadar iniyor.

2023-03-26 15:42:43.899 INFO 16654 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-03-26 15:42:43.902 INFO 16654 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2023-03-26 15:42:43.904 INFO 16654 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms
2023-03-26 15:42:44.039 INFO 16654 --- [nio-8080-exec-2] com.google.code.ssm.spring.SSMCache : Cache miss. Get by key 2 from cache drivers
2023-03-26 15:42:44.174 INFO 16654 --- [nio-8080-exec-2] com.google.code.ssm.spring.SSMCache : Put 'com.ilkaygunel.entities.Driver@31de18db' under key 2 to cache drivers
2023-03-26 15:42:44.220 INFO 16654 --- [nio-8080-exec-2] com.ilkaygunel.api.DriverController : Elapsed Time in getDriverById: 213 ms
2023-03-26 15:43:10.956 INFO 16654 --- [nio-8080-exec-3] com.google.code.ssm.spring.SSMCache : Cache hit. Get by key 2 from cache drivers value 'com.ilkaygunel.entities.Driver@5177787'
2023-03-26 15:43:10.963 INFO 16654 --- [nio-8080-exec-3] com.ilkaygunel.api.DriverController : Elapsed Time in getDriverById: 33 ms
2023-03-26 15:43:15.030 INFO 16654 --- [nio-8080-exec-4] com.google.code.ssm.spring.SSMCache : Cache hit. Get by key 2 from cache drivers value 'com.ilkaygunel.entities.Driver@55d4a87e'
2023-03-26 15:43:15.057 INFO 16654 --- [nio-8080-exec-4] com.ilkaygunel.api.DriverController : Elapsed Time in getDriverById: 60 ms
2023-03-26 15:43:18.686 INFO 16654 --- [nio-8080-exec-5] com.google.code.ssm.spring.SSMCache : Cache hit. Get by key 2 from cache drivers value 'com.ilkaygunel.entities.Driver@5241c547'
2023-03-26 15:43:18.687 INFO 16654 --- [nio-8080-exec-5] com.ilkaygunel.api.DriverController : Elapsed Time in getDriverById: 18 ms

Cache'i kontrol ettiğimde ise 4 id'li driver'ın yanında 9 id'li driver da cache'e eklenmiş durumda. 

Bu yazıda anlatacaklarım bu kadar arkadaşlar. Geri kalan tüm işlemler önceki yazımızdaki ile aynı. Spring’in cache anotasyonları olduğu gibi kullanılabilir yine.

Başka bir yazıda görüşene kadar hoşçakalın.

Latest posts by İlkay Günel (see all)

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir