LLM WikiAccess-protected knowledge portal
← 스터디 홈
4편 · 약 18분

클러스터 모드와 샤딩

왜 Redis Cluster가 필요한가

단일 Redis 인스턴스는 구조가 단순하고 지연시간이 낮다. 하지만 데이터셋이 한 서버의 메모리를 넘거나, 한 코어가 감당할 수 있는 명령 처리량을 넘으면 수직 확장만으로는 오래 버티기 어렵다. Redis Cluster는 이 문제를 키 공간을 여러 master에 나누는 방식으로 푼다. 즉, 모든 노드가 같은 데이터를 들고 있는 것이 아니라 각 master가 전체 키 공간의 일부를 책임진다.

여기서 중요한 운영 판단은 “Cluster를 켜면 Redis가 자동으로 모든 문제를 해결한다”가 아니다. Cluster는 확장성과 일부 장애 상황의 가용성을 주지만, 애플리케이션의 키 설계, 클라이언트 라이브러리, 네트워크 구성, resharding 절차가 함께 맞아야 한다. 특히 multi-key 명령, Lua script, transaction을 많이 쓰는 서비스라면 Cluster 전환 전에 키들이 같은 shard에 있어야 하는지부터 검토해야 한다.

Client
cluster-aware
→ key 계산 CRC16(key) % 16384 → slot
Master A
slots 0-5460
Master B
slots 5461-10922
Master C
slots 10923-16383
Replica A Replica B Replica C
Redis Cluster는 전체 키 공간을 slot으로 나누고, slot 범위를 master들이 나눠 가진다

hash slot: Redis Cluster의 분할 단위

Redis Cluster는 consistent hashing을 쓰지 않는다. 대신 전체 키 공간을 16,384개의 hash slot으로 고정해 둔다. 각 키의 slot은 다음 식으로 계산한다.

HASH_SLOT = CRC16(key) % 16384

예를 들어 master가 3개라면 다음처럼 slot 범위를 나눌 수 있다.

master책임지는 slot 예시역할
A0 ~ 5460해당 slot의 key read/write 처리
B5461 ~ 10922해당 slot의 key read/write 처리
C10923 ~ 16383해당 slot의 key read/write 처리

slot을 분할 단위로 쓰는 이유는 운영이 단순해지기 때문이다. 새 노드를 추가할 때 전체 키를 다시 hashing하는 것이 아니라 일부 slot을 새 master로 옮긴다. 노드를 제거할 때도 그 노드가 가진 slot을 다른 master로 옮긴 뒤 비우면 된다. 공식 문서는 slot 이동이 운영 중에도 가능하다고 설명하지만, 이것이 “부하 영향이 없다”는 뜻은 아니다. 실제로는 key migration traffic, client redirection, hot key 여부를 함께 봐야 한다.

CLUSTER KEYSLOT은 특정 key가 어떤 slot으로 가는지 확인할 때 쓴다.

CLUSTER KEYSLOT user:123:profile
CLUSTER KEYSLOT user:{123}:profile
CLUSTER KEYSLOT user:{123}:cart

위 두 번째와 세 번째 key는 {123}이라는 같은 hash tag를 쓰기 때문에 같은 slot으로 간다.

클라이언트 라우팅: proxy가 아니라 redirect

Redis Cluster의 핵심 특징 중 하나는 Redis Open Source Cluster가 기본적으로 중앙 proxy를 두지 않는다는 점이다. 각 노드는 자신이 맡은 slot을 알고 있고, 다른 노드의 slot 정보도 cluster bus를 통해 공유한다. 클라이언트가 잘못된 노드에 명령을 보내면 Redis는 직접 대신 처리해 주지 않고 redirection error를 돌려준다.

대표적인 redirection은 두 가지다.

응답의미클라이언트가 해야 할 일
MOVED해당 slot의 소유자가 완전히 다른 노드로 바뀜slot map을 갱신하고 새 노드로 재요청
ASKslot이 migration 중이라 임시로 다른 노드에 물어봐야 함ASKING 후 대상 노드로 해당 요청만 보냄

잘 만든 cluster-aware client는 시작 시 CLUSTER SHARDS 또는 구버전 호환으로 CLUSTER SLOTS를 호출해 slot-to-node map을 만든다. Redis 7.0부터는 CLUSTER SHARDSCLUSTER SLOTS의 더 확장 가능한 대체 명령으로 권장된다. 이후 일반 명령은 key의 slot을 로컬에서 계산해 바로 해당 master로 보낸다. MOVED를 받으면 topology cache를 갱신한다.

운영에서 피해야 할 패턴은 cluster를 구성해 놓고도 cluster를 모르는 client나 단일 endpoint 가정의 wrapper를 쓰는 것이다. 이런 경우 일부 명령은 우연히 성공하지만 slot이 다른 key가 섞이는 순간 MOVED, CROSSSLOT, connection retry 폭증이 발생한다.

hash tag: multi-key 제약을 다루는 도구

Redis Cluster에서는 대부분의 single-key 명령이 자연스럽게 동작한다. 문제는 MGET, MSET, set intersection, transaction, Lua script처럼 여러 key를 한 번에 다루는 명령이다. Redis Cluster는 여러 key가 같은 slot에 있을 때만 이런 명령을 허용한다. 서로 다른 slot이면 다음과 같은 CROSSSLOT 오류가 난다.

MSET user:1:name Kim user:1:cart cart-123
(error) CROSSSLOT Keys in request don't hash to the same slot

관련 key를 같은 slot에 넣고 싶을 때 hash tag를 쓴다. key 이름 안에 {...}가 있으면 Redis는 전체 key가 아니라 중괄호 안의 문자열만 hash한다.

MSET user:{1}:name Kim user:{1}:cart cart-123

이 설계는 강력하지만 남용하면 위험하다. 예를 들어 모든 세션 key에 {session} 같은 고정 tag를 넣으면 모든 session key가 한 slot으로 몰린다. 그러면 Cluster를 쓰고 있어도 실제로는 한 master가 대부분의 부하를 받는 hot slot이 된다.

실무 기준은 다음처럼 잡는 편이 안전하다.

키 관계권장 key 설계이유
한 사용자 안에서 원자적 multi-key 처리가 필요user:{userId}:profile, user:{userId}:cart사용자 단위 locality 확보
전체 서비스 공통 카운터hash tag 없이 분산 또는 shard suffix 사용단일 hot slot 방지
leaderboard처럼 특정 집합이 한 자료구조여야 함하나의 key 또는 의도적 hash tag분산보다 자료구조 원자성이 중요
단순 캐시 keyhash tag 사용하지 않음자동 분산에 맡김

cluster bus와 장애 감지

Cluster 노드는 client port 외에 node-to-node 통신용 port를 하나 더 쓴다. 기본값은 Redis port에 10000을 더한 값이다. 예를 들어 client port가 6379라면 cluster bus port는 기본적으로 16379다. 이 bus는 gossip, 실패 감지, configuration update, failover authorization 등에 쓰인다.

따라서 방화벽이나 보안그룹에서 client port만 열어 두면 Cluster는 정상 동작하지 않는다. 클라이언트는 cluster bus port로 접속하면 안 되지만, Redis 노드끼리는 서로의 bus port에 접근할 수 있어야 한다.

또 하나의 함정은 NAT와 port mapping이다. Redis Cluster는 노드가 서로에게 알려 주는 주소와 포트가 실제 접근 가능한 주소라는 가정을 강하게 가진다. 공식 문서는 NAT 환경이나 IP/port가 remap되는 환경을 일반적으로 지원하지 않는다고 설명한다. Docker에서 단순 port mapping으로 Cluster를 구성하면 노드가 자기 자신이 알고 있는 주소와 외부에서 접근해야 하는 주소가 달라져 문제가 생길 수 있다. 테스트 환경이라도 host networking 또는 명시적인 announce 설정을 신중히 봐야 한다.

master-replica와 가용성 한계

Cluster에서 shard는 “같은 slot 집합을 서비스하며 서로 복제 관계에 있는 노드 묶음”으로 볼 수 있다. 한 shard에는 한 시점에 master가 하나 있고, replica가 0개 이상 붙을 수 있다. 운영 구성에서는 보통 최소 3 masters + 3 replicas, 즉 6개 노드를 출발점으로 본다.

redis-cli --cluster create \
  10.0.0.1:6379 10.0.0.2:6379 10.0.0.3:6379 \
  10.0.0.4:6379 10.0.0.5:6379 10.0.0.6:6379 \
  --cluster-replicas 1

이 구성은 각 master에 replica 하나를 붙인다. master 하나가 죽으면 해당 replica가 승격되어 slot을 계속 서비스할 수 있다. 하지만 master와 그 replica가 함께 죽으면 해당 slot 범위는 서비스할 수 없다. 또한 master들의 과반이 사라지는 큰 네트워크 분할에서는 Cluster 전체가 unavailable해질 수 있다.

일관성도 강한 편이 아니다. Redis Cluster는 기본적으로 비동기 복제를 사용한다. master가 쓰기를 받고 OK를 반환한 뒤 replica로 전파하기 전에 죽으면, 승격된 replica에는 그 쓰기가 없을 수 있다. Cluster는 확장성과 가용성을 높이는 구조이지, 합의 기반의 강한 일관성 저장소가 아니다.

resharding: 노드 추가와 제거는 slot 이동이다

Cluster 확장은 “새 노드를 붙인다”에서 끝나지 않는다. 새 master가 실제 트래픽을 받으려면 기존 master들이 가진 slot 일부를 새 master로 옮겨야 한다. redis-cli --cluster reshard 같은 도구는 내부적으로 source node와 destination node 사이에서 slot을 MIGRATING / IMPORTING 상태로 두고 key를 옮긴다.

운영 절차는 대략 다음 흐름이다.

  1. 새 Redis 노드를 cluster mode로 띄운다.
  2. CLUSTER MEET 또는 redis-cli --cluster add-node로 클러스터에 합류시킨다.
  3. 새 노드가 master로 slot을 받을 준비가 되었는지 확인한다.
  4. 기존 master들에서 일부 slot을 새 master로 reshard한다.
  5. CLUSTER SHARDS, CLUSTER INFO, client error rate, latency를 확인한다.
  6. 필요하면 replica를 재배치해 장애 도메인 균형을 맞춘다.

노드 제거는 반대다. 제거할 master가 가진 slot을 모두 다른 master로 옮긴 다음 제거한다. slot을 가진 master를 바로 내리면 해당 slot이 unavailable해진다.

resharding 중에는 ASK redirection이 늘어날 수 있고, multi-key 명령은 더 민감해진다. 공식 specification도 manual resharding 동안 hash tag를 쓰는 multi-key operation이 잠깐 unavailable할 수 있다고 설명한다. 운영 중 resharding은 가능하지만, peak traffic 시간에 무심코 실행할 작업은 아니다.

운영자가 보는 기본 명령

Cluster 운영에서는 몇 가지 명령을 자주 본다.

명령용도운영 판단
CLUSTER INFOcluster state와 slot coverage 확인cluster_state:ok인지 확인
CLUSTER NODESnode ID, role, link, slot 범위 확인장애 노드, replica 관계 확인
CLUSTER SHARDSshard 단위 topology 확인Redis 7+ client topology source
CLUSTER KEYSLOT <key>key가 어느 slot인지 확인hash tag 설계 검증
redis-cli --cluster check <host:port>slot coverage와 node 상태 점검운영 점검과 변경 전후 비교

특히 CLUSTER NODES 출력은 익숙해져야 한다. node ID는 resharding, replica 지정, failover 조작에서 자주 쓰인다. IP와 port만 보고 판단하면 노드 재생성이나 컨테이너 재배치 때 실수하기 쉽다.

Cluster 전환 전 체크리스트

Cluster 전환은 인프라 작업처럼 보이지만 실제로는 애플리케이션 계약 변경에 가깝다. 다음 질문에 답하지 못하면 먼저 staging에서 충분히 검증해야 한다.

질문확인 방법위험
사용하는 client가 Redis Cluster를 지원하는가client 문서와 실제 MOVED 처리 테스트redirection loop, 일부 명령 실패
multi-key 명령이 있는가command log, 코드 검색CROSSSLOT 장애
Lua script나 transaction이 여러 key를 쓰는가script key 목록 점검같은 slot 조건 위반
key prefix에 hash tag가 필요한가도메인별 key 설계 리뷰hot slot 또는 원자성 부족
NAT/port mapping이 있는가노드 announce 주소와 실제 reachability 확인cluster bus 단절
resharding runbook이 있는가staging에서 add/remove node 리허설운영 중 slot 불균형, 장애 확대

Cluster가 적합하지 않은 경우도 있다. 데이터셋이 작고 단일 노드 병목이 없다면 Sentinel 기반 HA가 더 단순할 수 있다. 반대로 데이터가 크고 key 접근이 비교적 독립적이며 single-key 중심이라면 Cluster가 자연스럽다. 핵심은 Redis를 어떤 저장소로 쓰는지다. 캐시와 세션처럼 key 단위 접근이 많은 워크로드는 Cluster에 잘 맞고, 여러 key를 한 트랜잭션처럼 묶는 워크로드는 설계 제약이 커진다.

정리

Redis Cluster의 핵심은 “노드를 여러 개 둔다”가 아니라 16,384개 hash slot을 여러 master에 나누고, 클라이언트가 slot을 이해해 올바른 노드로 요청을 보내는 구조다. 이 구조 덕분에 데이터와 처리량을 수평으로 확장할 수 있고, replica가 있으면 일부 master 장애도 넘길 수 있다.

하지만 운영상 대가는 분명하다. multi-key 명령은 같은 slot에 묶어야 하고, hash tag는 hot slot을 만들 수 있으며, cluster-aware client가 필수다. 또한 cluster bus port, announce 주소, NAT, resharding 절차 같은 네트워크·운영 세부사항이 맞지 않으면 단일 Redis보다 장애 양상이 더 복잡해진다.

실무에서는 다음 순서로 접근하는 것이 안전하다.

  1. 현재 Redis 사용 패턴이 single-key 중심인지 확인한다.
  2. multi-key가 필요한 도메인만 hash tag로 묶는다.
  3. cluster-aware client로 MOVED, ASK, topology refresh를 검증한다.
  4. staging에서 node add/remove와 resharding을 실제로 연습한다.
  5. 운영에서는 slot 분포, hot key, replica coverage, cluster bus reachability를 계속 감시한다.

Redis Cluster는 Redis를 여러 대로 늘리는 버튼이 아니라, key 설계와 운영 절차까지 함께 바꾸는 샤딩 모델이다.

References