🌳 고급 performance
캐시 스탬피드가 뭔가요?
쉽게 이해하기
백화점 세일 시작 시간에 사람들이 입구에 몰려있다가 문 열리는 순간 우르르 몰려드는 거예요. 평소엔 캐시(미리 준비된 상품)가 있어서 빠르게 처리되는데, 캐시가 만료되면(재고 소진) 갑자기 모든 사람이 창고(데이터베이스)로 달려가서 창고가 마비되는 거죠.
핵심 정리
캐시가 만료되는 순간 수많은 요청이 동시에 몰려 서버가 마비되는 현상이에요.
자세히 알아보기
캐시 스탬피드(Cache Stampede)는 인기 있는 데이터의 캐시가 만료되는 순간, 수많은 요청이 동시에 데이터베이스로 몰려들어 시스템이 과부하되는 현상이에요. Thundering Herd Problem이라고도 불러요.
실제 사례를 보면 심각성을 알 수 있어요. 유튜브 같은 동영상 사이트에서 인기 영상의 조회수를 캐시에 저장해뒀다고 가정해봐요. 캐시 만료 시간이 5분이면, 5분마다 조회수를 데이터베이스에서 다시 읽어와야 해요. 그런데 그 영상을 보는 사람이 1만 명이라면? 캐시가 만료되는 순간 1만 개의 요청이 동시에 데이터베이스를 치는 거예요. 평소엔 캐시 덕분에 DB 부하가 없다가, 갑자기 1만 배의 부하가 걸리는 거죠.
해결 방법은 여러 가지예요. 첫째, Lock을 사용하는 거예요. 캐시가 만료되면 첫 번째 요청만 DB에 가고, 나머지는 대기시키는 거죠. 첫 요청이 새 데이터를 캐시에 쓰면 나머지는 새 캐시를 읽어요. Redis의 SETNX 명령어로 구현할 수 있어요. 둘째, 확률적 조기 갱신(Probabilistic Early Expiration)이에요. 캐시 만료 직전에 일부 요청이 미리 갱신하게 하는 거죠. 예를 들어 만료 30초 전부터 1% 확률로 갱신하면, 만료 시점에 이미 새 데이터가 캐시에 있어요.
실무에서는 Stale-While-Revalidate 패턴도 많이 써요. 캐시가 만료돼도 일단 오래된(stale) 데이터를 보여주고, 백그라운드에서 새 데이터를 가져와서 캐시를 갱신하는 거예요. 사용자는 빠른 응답을 받고, 서버는 부하를 피할 수 있죠. Next.js의 ISR(Incremental Static Regeneration)이 이 방식이에요.
쿠버네티스 환경에서도 조심해야 해요. Pod가 재시작되면 로컬 캐시가 날아가는데, 여러 Pod가 동시에 재시작되면 모든 Pod가 동시에 DB를 치거든요. 그래서 롤링 업데이트 전략을 쓰거나, Redis 같은 중앙 캐시를 쓰는 게 안전해요.