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

게시판 원본 데이터를 Redis에 넣으면 안 되는 이유

게시글, 댓글과 같은 핵심 원본 데이터를 휘발성인 Redis에만 저장했을 때 발생하는 치명적인 문제점을 분석합니다.

Redis의 빠른 속도를 경험하고 나면, 종종 "이왕 빠른 거, 모든 데이터를 Redis에 넣으면 안 될까?"라는 유혹에 빠집니다. 특히 응답 속도가 생명인 게시판이나 피드(Feed) 서비스에서 이런 고민을 하게 되죠.

하지만 핵심적인 비즈니스 원본 데이터를 Redis에만 보관하는 것은 시한폭탄을 안고 서비스를 운영하는 것과 같습니다. 이번 에피소드에서는 왜 특정 데이터를 절대 Redis에만 저장해서는 안 되는지 구체적인 이유를 파헤쳐봅니다.

메모리는 영원하지 않다 (휘발성의 공포)

가장 치명적인 문제는 Redis가 메모리(RAM) 기반 저장소라는 사실입니다. 컴퓨터를 사용하다가 저장하지 않은 문서가 정전으로 날아간 경험이 있으신가요? Redis도 기본적으로 이와 똑같은 약점을 가지고 있습니다.

메모리 기반 저장소의 위험성

서버 재부팅 및 정전

메모리에 적재된 모든 데이터가 즉시 증발함

프로세스 크래시(비정상 종료)

최근 변경된 내용이 복구 불가능하게 유실됨

메모리 용량 초과 (OOM)

운영체제가 강제로 Redis 프로세스를 죽여 데이터가 날아감

게시판의 '게시글 원본'이나 '댓글'은 서비스의 자산입니다. 만약 Redis 서버가 예기치 않게 재시작되어 이틀 동안 작성된 모든 게시글이 날아갔다고 상상해 보세요. 사용자의 신뢰는 바닥으로 떨어질 것입니다.

인메모리 백업 옵션의 한계

물론 Redis도 만약의 사태를 대비해 디스크에 데이터를 백업하는 RDB(스냅샷)와 AOF(로그) 기능을 제공합니다. 하지만 이는 어디까지나 재난 복구를 위한 최소한의 안전장치일 뿐, 처음부터 디스크 영속성을 고려하여 치밀하게 설계된 RDBMS(PostgreSQL 등)의 트랜잭션 안정성을 따라갈 수는 없습니다. 백업 주기에 따라 1~5분 사이의 최근 데이터는 여전히 날아갈 위험이 존재합니다.

용량과 비용의 현실적인 벽

데이터를 보관할 때 성능만큼이나 중요한 것이 경제성입니다. RAM은 SSD나 하드디스크에 비해 압도적으로 비쌉니다.

저장 매체별 용량 대비 비용 비교 (대략적 수치)

매체특징용량 한계비용 수준
RAM (Redis)가장 빠름, 휘발성수십~수백 GB매우 비쌈
SSD (PostgreSQL)빠름, 영속성 보장수 TB보통
HDD (S3 등)느림, 저렴함무제한매우 저렴

게시글은 시간이 지날수록 끝없이 누적되는 성질을 가집니다. 이를 모두 값비싼 RAM에 올려둔다면, 서비스가 성장할수록 눈덩이처럼 불어나는 서버 비용을 감당할 수 없게 됩니다.

결론: 무엇을 담아야 하는가?

Redis에는 날아가도 언제든 원본에서 다시 만들어낼 수 있는 데이터(캐시), 혹은 날아가도 치명적이지 않은 일회성 데이터(세션, 인증번호)만 저장해야 합니다. 복구 불가능한 핵심 원본은 무조건 RDBMS에 우선 저장해야 합니다.

안전하게 게시판 데이터를 다루는 법

그렇다면 빠른 게시판을 만들기 위해서는 어떻게 해야 할까요? 정답은 원본의 영구 보존과 복사본의 빠른 제공을 분리하는 것입니다.

안전한 게시글 캐싱 아키텍처

// 나쁜 예: Redis에만 게시글 저장 (위험!)
async function createPostBad(title, content) {
  const postId = generateId();
  // 데이터가 Redis에만 존재. 서버 재시작 시 영구 삭제됨
  await redis.set(`post:${postId}`, JSON.stringify({ title, content })); 
}

// 좋은 예: PostgreSQL에 저장 후 Redis로 캐싱 (안전!)
async function createPostGood(title, content) {
  // 1. 디스크 기반의 안전한 DB에 원본을 확실히 저장
  const newPost = await db.query(
    'INSERT INTO posts (title, content) VALUES ($1, $2) RETURNING *',
    [title, content]
  );
  
  // 2. 빠른 조회를 위해 Redis에 복사본(캐시) 업데이트
  await redis.set(`post:${newPost.id}`, JSON.stringify(newPost));
  
  return newPost;
}

이처럼 항상 "데이터베이스에 먼저 기록하고, Redis를 덮어씌우는" 순서를 지켜야 합니다. 만약 Redis 캐싱 과정에서 에러가 발생해도, 사용자는 데이터베이스에 저장된 원본을 통해 여전히 서비스를 이용할 수 있습니다.

개념 퀴즈

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

다음 중 Redis에 '원본'으로 저장하기에 적합한 데이터는 무엇인가요?

3줄 요약

  1. 1Redis는 메모리(RAM)를 사용하므로, 서버 재부팅 시 데이터가 영구적으로 유실될 위험이 높습니다.
  2. 2메모리는 디스크에 비해 단위 용량당 가격이 매우 비싸기 때문에 계속 누적되는 원본을 저장하기에 부적합합니다.
  3. 3게시글 같은 핵심 자산은 RDBMS에 우선 저장하고, Redis는 복사본을 임시로 제공하는 캐시 용도로만 사용해야 합니다.