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

영원한 캐시는 없다: TTL(Time To Live)의 중요성

Redis 데이터에 만료 시간(TTL)을 설정하여 메모리 누수를 방지하고 데이터를 최신 상태로 유지하는 법을 알아봅니다.

Redis를 사용할 때 가장 저지르기 쉬운 실수 중 하나는 데이터를 넣기만 하고 지우지 않는 것입니다. 이번 시간에서는 Redis 메모리 고갈과 데이터의 불일치를 막기 위한 가장 중요하고 기본적인 기능인 TTL(Time To Live)에 대해 배웁니다. 데이터를 언제까지 살려둘 것인가를 결정하는 과정은 보조 저장소 설계의 핵심입니다.

무한한 데이터가 만드는 비극

데이터베이스(PostgreSQL)의 데이터는 기본적으로 우리가 명시적으로 삭제(DELETE) 쿼리를 날리기 전까지 영원히 남아있습니다. 하지만 Redis는 메모리를 기반으로 작동하기 때문에 데이터를 무한정 쌓아둘 수 없습니다.

메모리 가득 참(OOM) 문제

만약 우리가 사용자 로그인 정보를 세션으로 저장하거나, 인기 검색어를 캐싱하면서 만료 시간을 설정하지 않는다면 어떻게 될까요? 트래픽이 늘어나면서 서버의 RAM이 점차 가득 차게 되고, 결국 Redis 서버가 죽어버리는 OOM(Out of Memory) 현상이 발생합니다. 이는 곧바로 전체 서비스 장애로 직결될 수 있습니다.

TTL 부재 시 발생하는 현상

만료 시간 없이 데이터 적재

Redis 메모리 사용량 지속 증가

메모리 한계 초과 (OOM)

Redis 서버 다운 및 새로운 데이터 쓰기 실패

캐시 시스템 마비

메인 데이터베이스로 트래픽이 몰려 서비스 전체 장애

TTL (Time To Live): 데이터의 수명 타이머

이러한 문제를 해결하기 위해 존재하는 개념이 바로 TTL(Time To Live) 입니다. TTL은 말 그대로 데이터가 살아있는 시간(수명)을 의미합니다. Redis에 데이터를 저장할 때 '이 데이터는 10분 뒤에 삭제해줘'라고 설정하면, 시간이 지난 후 Redis가 알아서 데이터를 메모리에서 지워줍니다.

TTL이 해결하는 두 가지 문제

TTL을 설정하면 앞서 말한 메모리 고갈 문제를 방지할 수 있습니다. 또한, 오래된 데이터가 영원히 남아 사용자에게 과거의 잘못된 정보를 보여주는 데이터 불일치(Stale Data) 문제도 완화시켜줍니다.

정의

Stale Data (오래된 데이터)

원본 데이터베이스(PostgreSQL)에서는 이미 정보가 변경되었지만, 캐시(Redis)에는 과거의 데이터가 남아있어 사용자에게 잘못 노출되는 데이터를 의미합니다.

적절한 TTL을 설정하는 기준

그렇다면 TTL은 얼마로 설정하는 것이 좋을까요? 짧게 잡으면 데이터를 자주 갱신해야 하므로 메인 데이터베이스에 부담이 가고, 길게 잡으면 메모리를 많이 차지하며 사용자에게 과거 데이터가 노출될 확률이 높아집니다.

데이터 성격에 따른 수명

데이터가 얼마나 자주 변하는지, 그리고 사용자가 약간 과거의 데이터를 봐도 괜찮은지가 기준이 됩니다. 예를 들어 쇼핑몰 메인 페이지의 '주간 베스트 상품'은 10분~1시간 정도 과거의 데이터라도 큰 문제가 없습니다. 반면 사용자 개인의 장바구니 개수나 결제 관련 상태는 1분이라도 틀리면 큰 불만이 발생합니다.

상황별 적절한 TTL 설정

상황선택이유
주간/일간 베스트 인기글 목록1시간 ~ 6시간실시간성이 조금 떨어져도 서비스 품질에 큰 영향이 없음
사용자의 로그인 세션30분 ~ 1시간보안을 위해 일정 시간 활동이 없으면 자동 로그아웃 처리
이메일/문자 인증 번호3분 ~ 5분인증 번호 유출 및 무차별 대입(Brute-force) 공격 방지

코드에서 만나는 TTL

개발자가 코드를 작성할 때, 대부분의 라이브러리는 Redis에 데이터를 저장하는 함수(Set)와 함께 TTL을 설정하는 옵션(Ex)을 제공합니다.

Node.js 환경에서의 TTL 설정 예시

// Redis에 데이터를 저장하면서 동시에 600초(10분) 뒤에 만료되도록 설정합니다.
// EX 옵션은 Expire의 약자로 초(Seconds) 단위를 의미합니다.
await redisClient.set('best_products', JSON.stringify(products), {
  EX: 600
});

개념 퀴즈

퀴즈 답을 맞춰야 학습 완료가 됩니다.

다음 중 TTL(Time To Live)에 대한 설명으로 올바른 것은 무엇인가요?

3줄 요약

  1. 1Redis는 메모리를 사용하므로 모든 데이터에 수명(TTL)을 지정해 메모리 고갈을 막아야 합니다.
  2. 2TTL을 통해 과거의 데이터(Stale Data)가 사용자에게 영원히 노출되는 것을 방지할 수 있습니다.
  3. 3데이터의 실시간성 요구와 중요도에 따라 3분, 1시간 등 상황에 맞는 적절한 TTL을 설정해야 합니다.