[Redis] 10. 실전 설계 패턴
Redis를 활용한 실전 설계 패턴과 애플리케이션 연동 방법을 정리합니다.
캐시 패턴
Cache-Aside (Lazy Loading)
가장 일반적인 캐시 패턴입니다. 캐시에 없으면 DB에서 조회 후 캐시에 저장합니다.
1. 캐시 조회 → HIT → 반환
2. 캐시 조회 → MISS → DB 조회 → 캐시 저장 → 반환
def get_user(user_id):
# 1. 캐시 조회
cached = redis.get(f"user:{user_id}")
if cached:
return json.loads(cached)
# 2. DB 조회
user = db.query("SELECT * FROM users WHERE id = %s", user_id)
# 3. 캐시 저장 (5분 TTL)
redis.setex(f"user:{user_id}", 300, json.dumps(user))
return user
Write-Through
데이터 쓰기 시 캐시와 DB를 동시에 업데이트합니다.
def update_user(user_id, data):
# DB 업데이트
db.execute("UPDATE users SET name=%s WHERE id=%s", data['name'], user_id)
# 캐시도 업데이트
redis.setex(f"user:{user_id}", 300, json.dumps(data))
Write-Behind (Write-Back)
캐시에 먼저 쓰고, 비동기로 DB에 반영합니다. 쓰기 성능이 중요할 때 사용합니다.
def update_user(user_id, data):
# 캐시에 즉시 반영
redis.setex(f"user:{user_id}", 300, json.dumps(data))
# 비동기 큐에 DB 업데이트 작업 추가
redis.rpush("db_write_queue", json.dumps({"user_id": user_id, "data": data}))
캐시 무효화 전략
| 전략 | 설명 | 적합한 경우 |
|---|---|---|
| TTL 기반 | 일정 시간 후 자동 만료 | 약간의 지연 허용 |
| 이벤트 기반 | 데이터 변경 시 즉시 삭제 | 실시간 일관성 필요 |
| 버전 기반 | 키에 버전 포함 (user:1:v3) |
롤백 필요 시 |
# 이벤트 기반 무효화
DEL cache:user:123 # 단일 키 삭제
# 패턴 기반 무효화 (SCAN 사용)
# KEYS cache:user:* 는 운영 환경에서 사용 금지
분산 락 (Distributed Lock)
단일 인스턴스 락
# 락 획득 (NX + EX로 원자적)
SET lock:resource:123 "owner-uuid" NX EX 30
# OK → 획득 성공, nil → 이미 잠김
# 락 해제 (Lua로 안전하게)
EVAL "
if redis.call('GET', KEYS[1]) == ARGV[1] then
return redis.call('DEL', KEYS[1])
else
return 0
end
" 1 lock:resource:123 "owner-uuid"
Redlock (다중 인스턴스 락)
5개의 독립 Redis 인스턴스에서 과반수(3개 이상) 락을 획득해야 성공으로 판단합니다.
1. 현재 시간 기록
2. 5개 인스턴스에 순차적으로 락 시도 (짧은 타임아웃)
3. 과반수(3개+) 성공 AND 경과 시간 < TTL → 락 획득 성공
4. 실패 시 모든 인스턴스에서 락 해제
세션 관리
# 세션 저장 (Hash 활용)
HSET session:abc123 user_id 1 role "admin" login_at "2026-05-05T10:00:00"
EXPIRE session:abc123 1800 # 30분 TTL
# 세션 조회
HGETALL session:abc123
# 세션 갱신 (접근 시 TTL 리셋)
EXPIRE session:abc123 1800
# 세션 삭제 (로그아웃)
DEL session:abc123
실시간 랭킹 시스템
# 점수 갱신
ZINCRBY ranking:daily 10 "user:홍길동"
ZINCRBY ranking:daily 5 "user:김철수"
# 상위 10명
ZREVRANGE ranking:daily 0 9 WITHSCORES
# 내 순위
ZREVRANK ranking:daily "user:홍길동"
# 내 점수
ZSCORE ranking:daily "user:홍길동"
# 일별 랭킹 초기화 (자정에)
DEL ranking:daily
# 주간 랭킹 합산
ZUNIONSTORE ranking:weekly 7 ranking:mon ranking:tue ranking:wed ranking:thu ranking:fri ranking:sat ranking:sun
실시간 알림 / 이벤트
Pub/Sub 기반 알림
# 알림 발행
PUBLISH notifications:user:123 '{"type":"order","message":"주문이 완료되었습니다"}'
# 구독 (클라이언트)
SUBSCRIBE notifications:user:123
Stream 기반 이벤트 (영속성 필요 시)
# 이벤트 발행
XADD events:orders * user_id 123 action "created" order_id 456
# Consumer Group으로 처리
XGROUP CREATE events:orders order_processors $ MKSTREAM
XREADGROUP GROUP order_processors worker1 COUNT 10 BLOCK 5000 STREAMS events:orders >
XACK events:orders order_processors "1714900000000-0"
키 네이밍 컨벤션
| 패턴 | 예시 | 설명 |
|---|---|---|
object:id |
user:123 |
기본 객체 |
object:id:field |
user:123:name |
객체의 필드 (String) |
action:object:id |
cache:user:123 |
용도 접두사 |
scope:object:id |
session:abc123 |
범위 접두사 |
object:id:relation |
user:123:followers |
관계 |
time:object:id |
rate:user:123 |
시간 기반 |
권장 규칙
- 구분자는
:사용 (일관성) - 짧지만 의미 있는 이름
- 환경 접두사 사용 (
prod:,dev:) - 날짜 포함 시 ISO 형식 (
2026-05-05)
- [Redis] 11. 모니터링과 Troubleshooting
- [Redis] 10. 실전 설계 패턴
- [Redis] 09. 메모리 관리와 설정
- [Redis] 08. 복제, Sentinel, Cluster (고가용성)
- [Redis] 07. 영속성 (RDB, AOF)
- [Redis] 06. Pub/Sub, 트랜잭션, Lua 스크립팅
- [Redis] 05. 고급 자료구조 (Stream, HyperLogLog, Bitmap, Geo)
- [Redis] 04. Hash와 Sorted Set
- [Redis] 03. List와 Set
- [Redis] 02. String과 숫자 (기본 자료구조)
- [Redis] 01. Redis 소개 및 설치