
루퍼스 5주차 WIL - (index 최적화 & 캐시 설계)
이번 5주차에 배운 것
- 인덱스는 무조건 많은 게 좋은 게 아니라, 추가할수록 쓰기(Insert/Update) 성능과의 트레이드오프가 발생한다는걸 알게되었다.
- 다양한 캐시 읽기/쓰기 전략(Cache Aside, Write Through 등)의 쓰임과 목적을 테스트하면서 체감하였다.
- 인덱스를 걸 때 카디널리티(Cardinality, 중복도가 낮고 고유값이 많은 정도)가 높은 순서대로 복합 인덱스를 구성해야 성능이 극대화된다는걸 경험했다.
이런 고민이 있었어요
- 목록 API 응답에 likeCount 가 포함되어 있는데, 좋아요를 누를 때마다 목록 캐시를 evict 하려면 어떤 목록 키에 해당 상품이 들어 있는지 특정할 수 없는 구조였다. 그럼 목록에서 likeCount 를 빼야 하나? 를 고민했는데, 목록에 likes_desc 정렬이 있는 이상 likeCount가 없으면 오히려 이상하다고 생각했다.
- 결국 "좋아요 는 재고처럼 비즈니스 임팩트가 크지 않다." 라는 판단 하에 TTL(1분) 동안의 stale 을 의도적으로 허용하는 것으로 결론을 내렸다. 트레이드오프를 인지하고 설계 결정으로 가져간 것이다.
앞으로 실무에 써먹을 수 있을 것 같은 포인트
- Slow Query 가 발생하면 무작정 코드나 쿼리부터 수정하지 않고, EXPLAIN으로 실행 계획을 먼저 확인해서 인덱스를 제대로 타고 있는지 확인하는 습관을 들여야겠다.
- 캐시를 나중에 추가할 때는 해당 도메인 내부의 변경 경로만 보기 쉬운데, 외부 도메인(주문, 브랜드)에서 상품 상태를 바꾸는 경로도 별도로 추적해야한다는 점을 기억해야겠다.
아쉬웠던 점 & 다음에 해보고 싶은 것
- OFFSET 페이지네이션의 한계도 이번에 인지했지만 개선하지는 못했다. EXPLAIN ANALYZE에서 OFFSET 2000 기준으로 2,248건을 읽는 걸 확인했는데, 페이지가 깊어질수록 선형적으로 나빠지는 구조이다. 다음에는 커서 기반 페이지네이션으로 전환해서 OFFSET 방식과 성능 차이를 직접 수치로 비교해보고 싶다.
- 캐시 워밍업도 고민해보고 싶다. 지금 구조는 서버가 재시작되면 캐시가 완전히 비어있는 상태에서 첫 트래픽을 받게 되는데 배포 직후나 이벤트 시작 순간처럼 트래픽이 몰리는 타이밍과 겹치면 전부 DB로 향하게 된다. ApplicationRunner로 서버 시작 시 주요 캐시를 미리 적재하는 방식이 어떻게 동작하는지 직접 구현해보고 검증해보고 싶다.
'루퍼스 > WIL' 카테고리의 다른 글
| [WIL] 10주차 회고 (0) | 2026.04.16 |
|---|---|
| [WIL] 9주차 회고 (0) | 2026.04.12 |
| [WIL] 8주차 회고 (0) | 2026.04.05 |
| [WIL] 7주차 회고 (0) | 2026.03.29 |
| [WIL] 6주차 회고 (0) | 2026.03.22 |