"Remote Dictionary Server" — 원격에 위치한 프로세스로 동작하는 인메모리 키-값 데이터 구조 서버
Redis는 단순한 캐시가 아니라 데이터베이스, 캐시, 메시지 브로커, 스트리밍 엔진으로 모두 쓰인다. RAM에서 직접 처리하므로 디스크 기반 DB 대비 수백 배 빠르지만, 용량이 제한적이고 기본적으로 영속성을 보장하지 않는다는 트레이드오프가 있다.
디스크 I/O 병목이 없다. 10,000건 기준으로 디스크는 약 30초, RAM은 약 0.0002초가 소요된다.
단순 String이 아니라 연산 특성에 맞게 자체 구현된 자료구조를 사용한다.
Redis 핵심 엔진은 싱글 스레드로 동작한다.
epoll/kqueue 같은 비차단 I/O로 수만 개의 클라이언트 연결을 동시에 처리싱글 스레드이기 때문에
KEYS *,SMEMBERS,HGETALL같은 O(N) 명령어 하나가 전체 서버를 블로킹할 수 있다. 운영 환경에서 주의해야 한다.
Redis의 가장 기본 타입. 텍스트, 숫자, 바이너리 모두 저장 가능하며 최대 512MB.
SET user:1:name "Alice"
GET user:1:name
INCR page:view:count # 원자적 카운터
INCRBY page:view:count 5
주요 사용 사례:
SET key value NX EX seconds)필드-값 쌍의 집합. 객체 하나를 키 하나로 표현하기에 적합하다.
HSET user:1 name "Alice" age 30 email "alice@example.com"
HGET user:1 name
HGETALL user:1
HINCRBY user:1 age 1
주요 사용 사례:
HGETALL은 O(N)이므로 필드가 많을 때는 특정 필드만HGET으로 가져오는 것이 안전하다.
삽입 순서가 유지되는 이중 연결 리스트. 양쪽 끝에서 O(1)로 삽입/삭제가 가능하다.
LPUSH queue:email "job1" # 왼쪽 삽입 (최신)
RPUSH queue:email "job2" # 오른쪽 삽입
LPOP queue:email # 왼쪽 제거 (스택)
RPOP queue:email # 오른쪽 제거 (큐)
LRANGE queue:email 0 -1 # 전체 조회 (O(N))
BLPOP queue:email 30 # 블로킹 팝 (최대 30초 대기)
주요 사용 사례:
중복 없는 고유 값의 집합. 순서 보장 없음. 합집합/교집합/차집합 연산 지원.
SADD user:1:tags "backend" "redis" "java"
SISMEMBER user:1:tags "redis" # 멤버 여부 O(1)
SMEMBERS user:1:tags # 전체 조회 (O(N) 주의)
SUNION user:1:tags user:2:tags # 합집합
SINTER user:1:tags user:2:tags # 교집합 (공통 팔로워 등)
SCARD user:1:tags # 크기
주요 사용 사례:
각 멤버에 **score(실수)**를 부여해 정렬 상태를 유지하는 집합. score 기준 범위 조회가 O(log N).
ZADD leaderboard 1500 "user:alice"
ZADD leaderboard 2300 "user:bob"
ZRANK leaderboard "user:alice" # 순위 (낮은 score = 낮은 순위)
ZREVRANK leaderboard "user:bob" # 역순 순위
ZRANGE leaderboard 0 9 WITHSCORES # 하위 10명
ZREVRANGE leaderboard 0 9 WITHSCORES # 상위 10명
ZINCRBY leaderboard 100 "user:alice" # score 증가
주요 사용 사례:
String을 비트 배열로 취급. 512MB String = 약 42억 비트. 공간 효율이 매우 높다.
SETBIT user:login:20260327 1001 1 # 유저 1001 오늘 로그인
GETBIT user:login:20260327 1001
BITCOUNT user:login:20260327 # 오늘 로그인한 유저 수
BITOP AND result key1 key2 # 7일 연속 로그인 유저
주요 사용 사례:
집합의 원소 개수(카디널리티)를 근사치로 계산하는 자료구조. 오차율 약 0.81%이지만 메모리를 최대 12KB만 사용한다.
PFADD uv:20260327 "user:1" "user:2" "user:1" # 중복 자동 제거
PFCOUNT uv:20260327 # 약 2 반환
PFMERGE uv:week uv:day1 uv:day2 uv:day3 # 주간 UV 합산
주요 사용 사례:
Redis 5.0에 추가된 로그 구조 자료구조. Kafka와 유사하게 소비자 그룹 기반으로 메시지를 처리한다.
XADD orders * userId 1001 amount 50000 # 메시지 추가
XLEN orders # 메시지 수
XREAD COUNT 10 STREAMS orders 0 # 읽기
XREADGROUP GROUP workers consumer1 COUNT 10 STREAMS orders > # 소비자 그룹 읽기
XACK orders workers <message-id> # 처리 완료 ACK
주요 사용 사례:
가장 일반적인 Redis 활용 사례. 캐싱 전략은 Look-Aside, Read-Through, Write-Through, Write-Behind 등 다양하다.
→ 캐싱 전략 상세: 캐시 설계 전략 총정리
실전 포인트:
다중 서버 환경에서 서버 간 세션 불일치 문제를 해결한다. 인메모리라 조회가 빠르고, TTL로 세션 만료를 자동 처리한다.
SET session:{token} {user_json} EX 1800 # 30분 세션
GET session:{token}
DEL session:{token} # 로그아웃
Redis vs Memcached (세션 저장소 비교):
| 항목 | Redis | Memcached |
|---|---|---|
| 자료구조 | String, Hash, List 등 다양 | String만 |
| 영속성 | RDB/AOF 지원 | 없음 |
| Replication | Master-Replica 지원 | 없음 |
| 클러스터 | 공식 Cluster 지원 | 별도 구성 필요 |
| 성능 | 읽기 우수 | 단순 쓰기 빠름 |
세션 저장소라면 대부분의 경우 Redis가 더 적합하다.
여러 서버가 동일한 자원에 동시 접근하는 것을 막는다. SET NX EX 조합으로 원자적으로 락을 획득한다.
SET lock:resource:1 {owner} NX EX 30 # 락 획득 (이미 있으면 실패)
DEL lock:resource:1 # 락 해제
채널을 통해 발행자(Publisher)와 구독자(Subscriber) 간 실시간 메시지를 전달한다.
SUBSCRIBE channel:notifications # 구독
PUBLISH channel:notifications "새 알림" # 발행
PSUBSCRIBE channel:* # 패턴 구독
주의: Pub/Sub은 메시지를 영속하지 않는다. 구독자가 없거나 오프라인이면 메시지가 유실된다. 신뢰성이 필요하다면 Redis Stream을 사용해야 한다.
주요 사용 사례:
# 슬라이딩 윈도우: Sorted Set 방식
ZADD rate:user:1 {now_ms} {now_ms} # 현재 요청 추가
ZREMRANGEBYSCORE rate:user:1 0 {window_start} # 윈도우 밖 제거
ZCARD rate:user:1 # 현재 윈도우 요청 수
# 고정 윈도우: INCR 방식
INCR rate:user:1:{minute}
EXPIRE rate:user:1:{minute} 60
주요 사용 사례:
Sorted Set의 score를 점수로 사용해 실시간 순위를 O(log N)으로 유지한다.
ZINCRBY leaderboard 100 "user:1" # 점수 추가
ZREVRANK leaderboard "user:1" # 현재 순위
ZREVRANGE leaderboard 0 9 WITHSCORES # 상위 10명
ZRANGEBYSCORE leaderboard 1000 +inf # 특정 점수 이상
주요 사용 사례:
복잡한 JOIN이 필요한 읽기 조회를 Redis에 미리 조합해 저장한다.
Redis는 싱글 스레드이므로 O(N) 명령어 하나가 전체 서버를 블로킹한다.
| 위험 명령어 | 대안 |
|---|---|
KEYS * | SCAN (커서 기반 반복) |
SMEMBERS | SSCAN |
HGETALL (필드 많을 때) | HSCAN 또는 필요한 필드만 HGET |
LRANGE 0 -1 (긴 리스트) | 페이지네이션 |
FLUSHALL, FLUSHDB | 운영 환경 사용 금지 |
Redis가 메모리를 할당/해제를 반복하면 파편화가 발생해 실제 사용량보다 많은 물리 메모리를 점유할 수 있다. 심하면 OOM으로 프로세스가 종료될 수 있다.
INFO memory에서 mem_fragmentation_ratio를 모니터링 (1.5 이상이면 주의)MEMORY PURGE로 파편화 메모리 회수 가능jemalloc 사용으로 파편화 최소화 (기본값)기본 설정에서 Redis는 프로세스 재시작 시 데이터가 사라진다. 영속성이 필요하면 RDB 스냅샷이나 AOF를 설정해야 한다.
→ 영속성 및 클러스터 상세: Redis 영속성과 클러스터
CPU 코어가 많아도 단일 코어만 사용한다. CPU-bound 작업(복잡한 Lua 스크립트 등)이 많으면 처리량이 제한된다. Redis 6.0+부터는 I/O 처리는 멀티 스레드화되었지만 명령 실행은 여전히 싱글 스레드다.
마스터 장애 시 자동으로 레플리카를 마스터로 승격(Failover)하는 모니터링 시스템이다. Sentinel 자체도 홀수 개(최소 3개)로 구성해 과반수 합의로 장애를 판단한다.
Master ──→ Replica 1
└─→ Replica 2
Sentinel 1 │
Sentinel 2 ├─ Master 감시 → 장애 감지 → Replica 승격
Sentinel 3 │
16,384개의 해시 슬롯으로 데이터를 분산해 수평 확장을 지원한다.
노드 A (Master): 슬롯 0 ~ 5460
노드 B (Master): 슬롯 5461 ~ 10922
노드 C (Master): 슬롯 10923 ~ 16383
각 Master마다 Replica 보유 → 자동 Failover
CRC16(key) % 16384{}: {user:1}:orders와 {user:1}:profile은 같은 노드에 저장 (트랜잭션 지원 위해)MGET, MULTI/EXEC는 같은 슬롯의 키에만 사용 가능→ 클러스터/영속성 상세: Redis 영속성과 클러스터
사용 사례별 상세 문서:
기타: