Foundry
캐시/Redis
중급
핵심

TTL과 캐시 무효화

캐시에서 가장 어려운 문제, 언제 버릴지 정하기

TTL과 캐시 무효화

무효화 방식

  • TTL 만료: 가장 단순. 불일치를 허용할 시간을 초 단위로 명시한다
  • 키 삭제: 쓰기 트랜잭션 커밋 후 관련 키를 DEL
  • 버전 키: 키에 버전을 넣어 user:42:v7처럼 쓰고 구버전은 자연 만료시킨다
  • 조건부 재검증: HTTP ETag / If-None-Match로 변경 없으면 304 응답

TTL 선택 기준

데이터TTL 감각이유
코드와 설정 목록수십 분 이상거의 변하지 않음
상품과 프로필수 분변경되지만 즉시성 요구 낮음
재고와 잔액수 초 또는 캐시 안 함불일치 비용이 큼

실무 포인트

  • 키에 정렬, 필터, 페이지 같은 파라미터를 모두 담는다. 조건이 다른 목록이 같은 키를 쓰면 잘못된 응답이 나간다
  • 삭제는 반드시 커밋 이후에. 커밋 전에 지우면 롤백 시 캐시가 잘못 채워진다
  • 대량 키에 동일 TTL을 주면 만료가 한꺼번에 몰린다. TTL에 지터를 더해 분산한다
  • 무효화 누락은 조용히 오래 살아남는다. 캐시 키 생성과 삭제 지점을 코드에서 한곳으로 모은다
면접에서 이렇게 나옵니다

Q.캐시 무효화 전략에는 어떤 것이 있고 각각 언제 쓰나요?

전략내용언제
만료 시간일정 시간 뒤 자동으로 사라진다약간의 지연을 허용할 때. 가장 단순하다
쓰기 시 삭제데이터를 바꿀 때 함께 지운다변경 지점이 명확할 때
변경 로그 구독DB 변경 이벤트를 받아 지운다변경 경로가 여러 개일 때
버전 키키에 버전을 넣고 버전을 올려 통째로 무효화묶음 단위로 갱신할 때
태그 기반관련 키에 태그를 붙여 함께 지운다한 변경이 여러 키에 영향을 줄 때

실무에서는 만료 시간과 쓰기 시 삭제를 함께 씁니다. 삭제가 실패하거나 놓친 경로가 있어도 만료로 수렴합니다.

변경 로그 구독이 강한 이유는 애플리케이션 경로와 분리돼 있어서입니다. 관리자 화면이나 배치가 직접 DB 를 고쳐도 잡힙니다.

흔한 실수: 쓰기 시 삭제만 두는 것. 코드에서 놓친 경로가 반드시 생기고, 그때 옛 값이 영구히 남습니다.

Q.TTL은 어떤 기준으로 정하나요?

허용 가능한 어긋남 시간에서 거꾸로 잡습니다. 성능이 아니라 정합성 요구가 기준입니다.

데이터허용 지연TTL
상품 상세 정보몇 분5분에서 10분
목록과 검색 결과수십 초30초에서 1분
인기 순위몇 분1분에서 5분
설정값, 코드 테이블몇 시간1시간 이상
잔액, 재고없다캐시하지 않거나 아주 짧게

그 다음에 조회 빈도를 봅니다. 초당 1,000회 조회되는 데이터는 TTL 10초만 두어도 DB 부하가 1만분의 1로 줄어듭니다. 짧은 TTL 로도 대부분의 효과가 나옵니다.

만료 시각이 몰리지 않게 편차를 더하는 것도 함께 갑니다.

흔한 실수: 길게 잡을수록 좋다고 보는 것. 히트율은 오르지만 어긋난 값이 그만큼 오래 남습니다. 그리고 길게 잡으면 무효화 실패를 만료가 덮어주지 못합니다.

Q.트랜잭션 커밋 전에 캐시를 삭제하면 어떤 문제가 생기나요?

삭제와 커밋 사이에 조회가 끼어들면 옛 값을 다시 캐시에 채웁니다.

순서동작결과
1캐시 삭제캐시가 비었다
2다른 요청이 조회DB 에서 아직 커밋 안 된 옛 값을 읽는다
3그 값을 캐시에 채운다옛 값이 박힌다
4트랜잭션 커밋DB 는 새 값, 캐시는 옛 값

만료까지 어긋난 채로 남습니다. 롤백되는 경우도 문제입니다. 캐시를 이미 지웠으니 불필요한 미스가 발생합니다.

그래서 커밋 후에 삭제합니다. 프레임워크의 커밋 후 훅을 쓰면 안전하게 붙일 수 있습니다.

커밋 후 삭제가 실패할 수 있으므로 만료 시간을 함께 두거나, 짧은 지연 뒤 한 번 더 지우는 방법을 씁니다.

흔한 실수: 트랜잭션 안에서 캐시를 조작하는 것. 캐시는 트랜잭션에 참여하지 않으므로 롤백해도 되돌아가지 않습니다.

Q.같은 API인데 정렬 조건만 다를 때 캐시 키를 어떻게 설계하나요?

키에 응답을 결정하는 모든 요소를 넣되, 조합이 폭발하지 않게 제한합니다.

캐시 키 = 자원 종류 + 필터 + 정렬 + 페이지 + 버전
예: products:cat=10:sort=price_asc:page=1:v3
원칙내용
허용 목록으로 정규화정렬은 미리 정한 몇 가지만. 임의 문자열을 키에 넣지 않는다
순서 고정파라미터 순서가 달라도 같은 키가 되게 정렬한다
기본값 명시생략된 파라미터를 기본값으로 채워 키를 통일한다
무의미한 파라미터 제외추적용 파라미터는 키에서 뺀다
버전 포함스키마가 바뀌면 버전을 올려 통째로 무효화한다

첫 번째가 히트율과 보안을 함께 지킵니다. 사용자 입력을 그대로 키에 넣으면 조합이 무한해지고, 메모리를 채우는 공격 표면이 됩니다.

흔한 실수: 개인화 요소를 키에서 빠뜨리는 것. 로그인 사용자별로 결과가 다른데 키가 같으면 남의 응답이 나갑니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

읽었으면 문제로 확인해보세요

캐시/Redis 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.