Redis를 활용한 게시판 캐싱
커뮤니티 게시판의 인기글 목록 조회 시 다음과 같은 비효율적인 부분이 있었습니다.
1. 반복적인 DB 조회 부담 : 자주 조회되는 실시간/주간/레전드 인기글 목록을 DB에서 조회하여 응답 시간이 증가했습니다.
2. 실시간 인기도 반영의 어려움: RDB만으로 글의 인기도를 실시간으로 반영하려면 요청마다 복잡한 인기글 재선정 로직이 필요했습니다.
따라서 자주 조회되는 요청은 캐싱을 하여 DB의 부담을 낮추고자 했습니다.
캐싱 요구 사항
- TTL이 만료되어도 집계 쿼리가 재실행되면 안됩니다.
- 실시간 인기글은 사용자 활동(조회, 댓글, 추천)에 따라 동적으로 변화합니다.
- 글이 삭제되거나 수정되었을 때 사용자는 이전 버전의 글을 보면 안됩니다.
- 자주 조회되고 변하지 않는 인기 게시글 목록은 통째로 캐싱하여 반환해야 합니다.
- 캐시 히트율이 90%을 넘어야합니다.
Redis 게시글 저장소 아키텍처 표
| 구분 | 자료구조 | TTL | 설명 |
| PostId 저장소 | DB 재조회 없이 캐시 복구용 인덱스 저장소 | ||
| └ 주간, 레전드 인기글 | Sorted Set | 1일 | 주간 상위 5개 postId 저장, 스케줄러 1일 주기 |
| └ 공지사항 | Set | 무한 | 관리자 공지사항 postId 저장 |
| 게시글 목록 저장소 | Hash | 5분 | 목록의 단일 항목 부분 업데이트 및 삭제에 유 |
| 게시글 상세 저장소 | String | 5분 | 모든 게시글의 상세 캐시 (공통) |
| 실시간 인기글 저장소 | Sorted Set | 무한 | 조회/댓글/추천 이벤트에 따른 실시간 점수 반영 |
전략 요약
| 작업 | Write 전략 | Cache 처리 |
| 생성 | Write-Around | 조회 시 캐싱 |
| 수정 | Cache Invalidation | 상세 + 목록 캐시 삭제 |
| 삭제 | Cache Invalidation | 모든 관련 캐시 삭제 |
| 조회 | Cache-Aside | Redis 우선 → DB 조회 → 캐싱 |
조회 전략 (Cache-Aside 적용)
게시글 상세: 게시글 상세 저장소에서 먼저 조회 -> Cache Miss시 DB조회 후 캐싱
실시간 인기글: 실시간 점수 저장소에서 postId 조회 → 실시간 목록 저장소에서 데이터 조회 → Cache Miss 시 DB fetch 후 캐싱
주간/레전드/공지 목록: 목록 저장소 조회 → Cache Miss 시 postId 저장소에서 postId 목록 조회 → DB에서 데이터 fetch → 캐싱
쓰기 전략 (Write-Through 부분 적용)
생성: Write-Around (조회 시 캐싱)
수정/삭제: 즉시 캐시 무효화 (Cache Invalidation)
수정 시: 해당 게시글의 상세 저장소 및 모든 목록 저장소에서 해당 postId 삭제
삭제 시: postId 저장소, 실시간 점수 저장소, 목록 저장소, 상세 저장소 모두 삭제
주간/레전드 인기글 목록은 5분 TTL 만료 시에도 1일 TTL의 PostId 저장소를 활용하여 집계 쿼리 재실행 없이 빠르게 캐시를 복구합니다.
TTL 기반 전략의 정합성 문제(추천 미반영, 삭제 글 노출 등)를 해결하기 위해 수정/삭제 시 즉시 캐시 무효화를 적용하여 사용자 경험을 보장했습니다.
실시간 인기글 점수는 조회 +2점, 댓글 작성 +3점, 추천 +4점으로 즉시 반영되며, 5분마다 스케줄러가 0.95배 지수 감쇠를 적용합니다. 점수가 1점 미만이면 ZREMRANGEBYSCORE로 자동 제거하여 '실시간'의 특징을 살렸습니다.
결과
| 캐시 | 토탈 | 히트 | 미스 | 캐시 히트율 |
| 공지사항 목록 | 61 | 60 | 1 | 98.3607 |
| 실시간 인기글 목록 | 34 | 31 | 3 | 91.1765 |
| 상세글 | 141 | 127 | 14 | 90.0709 |
| 주간 인기글 목록 | 20 | 18 | 2 | 90 |