Skip to content

refactor: ThunderingHerdCaching의 만료 임박 캐시 갱신 정책 수정 #801

Description

@Hexeong

어떤 부분을 리팩터링하려 하나요?

@ThunderingHerdCaching의 만료 임박 캐시 갱신 정책을 리팩터링합니다.

현재 ThunderingHerdCachingAspect.refreshCache()는 캐시 TTL이 임박했을 때 DB에서 값을 재계산하지 않고, 기존 cached value의 TTL만 다시 늘립니다. 이 방식은 hot key에 대한 Thundering Herd 문제를 피하는 효과는 있지만, 트래픽이 계속 있는 경우 stale cache가 TTL을 넘어 장시간 유지될 수 있습니다.

AS-IS

  • 캐시 miss 시에는 create lock을 잡은 요청 1개만 DB를 조회하고 Redis에 저장합니다.
  • 캐시 hit이면서 TTL이 만료 임박한 경우 refresh lock을 잡습니다.
  • refresh lock을 잡은 요청도 DB를 재조회하지 않고 기존 cached value의 TTL만 연장합니다.
  • refresh lock을 잡지 못한 요청은 기존 cached value를 바로 반환합니다.
  • 결과적으로 인기 key는 트래픽이 있는 동안 계속 TTL이 연장되어, 삭제/수정된 데이터가 명시적 evict 전까지 오래 남을 수 있습니다.

TO-BE

  • 캐시 miss 시 동작은 기존처럼 Thundering Herd를 방지합니다.
  • 캐시 hit이면서 TTL이 만료 임박한 경우 refresh lock을 잡은 요청 1개가 DB에서 값을 다시 계산합니다.
  • 새로 계산한 값을 Redis에 저장하고 반환합니다.
  • refresh lock을 잡지 못한 요청은 기존 cached value를 반환해 요청 폭주를 막습니다.
  • TTL은 stale cache의 최대 유지 시간을 의미하도록 동작해야 합니다.

작업 상세 내용

  • ThunderingHerdCachingAspect.refreshCache()가 기존 TTL만 연장하지 않고 값을 재계산하도록 수정
  • refresh lock 획득 실패 시에는 기존 cached value를 반환해 Thundering Herd 방지 유지
  • 캐시 miss/create lock 경로와 refresh lock 경로의 역할을 테스트로 검증
  • 기존 사용처(univApplyInfo:{id}, university:recommend:general:*)에 미치는 영향 확인
  • 필요하면 어노테이션 옵션으로 기존 sliding expiration 동작과 refresh recompute 동작을 분리할지 검토

참고할만한 자료(선택)

관련 PR:

배경:

  • 공통 추천 목록 캐시 개선 중 TTL을 3600초로 낮췄지만, 현재 ThunderingHerdCaching 구현에서는 TTL 임박 시 기존 값을 재계산하지 않고 TTL만 연장합니다.
  • 따라서 트래픽이 계속 있으면 TTL이 stale cache의 최대 유지 시간을 보장하지 못합니다.
  • 이번 작업은 #800의 직접 범위를 넘는 공통 캐시 정책 변경이므로 별도 리팩터링 이슈로 분리합니다.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions