캐시 미스(Cache Miss): 빈 데이터베이스 복구하기
Redis에 원하는 데이터가 없을 때 메인 데이터베이스에서 데이터를 조회하여 안전하게 캐시에 채워넣는 흐름을 배웁니다.
우리가 Redis에 데이터를 요청했을 때 항상 데이터가 존재한다는 보장은 없습니다. TTL이 지나서 지워졌거나, 원본 데이터가 수정되면서 앞서 배운 캐시 무효화로 인해 지워졌을 수 있습니다. 이렇게 캐시에 데이터가 없는 상황을 어떻게 다루는지, 기본적이고 필수적인 복구 패턴을 알아봅시다.
Cache Hit vs Cache Miss
Redis를 조회했을 때 데이터가 존재하는 상황과 존재하지 않는 상황은 용어로 명확히 구분됩니다. 이 두 가지 상황에 따라 애플리케이션이 어떻게 행동해야 하는지가 결정됩니다.
데이터가 있을 때 (Cache Hit)
캐시 히트(Cache Hit) 란 요청한 데이터가 Redis에 성공적으로 존재하는 경우입니다. 애플리케이션은 즉시 Redis에서 읽은 데이터를 사용자에게 반환합니다. 메인 데이터베이스(PostgreSQL)까지 내려갈 필요가 없으므로 응답 속도가 매우 빠릅니다.
데이터가 없을 때 (Cache Miss)
캐시 미스(Cache Miss) 란 요청한 데이터가 Redis에 없는 경우입니다. 이때는 당황하지 말고 원본 데이터가 저장된 메인 데이터베이스로 직접 찾아가야 합니다.
정의
Cache-Aside (혹은 Look-Aside) 패턴
실무에서 가장 많이 쓰이는 캐싱 전략입니다. 데이터를 찾을 때 항상 옆에 있는(Aside) 캐시를 먼저 쳐다보고(Look), 없으면 그때 데이터베이스로 찾아가는 방식입니다.
캐시 미스를 복구하는 표준 워크플로우
캐시 미스가 발생했을 때 데이터를 조회하고 복구하는 과정은 개발자들이 매일 작성하는 매우 정형화된 패턴입니다. 다음과 같은 세 단계를 거치게 됩니다.
캐시 미스 발생 시 데이터 복구 흐름
- 1Redis에 데이터를 요청합니다. (데이터가 없어 null이 반환됨)
- 2메인 데이터베이스(PostgreSQL)에 쿼리를 날려 원본 데이터를 조회합니다.
- 3조회한 원본 데이터를 다음 사용자를 위해 Redis에 저장(TTL 포함)하고 사용자에게 반환합니다.
코드에서는 어떻게 생겼을까?
이 흐름은 코드로 보면 훨씬 직관적입니다. 조건문(if)을 사용해 데이터 존재 여부를 판별하는 간단한 구조를 가집니다.
Cache-Aside 패턴 구현 예시
// 1. Redis에서 캐시 데이터를 먼저 찾습니다.
let userData = await redisClient.get(`user:profile:${userId}`);
// 2. 만약 캐시 미스(데이터가 없음)라면 메인 DB로 갑니다.
if (!userData) {
// 메인 데이터베이스에서 원본 데이터를 조회합니다.
const dbResult = await db.users.findById(userId);
// 3. 찾은 원본 데이터를 다시 Redis에 채워넣습니다 (TTL 1시간).
await redisClient.set(`user:profile:${userId}`, JSON.stringify(dbResult), { EX: 3600 });
userData = JSON.stringify(dbResult);
}
// 4. (캐시 히트든 미스든) 최종 데이터를 사용자에게 반환합니다.
return JSON.parse(userData);캐시 폭풍 (Cache Stampede) 주의보
캐시 미스는 정상적이고 필연적인 과정입니다. 하지만 매우 인기 있는 데이터의 TTL이 만료되어 갑자기 캐시 미스가 발생하면, 순간적으로 엄청난 수의 사용자가 동시에 메인 데이터베이스로 몰려가는 현상이 생길 수 있습니다. 이를 캐시 폭풍(Cache Stampede)이라고 합니다.
이러한 현상을 막기 위해 캐시가 만료되기 직전에 백그라운드에서 미리 데이터를 갱신하거나, 첫 번째 요청만 DB에 접근하게 막아두는 심화 기술들이 존재합니다. 그러나 기본적인 서비스에서는 Cache-Aside 패턴만 잘 지켜도 훌륭한 성능을 낼 수 있습니다.
개념 퀴즈
퀴즈 답을 맞춰야 학습 완료가 됩니다.Redis를 조회했는데 원하는 데이터가 존재하지 않는 상황을 의미하는 용어는 무엇인가요?
3줄 요약
- 1캐시 히트는 Redis에 데이터가 있어 빠르게 반환하는 것이고, 캐시 미스는 데이터가 없어 원본 DB를 조회하는 것입니다.
- 2캐시 미스가 발생하면 메인 DB에서 데이터를 읽어와 사용자에게 주고, 동시에 Redis에도 다시 저장해두어야 합니다.
- 3이처럼 캐시를 먼저 확인하고 없으면 DB를 조회하는 방식을 실무에서 'Cache-Aside 패턴'이라 부릅니다.