Redis 실전 가이드

Redis의 핵심 개념과 실무 활용

JavaScript중급
6시간
3개 항목
학습 진행률0 / 3 (0%)

학습 항목

1. JavaScript
Redis|캐싱|완벽|가이드
퀴즈튜토리얼
2. JavaScript
고급
Redis|테스트|전략|완벽|가이드
퀴즈튜토리얼
3. Python
고급
Redis|핵심|개념|완벽|정리
퀴즈튜토리얼
1 / 3

이미지 로딩 중...

Redis 캐싱 완벽 가이드 - 슬라이드 1/13

Redis 캐싱 완벽 가이드

Redis를 활용한 효율적인 캐싱 전략과 고급 기법을 다룹니다. 캐시 무효화, TTL 관리, 분산 캐싱 패턴 등 실무에서 필요한 핵심 개념들을 실제 코드와 함께 학습할 수 있습니다.


카테고리:JavaScript
언어:JavaScript
메인 태그:#Redis
서브 태그:
#Caching#TTL#CacheInvalidation#DistributedCache

들어가며

이 글에서는 Redis 캐싱 완벽 가이드에 대해 상세히 알아보겠습니다. 총 12가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.

목차

  1. 기본_Redis_캐싱_설정
  2. Cache-Aside_패턴
  3. Write-Through_캐싱
  4. 캐시_무효화_전략
  5. Redis_Pipeline_최적화
  6. 분산_락_구현
  7. 캐시_워밍업
  8. 스마트_TTL_관리
  9. 캐시_태깅_시스템
  10. Pub_Sub_캐시_동기화
  11. 레이트_리미팅_캐시
  12. 캐시_통계_모니터링

1. 기본_Redis_캐싱_설정

개요

Redis 클라이언트를 설정하고 기본적인 캐싱 패턴을 구현합니다. 데이터를 캐시에 저장하고 조회하는 기본 플로우를 보여줍니다.

코드 예제

const redis = require('redis');
const client = redis.createClient();

async function getUser(userId) {
  const cached = await client.get(`user:${userId}`);
  if (cached) return JSON.parse(cached);

  const user = await db.findUser(userId);
  await client.setEx(`user:${userId}`, 3600, JSON.stringify(user));
  return user;
}

설명

캐시에서 데이터를 먼저 확인하고, 없으면 DB에서 가져온 후 1시간(3600초) TTL로 캐시에 저장합니다.


2. Cache-Aside_패턴

개요

가장 일반적인 캐싱 패턴으로, 애플리케이션이 캐시를 직접 관리합니다. 캐시 미스 시 DB에서 데이터를 가져와 캐시를 업데이트합니다.

코드 예제

async function getData(key) {
  let data = await cache.get(key);

  if (!data) {
    data = await database.query(key);
    await cache.set(key, data, { EX: 600 });
  }

  return data;
}

설명

캐시에 없으면 DB 조회 후 10분간 캐시에 저장하는 Lazy Loading 방식입니다.


3. Write-Through_캐싱

개요

데이터 쓰기 시 캐시와 DB를 동시에 업데이트하여 캐시와 DB의 일관성을 보장합니다. 읽기 성능이 중요한 경우 유용합니다.

코드 예제

async function updateUser(userId, data) {
  await db.update(userId, data);
  await client.set(
    `user:${userId}`,
    JSON.stringify(data),
    { EX: 3600 }
  );
  return data;
}

설명

DB 업데이트와 동시에 캐시도 갱신하여 항상 최신 데이터를 캐시에 유지합니다.


4. 캐시_무효화_전략

개요

데이터가 변경될 때 관련된 모든 캐시를 삭제하여 stale 데이터를 방지합니다. 패턴 매칭을 사용한 일괄 삭제가 가능합니다.

코드 예제

async function invalidateUserCache(userId) {
  const keys = await client.keys(`user:${userId}:*`);

  if (keys.length > 0) {
    await client.del(keys);
  }

  await client.del(`user:${userId}`);
}

설명

특정 사용자와 관련된 모든 캐시 키를 찾아서 삭제하여 데이터 일관성을 유지합니다.


5. Redis_Pipeline_최적화

개요

여러 Redis 명령을 하나의 네트워크 요청으로 묶어서 실행합니다. 대량의 캐시 작업 시 성능을 크게 향상시킵니다.

코드 예제

async function cacheMultipleUsers(users) {
  const pipeline = client.pipeline();

  users.forEach(user => {
    pipeline.setEx(`user:${user.id}`, 3600, JSON.stringify(user));
  });

  await pipeline.exec();
}

설명

여러 SET 명령을 파이프라인으로 묶어서 한 번에 실행하여 네트워크 왕복 시간을 줄입니다.


6. 분산_락_구현

개요

분산 환경에서 동시성 문제를 해결하기 위한 락 메커니즘입니다. Redis의 원자적 연산을 활용하여 안전한 락을 구현합니다.

코드 예제

async function acquireLock(lockKey, timeout = 10) {
  const lockValue = Date.now() + timeout * 1000;
  const acquired = await client.set(
    lockKey, lockValue, { NX: true, EX: timeout }
  );

  return acquired ? lockValue : null;
}

설명

NX 옵션으로 키가 없을 때만 설정하여 원자적 락을 획득하고, TTL로 데드락을 방지합니다.


7. 캐시_워밍업

개요

애플리케이션 시작 시 자주 사용되는 데이터를 미리 캐시에 로드합니다. Cold start 시의 성능 저하를 방지합니다.

코드 예제

async function warmupCache() {
  const popularItems = await db.getPopularItems(100);

  for (const item of popularItems) {
    await client.setEx(
      `item:${item.id}`, 7200, JSON.stringify(item)
    );
  }
}

설명

인기 있는 데이터를 미리 2시간 TTL로 캐시에 저장하여 초기 요청부터 빠른 응답을 제공합니다.


8. 스마트_TTL_관리

개요

데이터 특성에 따라 동적으로 TTL을 설정합니다. 자주 조회되는 데이터는 더 긴 TTL을 부여하여 캐시 효율을 높입니다.

코드 예제

async function setWithSmartTTL(key, value, accessCount) {
  const baseTTL = 300;
  const ttl = baseTTL + Math.min(accessCount * 60, 3600);

  await client.setEx(key, ttl, JSON.stringify(value));
  await client.incr(`${key}:access`);
}

설명

접근 횟수에 따라 TTL을 동적으로 조정하여 인기 데이터는 더 오래 캐시에 유지합니다.


9. 캐시_태깅_시스템

개요

관련된 캐시들을 태그로 그룹화하여 효율적으로 관리합니다. 특정 태그의 모든 캐시를 한 번에 무효화할 수 있습니다.

코드 예제

async function cacheWithTags(key, value, tags) {
  await client.set(key, value);

  for (const tag of tags) {
    await client.sAdd(`tag:${tag}`, key);
  }
}

async function invalidateByTag(tag) {
  const keys = await client.sMembers(`tag:${tag}`);
  if (keys.length) await client.del(keys);
}

설명

Set 자료구조로 태그별 키를 관리하여, 카테고리별 일괄 캐시 삭제가 가능합니다.


10. Pub_Sub_캐시_동기화

개요

여러 서버 인스턴스 간 캐시를 동기화합니다. 한 서버에서 캐시 무효화 시 다른 서버들도 자동으로 업데이트됩니다.

코드 예제

const subscriber = redis.createClient();

subscriber.subscribe('cache:invalidate');
subscriber.on('message', (channel, key) => {
  localCache.delete(key);
});

async function invalidateGlobal(key) {
  await client.publish('cache:invalidate', key);
}

설명

Redis Pub/Sub으로 캐시 무효화 이벤트를 브로드캐스트하여 분산 환경에서 캐시 일관성을 유지합니다.


11. 레이트_리미팅_캐시

개요

Redis를 활용한 API 요청 제한 구현입니다. 시간 윈도우 내 요청 횟수를 추적하여 과도한 요청을 차단합니다.

코드 예제

async function checkRateLimit(userId, limit = 100) {
  const key = `ratelimit:${userId}:${Date.now() / 60000 | 0}`;
  const current = await client.incr(key);

  if (current === 1) await client.expire(key, 60);

  return current <= limit;
}

설명

분당 요청 횟수를 카운트하고 1분 후 자동 삭제되어, 간단하고 효율적인 레이트 리미팅을 구현합니다.


12. 캐시_통계_모니터링

개요

캐시 히트율과 성능 지표를 추적합니다. 캐시 효율성을 측정하고 최적화 포인트를 찾는데 활용합니다.

코드 예제

async function getCacheStats() {
  const info = await client.info('stats');
  const hits = parseInt(info.match(/keyspace_hits:(\d+)/)[1]);
  const misses = parseInt(info.match(/keyspace_misses:(\d+)/)[1]);

  const hitRate = (hits / (hits + misses) * 100).toFixed(2);
  return { hits, misses, hitRate: `${hitRate}%` };
}

설명

Redis의 통계 정보를 파싱하여 캐시 히트율을 계산하고 캐시 전략의 효과를 측정합니다.


마치며

이번 글에서는 Redis 캐싱 완벽 가이드에 대해 알아보았습니다. 총 12가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.

관련 태그

#Redis #Caching #TTL #CacheInvalidation #DistributedCache

#Redis#Caching#TTL#CacheInvalidation#DistributedCache#JavaScript