[Spring] CaffeineCache 사용해보기, 성능테스트

2024. 4. 7. 19:26· WEB/Spring
목차
  1. 개요
  2. Radis, EH Cache, Caffeine Cache
  3. SpringBoot에 Caffeine Cache 적용하기
  4. 성능비교
  5. 결론

개요

Cache라는 개념은 많은 곳에 이용됩니다.

CPU에도 L1, L2, L3캐시가 있고, 이들의 역할은 메모리를 조회하지 않아도 되도록 하는 것입니다.

같은 정보를 요청했을 때, 주 메모리에서 검색한 뒤 다시 CPU로 로드하는 것은 자원의 낭비이기 때문입니다.

 

이는 웹 서비스에서도 적용되는 개념입니다.

프론트엔드에서는 브라우저 캐시, HTTP 캐시 등과 같이 백엔드와 통신해서 가져오는 자원을 저장해둡니다.

백엔드에 같은 요청을 보낼 때, 이러한 캐시를 이용해서 통신에 필요한 자원을 절약합니다.

 

최근 진행한 프로젝트에서 백엔드 포지션을 맡았습니다.

이 때, 사용자와 어울리는 피드를 추천해주는 비즈니스 로직을 작성했습니다.

단순히 피드의 속성들과 사용자의 속성들에 대한 가중치를 연산하는 것이기에, 사용자가 추천 피드를 받으려면 모든 피드와 해당 가중치를 계산해야 했습니다.

 

물론 이후 추천 시스템을 업그레이드하는 것이 좋겠지만, 일단 캐시를 도입해 급한 불을 끄기로 했습니다.

 


Radis, EH Cache, Caffeine Cache

 

Spring Cache를 사용하기로 했기에 Redis와 EH Cache, Caffeine Cache 세 후보를 추렸습니다.

 

1. Redis

Redis Cache는 대표적인 Global Cache입니다.

사용자 인증/인가를 위해 Redis를 사용하고 있어 그대로 쓰면 된다는 장점과 인스턴스가 여러 개 있을 때 정합성 문제를 해결할 수 있다는 장점이 있었지만, 모놀리식 서버를 이용하고 있어 네트워크 트래픽이 발생하는 Global Cache를 선택할 이유는 없었습니다.

 

2. EH Cache

EH Cache는 대표적인 Local Cache입니다.

JAVA기반이며 Memory/Off Heap/Disk 3개의 스토리지에 저장할 수 있다는 특징이 있습니다.

또, Off Heap의 경우 GC의 영향을 받지 않아 매우 큰 객체를 저장할 수 있습니다.

 

3. Caffeine Cache

그래서 EH Cache의 정보를 찾아보던 중, Caffeine Cache를 발견했습니다.

마찬가지로 Spring에서 쉽게 사용할 수 있지만, EH Cache보다 제한적인 기능을 제공합니다.

하지만, 캐시를 단순하게 사용하는 경우 Caffeine Cache를 사용하는 것이 더 좋다고 생각했습니다.

벤치마크상 Caffeine Cache의 결과가 너무 좋게 나왔기 때문에...

더불어 EH Cache의 기능을 제대로 활용하는 상황이 아니었기 때문에 Caffeine Cache를 사용했습니다.

 

Caffeine Cache의 벤치마크 성능은 아래와 같습니다.

 

READ성능 비교

 

WRITE성능 비교

 

 

이처럼 차이가 확실했기에, Caffeine Cache를 선택하지 않을 이유가 없었습니다.

 


SpringBoot에 Caffeine Cache 적용하기

Caffeine Cache를 적용하는 법은 상당히 간단합니다.

 

1. Dependency 추가

 

SpringBoot Gradle에 Caffeine Cache의존성을 추가합니다.

 

2. Cache Type 추가

 

- 어떠한 정보를 저장할 것인지에 대한 타입

- TTL(유효시간)

- MAX SIZE

이와 같은 정보들을 CacheType으로 설정할 수 있습니다.

저는 사용자가 한 번 10개의 피드를 추천받을 때, 캐시에 200개의 피드가 저장되도록 했습니다.

때문에 유저에 대한 피드와 페이지 정보를 저장할 수 있도록 설정했습니다.

 

3. CacheConfig 추가

 

캐시 매니저를 빈으로 등록하는데, 캐시매니저 설정은 다음과 같습니다.

- expireAfterWrite : 캐시가 해당 시간 이후에 삭제되도록 설정

- maximumSize : 캐시의 최대용량 설정

- recordStats : 캐시에 대한 통계정보를 사용할 수 있도록 설정

 

4. 코드 작성

 

코드의 길이가 어느 정도 있어서, 일부를 가져왔습니다.

해당 로직의 경우, 정말 간단하게 캐시가 없거나 마지막 페이지인 경우 불러오기를 수행합니다.

그렇기 때문에, 해당 유저 닉네임에 대해 검색해서 캐시 데이터 존재여부를 확인합니다.

cacheManager.getCache().get(), cacheManager.getCache().put()을 이용했습니다.

 

 

이렇게 간단하게 Caffeine Cache를 도입해봤습니다.

마지막으로, Cache를 도입하기 전과 후 비교를 진행했습니다.

 


성능비교

 

성능 테스트 환경은 다음과 같습니다.

CPU : I7-11600H
RAM : 32GB
TOOL : Jmeter
USERS : 1
LOOP : 10000

 

피드 추천 요청에 대하여, 추천 요소를 계산할 때는

사용자의 가중치와 피드의 가중치를 곱하여 정렬, 랭킹순으로 가져오게 됩니다.

 

1. Feed 300개

캐시가_없을_때

 

캐시를 사용하지 않을 때 테스트입니다.

초당 50~70개의 Request를 처리하는 것을 볼 수 있습니다.

 

Caffeine Cache 사용

 

캐시를 사용할 때입니다.

TPS가 550이상 나오고 있습니다.

300이하로 떨어지는 순간이 있는데, 이는 특정 순간에 계산 요청이 몰리기 때문으로 보여집니다.

 

캐시를 사용하지 않을 때 2분 48초(168초), 캐시를 사용할 때 19초가 걸립니다.

약 9배의 차이가 나는 것을 볼 수 있습니다.

 

원래는 피드 양을 늘려 비교를 진행하려 했으나, 이미 캐시를 사용하지 않을 때 성적이 너무 저조하기 때문에...

이하 테스트는 캐시의 독무대가 되겠습니다.

 

2. Feed 3000개

 

캐시를 사용한 채로, 피드를 3천개로 늘렸습니다.

TPS가 80~120사이로 나오는 것을 볼 수 있습니다.

피드가 10배 늘었는데도 불구하고 캐시를 사용하지 않은 것보다 성능이 좋습니다.

 

3. Feed 12000개

 

피드를 12000개로 늘렸습니다.

이제는 TPS가 20~40개 사이에서 놀고 있습니다.

더 이상의 테스트는 무의미하다 생각해 20초에서 종료했습니다.

 


결론

간편하게 서버 처리량을 늘릴 수 있는 캐시를 사용해보는 좋은 기회였습니다.

성능차이가 9배정도 나기 때문에, 굳이 캐시를 사용하지 않을 이유는 없다 생각합니다.

차후 여러 인스턴스를 분할하여 캐시를 사용해야 할 때는 Global Cache를 사용해보고 싶습니다.

 

테스트를 진행할 때, 1명의 유저가 1만번의 Request를 보낸다는 시나리오로 진행했습니다.

하지만, 실제 사용 환경에서 이러한 테스트 시나리오는 의미가 없다 생각했습니다.

시간이 된다면, 100명의 유저가 50번 Request를 보낸다거나, 500명의 유저가 20번 Request를 보내는 시나리오를 점검해볼 것이라 생각합니다.

'WEB > Spring' 카테고리의 다른 글

[Spring] Virtual Thread, DB IO테스트시 발생했던 문제 - 1  (1) 2024.01.21
[Spring] HikariCP 알아보기  (0) 2024.01.14
[Spring] Actuator  (1) 2024.01.04
[Spring] SpringBoot에서의 Virtual Thread  (2) 2023.12.31
[Spring] Spring의 ThreadPool  (1) 2023.12.31
  1. 개요
  2. Radis, EH Cache, Caffeine Cache
  3. SpringBoot에 Caffeine Cache 적용하기
  4. 성능비교
  5. 결론
'WEB/Spring' 카테고리의 다른 글
  • [Spring] Virtual Thread, DB IO테스트시 발생했던 문제 - 1
  • [Spring] HikariCP 알아보기
  • [Spring] Actuator
  • [Spring] SpringBoot에서의 Virtual Thread
낭만주의 개발자
낭만주의 개발자
낭만주의자낭만주의 개발자 님의 블로그입니다.
낭만주의 개발자
낭만주의자
낭만주의 개발자
전체
오늘
어제
  • 분류 전체보기 (21)
    • CS (1)
    • JAVA (9)
      • 일반 (3)
      • GC (1)
      • Thread (5)
    • WEB (8)
      • Spring (7)
      • Architecture (0)
      • Monitoring (1)
    • NETWORK (0)
      • MAC,UDP,TCP,IP (0)
      • HTTP (0)
    • DB (0)
      • MySQL (0)
      • PostgreSQL (0)
    • Mobility (0)
      • HW (0)
      • SW (0)
    • 잡담 (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • eh cache
  • java21
  • Tomcat ThreadPool
  • java
  • Process와 Thread의 차이
  • Transaction Per Second
  • Spring
  • 스레드풀
  • local cache
  • DB
  • JVM
  • actuator
  • 가상스레드
  • java19
  • HotSpotVM
  • global cache
  • Thread Container
  • thread
  • JMeter
  • 경량스레드
  • 자바
  • 상태머신
  • Virtual Thread
  • springboot
  • LifeCycle
  • ThreadPool
  • caffeine cache
  • Process
  • tomcat
  • 스레드

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
낭만주의 개발자
[Spring] CaffeineCache 사용해보기, 성능테스트
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.