캐시 데이터가 100GB를 넘어갑니다. 단일 Redis 서버의 RAM으로는 감당이 안 됩니다. Redis Cluster로 여러 서버에 데이터를 나눠 저장하면 이 문제를 해결할 수 있습니다.
Redis Cluster는 16384개의 슬롯을 나눠 각 노드에 할당합니다.
노드 A: 슬롯 0 ~ 5460
노드 B: 슬롯 5461 ~ 10922
노드 C: 슬롯 10923 ~ 16383
키가 어느 노드에 저장될지는 슬롯 번호로 결정됩니다.
슬롯 번호 = CRC16(키) mod 16384
SET user:1000 "data"
→ CRC16("user:1000") mod 16384 = 7638
→ 슬롯 7638은 노드 B에 있음
→ 노드 B에 저장
CRC16: 데이터 무결성 검사에 쓰이는 해시 함수. Redis Cluster는 이를 이용해 키를 균등하게 16384개 슬롯에 분산합니다.
클라이언트가 잘못된 노드에 요청하면 Redis가 올바른 노드를 알려줍니다.
# 클라이언트가 노드 A에 연결해 요청
GET user:1000
# MOVED 7638 192.168.1.102:6379
# → "슬롯 7638은 노드 B(192.168.1.102)에 있어"
Cluster 지원 클라이언트는 이를 자동으로 처리합니다.
Master 3대, 각 Master에 Replica 1대 → 총 6대
Master A (슬롯 0~5460) ← Replica A'
Master B (슬롯 5461~10922) ← Replica B'
Master C (슬롯 10923~16383) ← Replica C'
노드 하나가 죽으면 해당 Replica가 Master로 승격해 서비스를 유지합니다.
redis-cli --cluster create \
192.168.1.100:6379 \
192.168.1.101:6379 \
192.168.1.102:6379 \
192.168.1.103:6379 \
192.168.1.104:6379 \
192.168.1.105:6379 \
--cluster-replicas 1
--cluster-replicas 1: 각 Master에 Replica를 1개씩 자동 배정.
import { Cluster } from "ioredis";
const cluster = new Cluster([
{ host: "192.168.1.100", port: 6379 },
{ host: "192.168.1.101", port: 6379 },
{ host: "192.168.1.102", port: 6379 },
]);
// 사용법은 일반 Redis와 동일
await cluster.set("user:1000", "data");
await cluster.get("user:1000");
클라이언트가 슬롯 맵을 캐시하므로, 대부분의 요청은 리다이렉션 없이 올바른 노드로 직접 갑니다.
같은 노드에 있어야 하는 키들을 {} 해시 태그로 묶습니다. 키 이름에서 중괄호 안의 문자열만으로 슬롯을 계산하므로, 관련 데이터를 같은 노드에 저장할 수 있습니다.
# user:1000의 프로필과 설정을 같은 노드에 저장
SET {user:1000}:profile "data"
SET {user:1000}:settings "data"
# {} 안의 내용으로만 슬롯 계산
# CRC16("user:1000") → 두 키 모두 같은 슬롯
Multi-key 명령(MSET, MGET, 트랜잭션 등)은 모든 키가 같은 슬롯에 있어야 합니다. 해시 태그 없이는 오류가 납니다.
MSET {user:1000}:a "v1" {user:1000}:b "v2" # OK — 같은 슬롯
MSET user:1000 "v1" user:2000 "v2" # ERR — 다른 슬롯 가능성
서버를 추가하면 기존 슬롯 일부를 새 노드로 이동합니다.
# 새 노드 추가
redis-cli --cluster add-node 192.168.1.106:6379 192.168.1.100:6379
# 슬롯 재분배 (리샤딩)
redis-cli --cluster reshard 192.168.1.100:6379
리샤딩 중에도 서비스는 중단되지 않습니다. 키가 이동 중이면 ASK 리다이렉션으로 처리합니다.
Cluster에는 몇 가지 제약이 있습니다.
SELECT 명령 불가 (DB 0만 사용)SUBSCRIBE/PUBLISH는 모든 노드에 전파되지 않을 수 있음| 항목 | Sentinel | Cluster |
|---|---|---|
| 목적 | 고가용성 | 수평 확장 + 고가용성 |
| 데이터 분산 | 없음 | 있음 (샤딩) |
| 단일 서버 용량 한계 | 있음 | 없음 |
| 설정 복잡도 | 중간 | 높음 |
| Multi-key 제약 | 없음 | 있음 |
데이터가 단일 서버에 담기면 Sentinel, 단일 서버를 넘어서면 Cluster를 선택합니다.