1. Intro
2. Cache란?
3. Cache 종류
4. 도입 후기 & 성능 테스트 결과
Intro
최근 업무에서 캐시 도입으로 반복된 DB 조회 비효율을 개선했다. 캐시를 도입하기 위해 학습한 Cache 와 여러 Cache 시스템을 비교해보겠다.
Cache
캐시는 값비싼 연산 결과 또는 자주 참조되는 데이터를 메모리 안에 두고, 뒤이은 요청이 보다 빨리 처리될 수 있도록 하는 저장소이다.
캐시의 종류는 데이터를 두는 공간에 따라서 CPU, SSD, HDD 등 다양하다. 캐시는 데이터를 영속화하는 목적의 저장소가 아니기 때문데 캐시 영역이 가득 차면 자동으로 비우거나(eviction) 또는 의도적으로 필요 없는 데이터를 비워주는(expriation) 기능이 필요하다.
이런 캐싱에 필요한 기능들을 구현한 여러 오픈소스, DBMS 가 존재하며 특징은 각기 다르므로 어플리케이션의 특성에 맞게 선택하면 된다.
Cache 와 관련된 용어 정리
- a cache hit : 요청된 데이터를 캐시 메모리에서 찾은 상태를 말한다.
- a cache miss : 요청된 데이터를 캐시 메모리에서 찾지 못한 상태를 말한다.
- eviction : 캐시는 메모리를 많이, 그리고 무한정 점유할 수 없으므로 특정 정책에 의해 데이터를 지우는 것
- expiration : 사용자가 데이터를 지우겠다라고 명시적으로 의도하여 지우는 것
- Distributed Caching, Replicated Caching : 분산 시스템에서 한 클러스터 내 여러 노드에서 캐시 데이터 일관성 보장, Fault Tolerant, 캐시 데이터가 방대하게 커졌을 경우 대응, 또는 확장성을 위한 전략이다.
Cache 오픈 소스
Redis
- Key, Value 구조의 비정형 데이터를 저장하고 관리하기 위한 오픈 소스 기반의 비관계형 데이터 베이스 관리 시스템
- 인메모리 데이터 구조 저장소
- String, Lists, Sets, Sorted Sets, Hashes 등의 자료 구조를 지원
- built-in replication, cluster, transactions 등의 다양한 기능 제공
- Distributed Caching, Replicated Caching 구축을 위한 기능 제공 — Redis clustering (sentinel, ElastiCache)
EhCache
- 자바 기반의 캐시 프레임워크
- fast and Light weight : 공식 문서에 따르면 EhCache은 빠르고 사용하기 쉬움을 강조하고 있다.
- scalable 기능을 제공한다
- off-heap 영역에 테라바이트의 데이터를 처리할 수 있다.
- 저장소로 on-heap, off-heap, disk 중 선택 가능하다.
- Distributed Caching, Replicated Caching 구축을 위한 기능 제공- Terracotta Server를 통해
Caffeine
- Java8 로 Guava 캐시를 재구현한 오픈 소스
- 저장소로 on-heap 사용. ConcurrentLinkedHashMap 을 사용하지만 eviction 기능이 구현되어 있다. eivction 정책으로 Window TinyLfu 을 사용하는데 이 덕분에 높은 성능을 자랑한다고 한다.
- 높은 hit-rate, high-performance 를 특징으로 하는 라이브러리라고 한다.
- 아래는 caffeine 깃헙 위키에 기재된 벤치마크 결과인데 읽기, 쓰기 테스트에서 모두 1위를 했다.
Cache 구축시 고려할 사항
- expriation 정책
- eviction 정책
- DB와 캐시 데이터와 일관성 유지
- 장애 대응
- 캐시 메모리 크기 설정
- 낮은 cache miss rate 유지하기
Caffeine 선정 이유
- 트래픽이나 서비스 아키텍처를 고려했을 때 분산 캐시, remote 캐시 필요 없음
- 토큰 검사 per request, 반복된 DB 조회를 줄이기 위한 캐싱
- 캐싱할 데이터 양이 극히 적음 → 캐시에 많은 메모리 할당 필요 없음.
- 확장성 고려 — Auth API 노드가 여러개 생길 경우 캐시와 DB의 일관성 유지 대응은?
- 노드를 여러 개 증설할 만큼 서비스가 성장하려면 상당한 시간 소요 예상. 그때 레디스로 전환.
캐시 도입 후 Jmeter 로 테스트 결과
Test Thread Group
- Number of Threads (Users) : 10
- Ramp-up period (secondes) : 1
- Loop Count : 5000
Before caching :
- ThroughPut : 284.1/sec
After caching :
- ThroughPut : 6847.439/sec
결론
무조건 레디스를 도입하기 보다는 서비스 트래픽, 분산 시스템일 경우 데이터 정합성 등 모두 고려해 적합한 캐시를 사용하면 된다.
캐싱은 잘 사용하면 성능 향상에 정말 좋다
'개발 > 자바&스프링' 카테고리의 다른 글
공식, 이론, 실제를 모두 확인하며 병렬 프로그래밍 성능 개선하기! (0) | 2023.11.14 |
---|---|
동기화된 리스트를 빠르게 조회하기 - synchronizedList와 CopyOnWriteArrayList 성능 비교해봅시다 (0) | 2023.11.03 |
대용량 데이터를 빠르게 조회하기 - 페이징 전략 비교(offset, no offset, Where In) (0) | 2023.11.02 |
@ConfigurationProperties 바인딩 동작 원리 분석 & SpringBoot 3.x 에서 변경된 내용 (0) | 2023.09.08 |
의존성, 의존관계, 의존관계 주입 정리하기! (0) | 2023.08.01 |