본문 바로가기
IT & 개발

Redis 실전 캐싱 패턴 6가지 - DB 부하 90% 줄이는 설계 전략

by 냉국이 2026. 3. 12.
728x90

Redis가 필요한 이유

데이터베이스는 아무리 최적화해도 디스크 I/O와 네트워크 지연을 피할 수 없습니다. Redis는 인메모리 데이터 스토어로 초당 수십만 건의 읽기/쓰기를 처리합니다. 제대로 활용하면 DB 부하를 90% 이상 줄일 수 있습니다.

Redis 주요 자료형

자료형 용도 주요 명령어
String 단순 값, 카운터, 세션 GET, SET, INCR
Hash 객체 저장 (유저 정보) HGET, HSET, HGETALL
List 최근 본 상품, 큐 LPUSH, RPOP, LRANGE
Sorted Set 랭킹, 리더보드 ZADD, ZRANGE, ZRANK

실전 캐싱 패턴 6가지

1. Cache-Aside (Lazy Loading)

async function getUser(userId: string) {
  const cached = await redis.get(`user:${userId}`);
  if (cached) return JSON.parse(cached);
  const user = await db.user.findUnique({ where: { id: userId } });
  await redis.setex(`user:${userId}`, 3600, JSON.stringify(user));
  return user;
}

2. Write-Through

async function updateUser(userId: string, data: UserData) {
  const user = await db.user.update({ where: { id: userId }, data });
  await redis.setex(`user:${userId}`, 3600, JSON.stringify(user));
  return user;
}

3. TTL 전략

const TTL = { session: 604800, userProfile: 3600, productList: 300, realTimePrice: 10 };

4. 분산 락

const locked = await redis.set(`lock:${orderId}`, "1", "EX", 30, "NX");
if (!locked) throw new Error("이미 처리 중입니다");

5. Rate Limiting

const count = await redis.incr(`rate:${ip}`);
if (count === 1) await redis.expire(`rate:${ip}`, 60);
return count <= 100;

6. Pub/Sub

await redis.publish("notifications", JSON.stringify({ userId, message: "주문 완료" }));

결론

Redis는 단순한 캐시가 아닙니다. 락, 랭킹, 큐, 실시간 통신까지 담당하는 핵심 인프라입니다.

300x250

댓글