Skip to content

perf: 공개 코스 조회 API에 Redis 캐싱 적용 - #203

Merged
unam98 merged 1 commit into
mainfrom
feat/redis-cache-public-course
Jul 28, 2026
Merged

perf: 공개 코스 조회 API에 Redis 캐싱 적용#203
unam98 merged 1 commit into
mainfrom
feat/redis-cache-public-course

Conversation

@unam98

@unam98 unam98 commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

배경

dev 환경에서 Artillery 부하테스트(초당 20건, KPI: p95 500ms 이하·에러율 0%) 결과 p95 9.3초·에러율 71%로 KPI 미달성. 응답시간이 구간마다 계속 치솟고 대기 요청이 눈덩이처럼 쌓이는 패턴을 확인 — 리전 간 DB 왕복(회당 약 60~90ms)이 동시 요청마다 반복되며 스레드/커넥션을 묶어두는 것이 원인으로 진단됨.

변경 내용

읽기 전용 3개 API(전체 페이지 수/마라톤/추천 목록)에 @Cacheable 적용, TTL 1분.

  • total-page-count: 전체 유저 공통 응답이라 키 없이 캐싱
  • marathon, recommend: 응답에 유저별 스크랩 여부(isScrap)가 섞여있어 userId(+페이지/정렬)를 캐시 키에 포함 — 실 트래픽에서는 유저가 분산되는 만큼 히트율이 이번 부하테스트(단일 유저 반복 호출)만큼 극적이진 않을 수 있음

RedisConfig에 명시적 CacheManager 빈 추가 — GenericJackson2JsonRedisSerializer로 DTO 직렬화, TTL 1분으로 캐시 무효화 리스크를 제한.

검증 (dev 환경)

동일 조건(초당 20건, 워밍업 10초+타겟 30초) 재테스트 결과:

지표 Before After
p95 응답시간 9,306ms 4,488ms (약 52% 감소)
성공(200) 비율 122/650 (18.8%) 649/650 (99.8%)
서버 다운(502) 발생 미발생
저부하(5건/s) p95 2,254ms 377ms (목표 500ms 달성)

목표 부하(20건/s)에서 p95 500ms 자체는 아직 못 넘겼지만, 에러율은 사실상 해소되고 서버 크래시도 없어짐. 잔여 지연은 Render 0.1 vCPU 자체의 순수 처리 용량 한계로 판단(캐싱으로 해결 가능한 범위 밖).

알려진 한계

  • 캐시 무효화: TTL 1분에 의존, 코스 추가/삭제 시 최대 1분간 오래된 응답 노출 가능
  • 캐시 키에 userId가 섞인 두 엔드포인트는 실 서비스(다수 유저 분산 트래픽)에서는 이번 벤치마크만큼 히트율이 안 나올 수 있음

부하테스트(초당 20건)에서 p95 9.3초, 에러율 71%로 KPI 미달성. 응답시간이
구간마다 계속 치솟고 대기 요청이 눈덩이처럼 쌓이는 패턴 확인 — 리전 간 DB
왕복(회당 약 60~90ms)이 동시 요청마다 반복되며 스레드/커넥션을 묶어두는
것이 원인으로 진단됨.

읽기 전용 3개 API(전체 페이지 수/마라톤/추천 목록)에 @Cacheable 적용,
TTL 1분. total-page-count는 전체 유저 공통이라 키 없이 캐싱하고, 나머지
둘은 응답에 유저별 스크랩 여부가 섞여있어 userId를 캐시 키에 포함함(실
트래픽에서는 이번 부하테스트만큼 히트율이 높지 않을 수 있음).

RedisConfig에 명시적 CacheManager 빈 추가 — GenericJackson2JsonRedisSerializer로
DTO 직렬화, TTL 1분으로 캐시 무효화 리스크를 제한.
@unam98 unam98 self-assigned this Jul 28, 2026
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9ae68453-d32e-45fa-aedd-7918288fba00

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/redis-cache-public-course

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@unam98
unam98 merged commit 7acb46f into main Jul 28, 2026
2 checks passed
@unam98
unam98 deleted the feat/redis-cache-public-course branch July 28, 2026 21:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants