
Hash Slot으로 데이터가 나뉘는 방식
이전 글에서는 Redis Cluster가 왜 필요한지 정리했다.
단일 Redis는 단순하고 빠르지만, 데이터가 많아지거나 트래픽이 늘어나거나 장애 대응이 필요해지면 한계가 생길 수 있다.
Redis Cluster는 이런 문제를 해결하기 위해 여러 Redis 노드에 데이터를 나눠 저장한다.
그럼 여기서 궁금해진다.
Redis Cluster는 데이터를 어떤 기준으로 나눌까?
어떤 key가 어떤 Redis 노드에 저장되는 걸까?
클라이언트는 어느 Redis로 요청을 보내야 할까?
이 질문의 핵심에 있는 개념이 바로 Hash Slot이다.
Redis Cluster는 16,384개의 Hash Slot을 사용한다
Redis Cluster는 전체 key 공간을 16,384개의 Hash Slot으로 나눈다.
0 ~ 16383
그리고 각 Master 노드가 이 slot을 나눠 가진다.
예를 들어 Master 노드가 3개라면 대략 이런 식으로 slot을 나눌 수 있다.
Master A: 0 ~ 5460
Master B: 5461 ~ 10922
Master C: 10923 ~ 16383
이 상태에서 key가 들어오면 Redis는 key를 해시해서 slot 번호를 계산한다.
예를 들어 이런 key가 있다고 해보자.
SET user:1 "jian"
Redis Cluster는 user:1이라는 key를 기준으로 slot을 계산한다.
user:1 -> hash 계산 -> slot 3000
slot 3000번을 Master A가 담당하고 있다면, 이 key는 Master A에 저장된다.
user:1 -> slot 3000 -> Master A
다른 key는 다른 slot이 나올 수 있다.
order:10 -> slot 8000 -> Master B
product:5 -> slot 13000 -> Master C
즉 Redis Cluster는 key를 보고 slot을 계산하고, 그 slot을 담당하는 Master 노드에 데이터를 저장한다.
서버 개수로 바로 나누는 게 아니다
처음에는 Redis Cluster가 서버 개수만큼 데이터를 나누는 것처럼 느껴질 수 있다.
예를 들어 Redis가 3대면 데이터를 3등분하는 구조처럼 보인다.
하지만 정확히는 Redis 서버가 데이터를 직접 3등분하는 게 아니라, 16,384개의 slot을 Master들이 나눠 가지는 구조다.
이 차이가 중요하다.
잘못 이해한 방식:
key -> 서버 3대 중 하나
실제 방식:
key -> hash slot 계산 -> 해당 slot을 가진 Master
이렇게 slot을 중간에 두는 이유는 나중에 노드를 추가하거나 제거할 때 유리하기 때문이다.
만약 서버 기준으로만 데이터를 나누면 서버가 추가되거나 빠질 때 많은 key를 다시 재배치해야 한다.
하지만 Redis Cluster는 slot 단위로 이동할 수 있다.
예를 들어 Master가 3대에서 4대로 늘어나면, 기존 Master들이 가지고 있던 slot 일부를 새로운 Master로 옮기면 된다.
Before:
Master A: 0 ~ 5460
Master B: 5461 ~ 10922
Master C: 10923 ~ 16383
After:
Master A: 일부 slot 유지
Master B: 일부 slot 유지
Master C: 일부 slot 유지
Master D: 기존 노드에서 일부 slot 이동
즉 Redis Cluster에서 데이터 분산의 기준은 서버가 아니라 slot이다.
클라이언트는 어떻게 올바른 노드를 찾을까?
Redis Cluster를 사용하면 클라이언트가 어느 노드에 요청을 보내야 할지 궁금해진다.
예를 들어 user:1이 Master A에 있고, order:10이 Master B에 있다면 애플리케이션은 매번 어느 Redis에 요청해야 하는지 알고 있어야 할까?
결론부터 말하면, Redis Cluster를 지원하는 클라이언트 라이브러리를 사용하면 대부분 자동으로 처리된다.
클라이언트는 클러스터의 slot 정보를 가져와서 어떤 key가 어느 노드로 가야 하는지 판단한다.
Go에서는 예를 들어 go-redis의 ClusterClient를 사용할 수 있다.
rdb := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{
"redis-1:6379",
"redis-2:6379",
"redis-3:6379",
},
})
이렇게 클러스터 노드 주소를 넘기면 클라이언트가 내부적으로 slot 정보를 가져오고, key에 맞는 노드로 요청을 보낸다.
그래서 Redis Cluster를 사용할 때는 반드시 Cluster를 제대로 지원하는 클라이언트 라이브러리를 사용하는 것이 중요하다.
MOVED 응답은 무엇일까?
만약 클라이언트가 잘못된 노드로 요청을 보내면 어떻게 될까?
예를 들어 user:1이라는 key가 slot 3000에 있고, 이 slot은 Master A가 담당하고 있다고 해보자.
그런데 클라이언트가 Master B로 요청을 보냈다면 Master B는 이렇게 응답할 수 있다.
MOVED 3000 192.168.0.10:6379
이 뜻은 간단하다.
slot 3000은 내가 가지고 있지 않다.
192.168.0.10:6379 노드가 가지고 있으니 그쪽으로 다시 요청해라.
Redis Cluster를 지원하는 클라이언트는 이 MOVED 응답을 보고 slot 정보를 갱신한다.
그 다음부터는 같은 slot에 해당하는 요청을 올바른 노드로 보낸다.
즉 MOVED는 Redis Cluster에서 “이 key는 다른 노드에 있다”고 알려주는 리다이렉션 응답이라고 보면 된다.
멀티 키 명령어에서 문제가 생길 수 있다
Redis Cluster를 사용할 때 조심해야 하는 부분이 있다.
바로 여러 key를 한 번에 다루는 명령어다.
예를 들어 이런 명령어가 있다고 해보자.
MGET user:1 user:2
단일 Redis에서는 별문제 없이 동작한다.
하지만 Redis Cluster에서는 user:1과 user:2가 서로 다른 slot에 있을 수 있다.
user:1 -> slot 3000 -> Master A
user:2 -> slot 9000 -> Master B
이 경우 Redis Cluster는 이 명령을 한 번에 처리할 수 없다.
왜냐하면 하나의 명령이 서로 다른 Master에 있는 key를 동시에 다루게 되기 때문이다.
이때 발생할 수 있는 에러가 바로 CROSSSLOT이다.
CROSSSLOT Keys in request don't hash to the same slot
뜻은 이렇다.
요청에 포함된 key들이 같은 slot에 있지 않다.
즉 Redis Cluster에서는 멀티 키 명령어를 사용할 때 key들이 같은 slot에 있어야 한다.
Hash Tag로 같은 slot에 묶기
그럼 여러 key를 반드시 같이 다뤄야 하는 경우에는 어떻게 해야 할까?
이때 사용할 수 있는 것이 Hash Tag다.
Redis Cluster는 key 안에 {}가 있으면, 그 안의 값만 기준으로 slot을 계산한다.
예를 들어 이런 key가 있다고 해보자.
user:{1}:profile
user:{1}:settings
Redis Cluster는 전체 key가 아니라 {1} 부분을 기준으로 slot을 계산한다.
그래서 두 key는 같은 slot에 들어간다.
user:{1}:profile -> {1} 기준으로 slot 계산
user:{1}:settings -> {1} 기준으로 slot 계산
이렇게 하면 같은 사용자에 대한 여러 데이터를 같은 slot에 묶을 수 있다.
예를 들어 사용자 프로필과 사용자 설정을 한 번에 조회해야 한다면 이런 식의 key 설계가 도움이 될 수 있다.
다만 Hash Tag를 무조건 많이 쓰는 것이 좋은 것은 아니다.
모든 key를 같은 Hash Tag로 묶어버리면 특정 slot에 데이터가 몰릴 수 있다.
그러면 Redis Cluster를 사용하는 이유인 데이터 분산 효과가 떨어진다.
그래서 Hash Tag는 꼭 같이 다뤄야 하는 key에만 신중하게 사용하는 것이 좋다.
Redis Cluster에서는 key 설계가 중요하다
단일 Redis를 사용할 때는 key 이름을 어느 정도 자유롭게 정해도 큰 문제가 없는 경우가 많다.
하지만 Redis Cluster에서는 key 설계가 더 중요해진다.
특히 다음과 같은 경우에는 미리 고민해야 한다.
- 여러 key를 한 번에 조회해야 하는가?
- MGET, MSET 같은 멀티 키 명령어를 자주 사용하는가?
- Lua Script에서 여러 key를 다루는가?
- 트랜잭션으로 여러 key를 묶어 처리하는가?
- 특정 사용자 단위로 데이터를 함께 다뤄야 하는가?
Redis Cluster는 데이터를 나눠 저장하는 구조이기 때문에, 여러 key가 서로 다른 노드에 흩어질 수 있다.
그래서 “이 key들이 같이 조회되어야 하는가?”를 기준으로 key 설계를 해야 한다.
마무리
Redis Cluster에서 데이터를 나누는 핵심은 Hash Slot이다.
Redis Cluster는 전체 key 공간을 16,384개의 slot으로 나누고, 각 Master 노드가 이 slot을 나눠 가진다.
key가 들어오면 Redis는 key를 해시해서 slot 번호를 계산하고, 그 slot을 담당하는 Master에 데이터를 저장한다.
이 구조 덕분에 Redis는 여러 노드에 데이터를 분산 저장할 수 있다.
하지만 데이터가 나뉘는 만큼 멀티 키 명령어에는 제약이 생긴다.
여러 key를 한 번에 다뤄야 한다면 key들이 같은 slot에 있어야 하고, 이때 Hash Tag를 사용할 수 있다.
결국 Redis Cluster를 잘 쓰려면 단순히 클러스터를 구성하는 것뿐만 아니라, key 설계까지 같이 봐야 한다.
다음 글에서는 Redis Cluster의 Master와 Replica 구조, 그리고 서버 3대에서 Redis Cluster를 어떻게 구성할 수 있는지 정리해보려고 한다.
'Infra' 카테고리의 다른 글
| Redis Cluster 정리, Predixy 역할과 필요한 경우 이해하기 (4) (0) | 2026.05.02 |
|---|---|
| Redis Cluster 정리, Master Replica 구조와 장애 복구 이해하기 (3) (0) | 2026.05.02 |
| Redis Cluster 정리, 단일 Redis의 한계와 필요성 이해하기 (1) (0) | 2026.05.01 |
| Redis 캐시 TTL을 잘못 잡으면 생길 수 있는 Cache Stampede 문제 (0) | 2026.04.30 |
| n8n Webhook 테스트, curl로 요청 보내고 응답 받아보기 (0) | 2026.04.27 |