Spring boot 에 caffeine cache 적용하기
● 개요
일정기간 변경되지 않는 데이터에 대해 잦은 호출로 인하여 서버 자원 낭비를 방지하고자 cache를 활용하고자 한다.
● java cache 라이브러리
java cache에 활용되는 라이브러리를 살펴 보았다.
1. springboot cache
springboot에서 지원하는 cache로 auto cofingired되어 설정에 대한 부분이 편리하다.
(https://spring.io/guides/gs/caching/)
2. caffeine cache
캐시를 읽고 쓰는 속도에서 가장 좋은 성능을 보여주는 라이브러리로 설정도 편리하다.
속도 측정 참고- https://github.com/ben-manes/caffeine/wiki/Benchmarks
3. ehcache
cache 라이브러리중 가장 많은 기능을 지원한다. 서버 간 분산캐시, 동기/비동기, 디스크 저장 지원등
- 프로젝트를 단순 캐시 저장후 조회만 하면 되기 때문에 캐시의 성능면에서 뛰어난 caffeine cache를 적용하려고 한다.
● caffeine cache 구현하기
1. dependency 추가
implementation 'org.springframework.boot:spring-boot-starter-cache'
implementation 'com.github.ben-manes.caffeine:caffeine:3.1.1'
2. Spring cache management 활성화(@EnableCache)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@EnableCaching // 캐시 활성화
@SpringBootApplication
public class SpringbootCaffeineCacheApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootCaffeineCacheApplication.class, args);
}
}
3. 캐시에 저장할 내용을 enum으로 정의
- enum이 아닌 직접 설정파일에 입력을 해도 되지만 많은 캐시저장소를 정의할 경우 enum을 활용하여 관리하는것이 편리합니다.
- 만료시간이 0이라면 만료되지 않습니다.
- 최대갯수의 경우 모두 입력하게 되면 첫번째로 돌아가 첫번째 값을 제거하고 쓰여진다.
@Getter
@AllArgsConstructor
public enum CacheType {
CACHE_STORE("cacheStore", 5 * 60, 10000);
private final String cacheName; // 캐시 이름
private final int expireAfterWrite; // 만료시간
private final int maximumSize; // 최대 갯수
}
4. config bean 등록
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import net.suby.springbootcaffeinecache.caffeine.enums.CacheType;
import com.github.benmanes.caffeine.cache.Caffeine;
@Configuration
public class CacheConfig {
@Bean
public List<CaffeineCache> caffeineConfig() {
return Arrays.stream(CacheType.values())
.map(cache -> new CaffeineCache(cache.getCacheName(), Caffeine.newBuilder()
.recordStats()
.expireAfterWrite(cache.getExpireAfterWrite(),
TimeUnit.SECONDS)
.maximumSize(cache.getMaximumSize())
.build()
)
)
.toList();
}
@Bean
public CacheManager cacheManager(List<CaffeineCache> caffeineCaches) {
final SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(caffeineCaches);
return cacheManager;
}
}
5. cache 적용
- @Cacheable 를 사용하여 결과값을 캐시에 저장하며 캐시에 동일한 키가 있다면 캐시에 저장된 값을 리턴합니다.
- cacheNames : caffeineCache에 저장한 캐시명
- key : 캐시에 등록되는 키로 동일한 key값이 입력되면 캐시의 값을 바로 리턴합니다.
만약 파라미터가 여러개라면 연결을 하거나 toString으로 정의하여 key값을 정의하여 줍니다.
import static java.lang.Thread.sleep;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
@Service
public class CaffeineCacheService {
@Cacheable(cacheNames = "cacheStore", key = "#name")
public String getCache(String name) throws InterruptedException {
sleep(3000);
return name;
}
}
6. cache 제거
- @CacheEvict 를 사용하여 캐싱에 저장된 키값을 제거합니다.
- value : 캐시명
- key : 캐시가 저장된 키값
import static java.lang.Thread.sleep;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
@Service
public class CaffeineCacheService {
@CacheEvict(value = "cacheStore", key = "#name")
public String removeCache(String name) {
return "OK";
}
}
● git 주소
https://bitbucket.org/technology-team/springboot-caffeine-cache/src/master/
● 참고 url
https://halkrine.tistory.com/64
https://velog.io/@soongjamm/Caffeine-Cache-%EB%A5%BC-%EC%A0%81%EC%9A%A9%ED%95%B4%EB%B3%B8-%EA%B2%BD%ED%97%98
https://wave1994.tistory.com/182
https://ykh6242.tistory.com/entry/Spring-Cache-Abstraction-%EC%A0%95%EB%A6%AC
https://gosunaina.medium.com/cache-redis-ehcache-or-caffeine-45b383ae85ee
https://blog.yevgnenll.me/posts/spring-boot-with-caffeine-cache