MMeshOps
Redis 실전: 서비스 장애를 막는 안전한 캐싱과 상태 관리
7예상 8중급

캐시 미스(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), 없으면 그때 데이터베이스로 찾아가는 방식입니다.

캐시 미스를 복구하는 표준 워크플로우

캐시 미스가 발생했을 때 데이터를 조회하고 복구하는 과정은 개발자들이 매일 작성하는 매우 정형화된 패턴입니다. 다음과 같은 세 단계를 거치게 됩니다.

캐시 미스 발생 시 데이터 복구 흐름

  1. 1Redis에 데이터를 요청합니다. (데이터가 없어 null이 반환됨)
  2. 2메인 데이터베이스(PostgreSQL)에 쿼리를 날려 원본 데이터를 조회합니다.
  3. 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. 1캐시 히트는 Redis에 데이터가 있어 빠르게 반환하는 것이고, 캐시 미스는 데이터가 없어 원본 DB를 조회하는 것입니다.
  2. 2캐시 미스가 발생하면 메인 DB에서 데이터를 읽어와 사용자에게 주고, 동시에 Redis에도 다시 저장해두어야 합니다.
  3. 3이처럼 캐시를 먼저 확인하고 없으면 DB를 조회하는 방식을 실무에서 'Cache-Aside 패턴'이라 부릅니다.