Redis Cluster 샤딩 전략과 핫 슬롯 병목 해결
Redis Cluster는 수평 확장과 고가용성을 동시에 제공하는 분산 아키텍처입니다. 그러나 샤딩 전략을 잘못 설계하면 특정 노드에 트래픽이 집중되는 핫 슬롯(hot slot) 현상이 발생하고, 클러스터 전체가 아닌 단일 노드 하나…
목차
- 개요
- Redis Cluster 샤딩 메커니즘 이해
- 핫 슬롯 병목의 원인과 탐지
- 핫 슬롯 해결 전략 — 데이터 분산 설계
- 운영 환경에서의 슬롯 리밸런싱
- 성능 특성과 트레이드오프 비교
- 맺음말
개요
Redis Cluster는 수평 확장과 고가용성을 동시에 제공하는 분산 아키텍처입니다. 그러나 샤딩 전략을 잘못 설계하면 특정 노드에 트래픽이 집중되는 핫 슬롯(hot slot) 현상이 발생하고, 클러스터 전체가 아닌 단일 노드 하나가 전체 시스템의 병목이 됩니다. 이 글은 Redis Cluster의 해시 슬롯 분배 원리부터 시작해, 핫 슬롯이 생기는 구조적 원인을 분석하고, 현업에서 검증된 해결 전략을 구체적으로 다룹니다.
Redis Cluster는 16,384개의 슬롯을 노드에 나누어 담당하게 합니다. 키 하나가 어느 노드로 가야 하는지는 CRC16(key) % 16384라는 단순한 공식으로 결정됩니다. 이 메커니즘 자체는 견고하지만, 애플리케이션 코드가 같은 접두사를 가진 키를 지나치게 많이 생성하거나, 특정 비즈니스 엔티티가 동일한 해시 슬롯에 집중되면 한 노드만 과부하 상태가 됩니다. 더 심각한 문제는, Redis의 단일 스레드 특성상 해당 노드에서 처리 지연이 발생하면 그 영향이 연결된 모든 명령으로 전파된다는 점입니다.
문제 배경
클러스터를 구성했음에도 모니터링 대시보드에서 노드 한두 개의 CPU 사용률이 90%를 넘어서고, 나머지 노드는 10~20%에 머무는 상황은 핫 슬롯 병목의 전형적인 신호입니다. 2022년 이후 Redis 7.x 버전이 광범위하게 도입되면서 클러스터 규모가 커졌고, 이에 따라 슬롯 분배의 불균형 문제도 보고 빈도가 높아졌습니다.
Redis Cluster 도입 초기에는 단순히 "노드를 늘리면 된다"는 인식이 지배적이었습니다. 그러나 노드를 추가해도 핫 슬롯이 해소되지 않는 경우가 많습니다. 슬롯 자체가 다수의 노드에 이미 분배되어 있어도, 특정 슬롯에 쓰기 연산이 집중되면 그 슬롯을 소유한 노드 한 곳에서만 처리가 이뤄지기 때문입니다. 이 구조적 한계를 이해하지 못하면 수평 확장으로 문제를 해결하려다 비용만 증가하는 상황에 빠질 수 있습니다.
기존 방식의 한계
전통적인 단일 Redis 인스턴스나 센티넬(Sentinel) 구성에서는 샤딩이 없으므로 핫 슬롯 문제 자체가 존재하지 않았습니다. 클러스터 전환 시 개발팀은 대부분 키 설계를 그대로 가져오는데, 단일 인스턴스 시절에 통했던 {user}:{id}:session 형태의 키 구조가 클러스터에서는 해시 태그({}) 동작으로 인해 예상치 못한 슬롯 집중을 일으킵니다. 해시 태그는 멀티-키 연산을 위한 도구이지만, 무분별하게 사용하면 오히려 분산을 망가뜨리는 원인이 됩니다.
Redis Cluster 샤딩 메커니즘 이해
해시 슬롯 분배 원리
Redis Cluster는 데이터를 논리적 단위인 **슬롯(slot)**으로 나눕니다. 총 16,384개의 슬롯이 각 마스터 노드에 배정되며, 클라이언트가 키를 읽거나 쓸 때 Redis는 해당 키가 속하는 슬롯과 그 슬롯을 담당하는 노드로 요청을 라우팅합니다. 3개 마스터 노드 기준으로 슬롯은 대략 균등하게 나뉩니다.
슬롯 번호 계산식은 단순합니다. 키 전체에 CRC16을 적용하고 16384로 나눈 나머지가 슬롯 번호가 됩니다. 단, 키에 중괄호({…})가 포함되면 중괄호 안의 내용만을 해시합니다. 이 기능이 해시 태그이며, 여러 키를 동일 슬롯에 강제로 배치해 멀티-키 명령(MGET, MSET, 파이프라이닝)이나 루아 스크립트를 클러스터에서도 사용할 수 있게 해 줍니다.
해시 태그가 있으면 중괄호 내용만으로 슬롯이 결정되므로, {user}:1:data와 {user}:2:data는 서로 다른 키이지만 동일한 슬롯에 배치됩니다.
해시 태그의 양면성
해시 태그는 Redis Cluster에서 원자적 멀티-키 연산을 가능하게 하는 핵심 기능입니다. 예를 들어 쇼핑 카트를 구현할 때 {session:abc}:cart와 {session:abc}:metadata를 같은 슬롯에 두면 하나의 루아 스크립트로 두 키를 원자적으로 갱신할 수 있습니다. 이것은 분산 환경에서 트랜잭션을 모사하는 합리적인 접근입니다.
그러나 문제는 해시 태그의 범위가 너무 넓을 때 발생합니다. 애플리케이션 전역에 걸쳐 {global}:이나 {app}: 같은 공통 접두사를 해시 태그로 쓰면, 수백만 개의 키가 16,384개 슬롯 중 단 하나에 몰립니다. 이런 설계는 클러스터를 구성한 의미를 완전히 잃게 만듭니다.
| 해시 태그 설계 | 슬롯 수 | 분산 효과 | 주의점 |
|---|---|---|---|
| 태그 없음 | 키마다 다른 슬롯 | 최대 분산 | 멀티-키 명령 불가 |
{userId}:* |
사용자별 1개 | 적정 분산 | 사용자 수에 비례 |
{service}:* |
서비스 이름 1개 | 매우 집중 | 핫 슬롯 위험 |
{global}:* |
슬롯 1개 | 분산 없음 | 즉시 병목 발생 |
클러스터 토폴로지와 리디렉션
클라이언트가 잘못된 노드에 요청을 보내면 Redis는 -MOVED 응답으로 올바른 노드의 주소를 알려 줍니다. 이 리디렉션은 자동으로 처리되지만, 캐시되지 않은 슬롯 맵을 가진 클라이언트가 계속 잘못된 노드로 요청을 보내면 네트워크 왕복이 두 배로 늘어납니다. 그래서 Lettuce나 Jedis 같은 클라이언트 라이브러리는 슬롯-노드 매핑 테이블을 내부적으로 캐싱하고, 노드 변경이 감지될 때만 갱신합니다.
-MOVED 응답은 한 번의 리디렉션으로 끝나지만, 클러스터 토폴로지가 자주 바뀌는 환경에서는 슬롯 맵 갱신 빈도가 지연(latency)에 영향을 줍니다.
핫 슬롯 병목의 원인과 탐지
병목이 만들어지는 구조
Redis는 기본적으로 단일 스레드(I/O 처리 포함 시 멀티 스레드지만 명령 실행은 단일 스레드)로 동작합니다. 이 설계는 락 없는 원자성을 보장하는 장점이 있지만, 특정 슬롯에 연산이 집중되면 해당 슬롯을 담당하는 노드의 이벤트 루프가 포화 상태에 이릅니다. 클러스터의 다른 노드들이 유휴 상태여도 문제가 된 노드의 처리 큐는 계속 늘어나며, 결과적으로 P99 지연이 급격히 상승합니다.
핫 슬롯이 발생하는 가장 흔한 시나리오는 세 가지입니다. 첫째, 카운터·랭킹·실시간 집계처럼 초당 수만 번의 INCR·ZINCRBY 연산이 특정 키 하나에 집중되는 경우입니다. 둘째, 앞서 설명한 해시 태그의 과도한 사용으로 인해 논리적으로 관련 없는 키들이 같은 슬롯에 몰리는 경우입니다. 셋째, 배치 처리 스크립트가 순차적으로 동일 패턴의 키를 대량 생성해 일시적으로 특정 슬롯에 쓰기가 폭발하는 경우입니다.
클러스터를 수평 확장해도 핫 슬롯을 담당하는 노드는 변하지 않으며, 병목은 해소되지 않습니다.
핫 슬롯 탐지 방법
Redis 7.0부터는 LATENCY HISTORY와 SLOWLOG 외에도 CLUSTER SHARDS 명령으로 슬롯별 키 분포를 확인할 수 있습니다. 그러나 가장 직접적인 탐지 도구는 redis-cli --hotkeys 옵션과 OBJECT FREQ 명령입니다. --hotkeys는 내부적으로 maxmemory-policy가 LFU 계열로 설정된 경우에만 동작하며, 각 키의 접근 빈도를 기반으로 상위 핫 키를 출력합니다.
프로메테우스 + Grafana 스택을 사용하는 환경이라면 redis_exporter의 redis_cluster_slots_ok와 노드별 redis_commands_processed_total을 비교하는 것이 가장 실용적입니다. 특정 노드의 명령 처리량이 평균의 3배 이상이면 핫 슬롯 의심 대상으로 분류하고 해당 노드의 키 분포를 분석합니다.
탐지-분석-전략 수립의 흐름을 지키면 병목의 범위를 좁히고 불필요한 리팩터링을 피할 수 있습니다.
슬롯 키 분포 분석 스크립트
핫 슬롯을 특정한 뒤에는 해당 슬롯에 어떤 키들이 몰려 있는지 확인해야 합니다. Redis의 CLUSTER GETKEYSINSLOT 명령이 이 목적에 사용됩니다.
슬롯 번호와 키 패턴을 함께 파악하면 키 설계 변경 범위를 사전에 가늠할 수 있습니다.
# 슬롯 1234에 속한 키 샘플 100개 추출
redis-cli -c CLUSTER GETKEYSINSLOT 1234 100
# 전체 슬롯별 키 수 분포 (Python 스크립트 일부)
import redis
r = redis.RedisCluster(host='localhost', port=7000)
slot_dist = {}
for node in r.get_primaries():
for slot in node.slots:
count = node.redis_connection.execute_command(
'CLUSTER COUNTKEYSINSLOT', slot
)
slot_dist[slot] = count # 결과: {1234: 892000, 1235: 1200, ...}
hot = sorted(slot_dist.items(), key=lambda x: x[1], reverse=True)[:5]
print(hot)
# 결과: [(1234, 892000), (5678, 410000), ...]슬롯 1234에 892,000개의 키가 집중되고 인접 슬롯에는 1,200개에 불과하다면, 해시 태그 남용이나 특정 키 패턴 집중을 즉시 의심해야 합니다.
핫 슬롯 해결 전략 — 데이터 분산 설계
키 접미사 샤딩으로 부하 분산
가장 직접적인 해결책은 단일 키에 집중되는 연산을 여러 키로 분산시키는 키 분할(key splitting) 전략입니다. 예를 들어 초당 50,000번 INCR이 발생하는 page:view:count 키가 있다면, 이것을 page:view:count:0 ~ page:view:count:15처럼 16개로 나눕니다. 각 요청은 random() % 16으로 선택한 샤드에 INCR을 실행하고, 실제 집계가 필요할 때만 16개 키를 MGET으로 읽어 합산합니다.
이 방식은 카운터, 랭킹 점수 집계, 실시간 통계처럼 개별 연산이 독립적이고 최종 집계가 후처리로 가능한 경우에 잘 맞습니다. 트레이드오프는 읽기 시 합산 로직이 추가된다는 점과, 분할된 키들이 서로 다른 슬롯에 흩어지므로 원자적 연산이 불가능하다는 점입니다. 카운터나 통계처럼 소량의 오차가 허용되는 경우에는 이 트레이드오프가 충분히 수용 가능합니다.
쓰기는 분산, 읽기는 합산 — 이 패턴으로 단일 키 집중 문제를 노드 수에 비례해 분산시킬 수 있습니다.
해시 태그 설계 재검토
핫 슬롯의 가장 흔한 원인인 해시 태그 남용을 교정하려면, 먼저 해시 태그가 꼭 필요한 경우와 관례적으로 사용하는 경우를 구분해야 합니다. 해시 태그가 필수인 경우는 루아 스크립트나 WATCH/MULTI/EXEC 트랜잭션 내에서 두 개 이상의 키를 원자적으로 조작해야 할 때뿐입니다. 단순히 "같은 사용자의 데이터를 함께 조회하고 싶다"는 이유만으로 해시 태그를 쓰면 분산 효과가 반감됩니다.
해시 태그 범위를 최소화하는 원칙은 가장 좁은 단위로 묶기입니다. {user}: 대신 {user:12345}:처럼 구체적인 식별자를 태그로 쓰면, 슬롯 개수가 사용자 수만큼 다양해져 분산이 살아납니다. 실제로 사용자 ID가 1백만 개라면 해시 태그에 따라 최대 1백만 개의 서로 다른 슬롯으로 분산될 수 있습니다(16,384개 한도 내에서).
| 해시 태그 패턴 | 슬롯 다양성 | 원자성 범위 | 권장 여부 |
|---|---|---|---|
{app}:user:* |
슬롯 1개 | 전체 키 | ❌ 핫 슬롯 확정 |
{user}:* |
고정 수 (~수십) | "user" 포함 전체 | ⚠️ 위험 |
{user:12345}:* |
사용자 수 비례 | 해당 사용자만 | ✅ 권장 |
| 태그 없음 | 키마다 다름 | 단일 키만 | ✅ 멀티키 불필요 시 |
읽기 부하는 레플리카로 분산
쓰기 연산이 특정 슬롯에 집중되는 문제는 키 분할로 대응하지만, 읽기 연산이 집중되는 경우에는 **레플리카 읽기(replica reads)**가 효과적인 보완책이 됩니다. Redis Cluster에서 레플리카는 기본적으로 읽기 요청을 받지 않습니다. 클라이언트가 레플리카에 READONLY 명령을 먼저 보낸 뒤 읽기 요청을 하면 레플리카에서 직접 처리됩니다.
Lettuce 클라이언트의 경우 ReadFrom.REPLICA_PREFERRED 설정으로 이 동작을 간단하게 활성화할 수 있습니다. 단, 레플리카 읽기는 최종 일관성(eventual consistency) 만을 보장합니다. 마스터에 쓴 뒤 즉시 레플리카에서 읽으면 복제 지연(일반적으로 수 밀리초 이내)으로 인해 이전 값을 읽을 수 있습니다. 이 점은 세션 데이터, 재고 수량처럼 강한 일관성이 필요한 경우에는 레플리카 읽기를 적용하면 안 된다는 뜻이기도 합니다.
// Lettuce 레플리카 읽기 활성화 예시
RedisClusterClient client = RedisClusterClient.create("redis://localhost:7000");
ClusterClientOptions options = ClusterClientOptions.builder()
.readFrom(ReadFrom.REPLICA_PREFERRED) // 레플리카 우선, 없으면 마스터
.build();
client.setOptions(options);
StatefulRedisClusterConnection<String, String> conn = client.connect();
// 이후 read 요청은 레플리카로 분산됨
// 결과: 마스터 읽기 부하 약 50~66% 감소 (레플리카 2개 구성 시)레플리카 읽기는 설정 한 줄로 마스터 읽기 부하를 절반 이하로 줄일 수 있는 가장 간단한 핫 슬롯 완화 전략입니다.
운영 환경에서의 슬롯 리밸런싱
슬롯 이동과 마이그레이션 원리
핫 슬롯 문제를 해결하는 또 다른 방법은 슬롯 자체를 덜 바쁜 노드로 이동하는 것입니다. Redis Cluster는 CLUSTER SETSLOT과 MIGRATE 명령을 통해 온라인 상태에서 슬롯을 다른 노드로 이전할 수 있습니다. 이 과정을 **슬롯 마이그레이션(slot migration)**이라고 하며, redis-cli --cluster rebalance 명령이 이를 자동화해 줍니다.
마이그레이션 중에는 해당 슬롯이 -ASK 리디렉션 상태가 됩니다. -MOVED와 달리 -ASK는 일시적인 상태를 의미하며, 클라이언트는 ASKING 명령을 선행한 뒤 새 노드로 요청을 보내야 합니다. 이 전환 과정은 대부분의 Redis 클라이언트 라이브러리에서 투명하게 처리되지만, 마이그레이션 속도가 너무 빠르면 클라이언트 쪽에서 일시적인 지연이나 오류가 발생할 수 있습니다. 운영 환경에서는 --cluster-migration-barrier와 --cluster-node-timeout 값을 보수적으로 설정해 마이그레이션 속도를 조절하는 것이 안전합니다.
마이그레이션은 네 단계 상태 전이로 이뤄지며, 각 단계에서 클러스터는 -ASK 응답으로 일관성을 유지합니다.
무중단 리밸런싱 전략
슬롯 리밸런싱을 운영 중에 진행할 때 가장 큰 위험은 이전 중인 슬롯에 대한 요청 오류입니다. MIGRATE 명령은 기본적으로 키를 하나씩 이동하므로, 수십만 개 이상의 키를 가진 슬롯을 이동하면 수 분에서 수십 분이 소요됩니다. 이 기간 동안 해당 슬롯을 사용하는 기능에 레이턴시 스파이크가 생길 수 있습니다.
안전한 리밸런싱을 위해 권장되는 절차는 다음과 같습니다. 먼저 트래픽이 가장 적은 시간대를 선택합니다. 다음으로 redis-cli --cluster check 명령으로 클러스터 상태를 사전에 검증합니다. 그런 다음 한 번에 이동할 슬롯 수를 제한(--cluster-slots)하고, 이동 중 INFO stats의 instantaneous_ops_per_sec 지표를 모니터링해 이상 징후를 즉시 감지합니다. 마지막으로 마이그레이션 완료 후 슬롯 분포를 재확인하고 레이턴시가 정상화되었는지 검증합니다.
| 단계 | 명령 / 조치 | 주의점 |
|---|---|---|
| 사전 검증 | redis-cli --cluster check |
기존 오류 없어야 함 |
| 리밸런싱 | --cluster rebalance --use-empty-masters |
트래픽 최소 시간대 |
| 모니터링 | INFO stats, LATENCY HISTORY |
P99 기준 |
| 완료 검증 | CLUSTER INFO, CLUSTER SHARDS |
슬롯 균등 확인 |
노드 추가 없이 슬롯 재배치
클러스터에 노드를 새로 추가하지 않고도 기존 노드 간 슬롯 재배치로 핫 슬롯을 분산할 수 있습니다. 핵심은 핫 슬롯을 상대적으로 여유로운 노드로 이전하는 것입니다. 예를 들어 노드A가 슬롯 0~5460을 담당하고 있고 그중 슬롯 1234가 핫 슬롯이라면, 슬롯 1234만 노드B나 노드C로 이동시킬 수 있습니다. 이렇게 하면 비용 없이 부하를 재분산할 수 있습니다.
단, 이 접근이 효과적이려면 핫 슬롯의 부하가 노드 단위가 아닌 슬롯 단위로 격리되어야 합니다. 핫 슬롯 하나에 초당 수십만 건의 연산이 몰린다면, 그 슬롯을 어느 노드로 옮겨도 해당 노드가 새로운 병목이 됩니다. 이 경우에는 슬롯 이동보다 앞서 설명한 키 분할이나 레플리카 읽기 분산을 먼저 적용해야 합니다.
핫 슬롯 원인에 따라 전략이 달라집니다. 단일 처방이 아닌 원인 분석 우선이 핵심입니다.
성능 특성과 트레이드오프 비교
벤치마크 관점에서의 클러스터 동작
Redis Cluster의 처리량은 이론적으로 마스터 노드 수에 비례해 선형 확장됩니다. redis-benchmark 도구로 단일 인스턴스 대비 3-노드 클러스터를 비교하면, 키가 고르게 분산된 경우 약 2.8~3배의 처리량이 나옵니다. 그러나 핫 슬롯이 하나라도 존재하면 전체 처리량이 해당 노드의 한계로 제한됩니다.
실제 현업 사례에서 흔히 확인되는 수치는 다음과 같습니다. 단일 마스터 노드의 최대 처리량이 약 100,000 ops/sec (get/set 혼합) 기준일 때, 3개 마스터 구성에서 슬롯이 균등하게 분산된 경우 약 280,000~300,000 ops/sec가 나옵니다. 반면 핫 슬롯 하나가 전체 트래픽의 70%를 담당하는 상황에서는 클러스터 전체가 140,000 ops/sec 수준에서 포화됩니다. 노드를 두 배로 늘려도 핫 슬롯이 해소되지 않으면 처리량은 거의 개선되지 않습니다.
노드 수가 아닌 슬롯 분산이 실제 처리량을 결정합니다. 핫 슬롯 해소 전후 처리량 차이가 노드 추가보다 훨씬 큽니다.
대안 기술과의 비교
Redis Cluster와 유사한 분산 캐시/스토어로는 Memcached 클러스터, Apache Ignite, Hazelcast, 그리고 클라이언트 사이드 샤딩(Twemproxy, Envoy Proxy 기반) 방식이 있습니다. 각 접근법은 핫 슬롯 문제에 대해 서로 다른 특성을 보입니다.
Memcached의 클라이언트 사이드 샤딩은 서버 측에 클러스터 인식이 없으므로, 핫 노드 문제는 발생할 수 있지만 슬롯 개념 자체가 없어 재배치 유연성도 낮습니다. Twemproxy(Nutcracker)를 Redis 앞에 두는 방식은 클라이언트 코드를 단순화하지만, 프록시 레이어 자체가 병목이 될 수 있고 Redis Cluster 프로토콜과 호환되지 않습니다.
| 기술 | 핫 노드 완화 | 온라인 재배치 | 클러스터 인식 | 적합 사례 |
|---|---|---|---|---|
| Redis Cluster | 슬롯 마이그레이션 | 지원 | 네이티브 | 범용 캐시·세션 |
| Memcached | 클라이언트 재해싱 | 미지원 | 미지원 | 단순 캐시 |
| Twemproxy | 프록시 라운드로빈 | 재시작 필요 | 프록시 레이어 | 레거시 환경 |
| Hazelcast | Near-cache, 파티션 이동 | 지원 | 네이티브 | JVM 기반 앱 |
언제 Redis Cluster를 선택해야 하는가
Redis Cluster는 단일 인스턴스나 센티넬로는 처리할 수 없는 규모(메모리 100GB+, ops 수십만/초 이상)에 진입하거나, 하나의 노드 장애가 전체 서비스에 영향을 주지 않도록 하는 고가용성 요구가 있을 때 도입을 검토합니다. 그러나 클러스터는 단일 노드 대비 운영 복잡도가 크게 높아집니다. lua 스크립트가 여러 노드에 걸친 키를 사용할 수 없고, SCAN 명령이 노드별로 실행되어야 하며, 클라이언트 라이브러리가 클러스터 프로토콜을 지원해야 합니다.
데이터 크기가 수 GB 이내이고 현재 센티넬 구성이 안정적으로 동작하고 있다면, 클러스터 전환이 오히려 운영 부담을 증가시킵니다. 클러스터 도입 결정은 단순히 성능 수치만이 아니라 팀의 운영 역량, 클라이언트 라이브러리 지원 여부, 기존 키 설계의 마이그레이션 비용을 종합적으로 고려해야 합니다.
맺음말
핵심 요약
Redis Cluster는 16,384개 슬롯을 노드에 분배하는 방식으로 수평 확장을 실현하지만, 특정 슬롯에 연산이 집중되는 핫 슬롯이 발생하면 클러스터 전체가 아닌 단일 노드가 병목이 됩니다. 핫 슬롯의 주요 원인은 해시 태그의 과도한 사용과 단일 키 집중 쓰기이며, redis-cli --hotkeys와 CLUSTER COUNTKEYSINSLOT으로 탐지할 수 있습니다. 해결 전략은 원인에 따라 다르며, 읽기 집중에는 레플리카 읽기, 쓰기 집중에는 키 접미사 샤딩, 구조적 불균형에는 슬롯 리밸런싱이 적합합니다.
해시 태그는 멀티-키 원자성이 실제로 필요한 최소 범위에만 적용하고, 태그 범위를 구체적인 식별자({user:12345}:)로 좁히는 것이 슬롯 분산을 유지하는 가장 근본적인 설계 원칙입니다.
적용 판단 기준
Redis Cluster 도입 이후 특정 노드의 CPU가 지속적으로 80% 이상이고 나머지 노드는 여유가 있다면, 수평 확장 전에 반드시 슬롯 분포와 핫 키 분석을 먼저 수행해야 합니다. 노드 추가는 핫 슬롯이 해소된 이후의 확장 수단입니다. 새 시스템을 클러스터로 설계할 때는 해시 태그 정책을 사전에 문서화하고, 카운터·집계처럼 고빈도 쓰기가 예상되는 키는 처음부터 접미사 샤딩 구조로 설계하는 것이 운영 환경에서의 병목을 예방하는 효과적인 접근입니다. 슬롯 리밸런싱은 강력한 도구이지만, 키 설계 문제를 해결하지 않은 채로 슬롯만 이동하면 병목이 다른 노드로 옮겨갈 뿐이라는 점을 명심해야 합니다.