Caffeine 유지 결정 기록
API를 4대로 늘리기 전에 Redis를 비교했고, 실측을 근거로 Caffeine을 유지했다. 판단 근거와 재검토 조건을 기록한다.
Caffeine 유지 결정 기록
결정
인프로세스 캐시(Caffeine) 단독 구성을 유지한 채 4대 확장 진행
- ETF 가격 변동 설명 조회 API는 단일 인스턴스에서 Caffeine으로
(ticker, trade_date)결과를 짧은 TTL 동안 재사용한다. 이 구성을 증권사 관리 환경의 로드밸런서 뒤 4대로 확장하는 것이 과제였다. - 처음에는 인프로세스 캐시가 공유되지 않으니 Redis가 필요하다고 봤다. 바로 도입하지 않고 부하를 걸어 비교해 보니 Caffeine만 유지하는 편이 나았다.
- Redis를 단독 캐시로도, L1 위의 L2로도 도입하지 않는다.
- 이 글은 결정 기록이다. 개념 정리는 1편에, 전체 실측은 2편에 있다.
4대 확장은 현재의 Caffeine 구성 그대로 진행한다.
실험에서 확인한 네 가지
로컬 Compose 환경(API 4대, 공통 요청률 1,600 rps, 3회 반복 중앙값)에서 네 구성을 같은 조건으로 비교
- 응답 지연 : 네 전략의 p99는 캐시가 없는 대조군까지 모두 1~2ms였다. 이 조건에서는 DB 로딩 횟수가 캐시 전략을 구별했다.
- DB 로딩 : 인프로세스 캐시만으로 DB 로딩은 초당 5.9회까지 줄었다. Redis를 추가하면 초당 1.1회가 된다. 줄어드는 양은 초당 4.8회였고, PostgreSQL은 처리 여유가 3배 남아 있었으며 커넥션 풀 대기도 없었다.
- 콜드 스타트 : 캐시를 모두 비우고 재기동한 직후 30초 동안 Redis 단독 구성은 DB를 1,658회 조회했고, 인프로세스 구성은 92회에 그쳤다. 1편에서 정한 기준으로 보면 이 구간이 실험에서 확인한 유일한 스탬피드였다. 공유 캐시 경로에 요청 병합이 없어 동시 miss가 그대로 DB로 향했고, Caffeine의 원자 로더가 제공하던 single-flight가 빠진 결과였다.
- Redis 장애 : 2계층 구성에서 Redis를 60초 정지시켰을 때 오류는 0이었고 처리율은 유지됐다. DB 로딩도 L1 단독 이론치 수준에 머물렀다. DB 부하를 막고 있던 계층은 L1이었다.
| 항목 | 인프로세스만 | Redis 추가 시 |
|---|---|---|
| p99 | 1~2ms | 1~2ms |
| DB 로딩 (초당) | 5.9회 | 1.1회 |
| 콜드 스타트 30초 DB 로딩 | 92회 | 1,658회 (Redis 단독) |
| Redis 60초 정지 시 오류 | 해당 없음 | 0 (2계층) |
응답 지연에서는 차이가 없었고, 콜드 스타트에서는 공유 캐시 단독이 더 나빴다.
2계층의 이득과 비용
인스턴스를 한 대 더 합류시킬 때만 L2가 제 역할을 수행
- 신규 인스턴스의 L1 miss가 모두 L2에서 적중하면서 클러스터 전체의 DB 로딩은 늘지 않았다. 인프로세스 캐시만 썼다면 약 3배로 뛰었을 값이다.
- L1은 동시 요청을 합쳤고, L2는 인스턴스가 늘면서 생긴 중복 로딩을 줄였다.
- 다만 L2가 줄여준 DB 로딩은 초당 약 1.5회였다. 이 수치를 위해 감수해야 할 비용은 다음과 같았다.
- 전체 경로(감사 기록 포함)에서만 관측된 지연 꼬리 악화
- TTL 두 계층의 무효화·정합성 운영 복잡도
- 새로운 공용 장애 의존성
- 증권사 관리 환경에 컴포넌트를 하나 더 반입하는 절차 비용
| 이득 | 비용 | |
|---|---|---|
| 2계층 (L1 + L2) | 증설 시 DB 로딩 초당 약 1.5회 절감 | 지연 꼬리 악화, 운영 복잡도, 공용 장애 의존성, 반입 절차 |
현재 조건에서는 초당 1.5회를 줄이려고 이 비용을 감수할 이유가 없었다.
재검토 조건
아래 값 중 하나가 달라지면 같은 실험을 다시 실행
| 재검토 트리거 | 현재 값 |
|---|---|
| 워킹셋이 균등 접근 기준 약 800종을 넘음 (실측 좌표는 아래 참고) | 키 3종 |
| 로더가 고비용화(무거운 조립·외부 호출) | 약 1ms |
| 인스턴스가 수십 대 규모 | 4대 |
| DB가 다른 워크로드와 공유되는 자원이 됨 | 전용, 여유 3배 |
| 캐시 외 용도로 Redis가 이미 도입됨 | 없음 |
- 첫 줄은 처음에 수백 종이라는 추정으로 적었다가, 후속 실측으로 좌표를 얻어 갱신했다.
- L1 적중률이 50% 아래로 무너지는 임계점은 균등 접근 기준 798~800종이었고, 실제 국내 ETF 수(1,088종)는 그 너머다.
- 이 선은 접근 분포의 함수라서, 요청의 90%가 인기 종목에 쏠리는 현실 분포에서는 1,088종에서도 적중률 90%가 유지돼 임계점이 사실상 나타나지 않는다.
- 현재는 여러 프로세스가 같은 값을 다시 만든다는 조건만 해당한다. 로더 비용이 커지거나 같은 키를 훨씬 자주 조회하게 되면 공유 캐시의 이득도 달라진다.
조건이 바뀌면 그때 다시 재면 된다.
회고
이번에 남긴 것은 Caffeine을 유지한다는 결론과 재검토 조건
- 수치를 재지 않았다면 다음에 상황이 바뀔 때 판단을 처음부터 반복했을 것이다.
- 구성을 그대로 유지한 이유도 기록해 두기로 했다. Redis를 추가하면 운영 대상과 장애 지점이 늘어난다.
지금 얻을 수 있는 이득으로는 Redis 추가의 비용을 설명하기 어려웠다.
Caffeine 유지 결정과 그 근거, 뒤집을 조건을 기록했다.
그런데 재검토 조건의 첫 줄인 워킹셋 수백 종은 범위가 너무 넓은데, 캐시는 실제로 몇 종까지 버틸까?
다음 편에서는 종목 수와 접근 분포를 바꿔가며 L1 적중률이 무너지는 지점을 직접 측정한 캐시 경계 측정을 다룬다.
캐시 전략 시리즈
- 다중 인스턴스와 Redis 도입 판단
- 4가지 캐시 구성 부하 실험
- Caffeine 유지 결정 기록
- 캐시 경계 측정 (워킹셋 임계점)
This post is licensed under CC BY 4.0 by the author.