Sharded Pub/Sub 의 등장
From Redis 7.0, sharded Pub/Sub is introduced in which shard channels are assigned to slots by the same algorithm used to assign keys to slots. A shard message must be sent to a node that owns the slot the shard channel is hashed to. The cluster makes sure the published shard messages are forwarded to all nodes in the shard, so clients can subscribe to a shard channel by connecting to either the master responsible for the slot, or to any of its replicas. SSUBSCRIBE, SUNSUBSCRIBE and SPUBLISH are used to implement sharded Pub/Sub.
https://redis.io/docs/latest/develop/pubsub/#sharded-pubsub
레디스 7.0 버전부터 sharded Pub/Sub이라는 기능이 도입되었습니다. 기존의 Redis Pub/Sub이 레디스 클러스터 환경에서 불필요한 리소스 사용과 네트워크 부하를 초래한다는 문제가 존재하므로, 이를 해결하기 위해 레디스는 클러스터 환경에서 효율적으로 사용할 수 있는 sharded Pub/Sub 기능을 출시하였습니다.
그러면 왜 클러스터 환경에서는 Redis Pub/Sub이 문제가 될까요?
클러스터 환경에서의 Redis Pub/Sub의 문제점

일반 Redis Pub/Sub에서 메시지를 발행하면, 메시지는 모든 노드에 전파됩니다. 그래서 Subscribe하고 있는 서버는 아무 레디스 노드에 subscribe하여도 메시지를 수신할 수 있게 됩니다. 하지만, 이렇게 모든 노드에 데이터를 전파하는 것은 클러스터를 효율적으로 사용하지 못하는 구조이며, 불필요하게 리소스를 사용하고 네트워크 부하도 발생할 수 있습니다. 실제로 AWS의 ElastiCache 사용자 가이드에서도 cluster 환경에서 pub/sub을 사용하는 것은 EngineCPUUtilization이 높아지는 결과를 초래할 수 있다고 합니다.
Use cluster-mode enabled configurations – Cluster-mode enabled allows the cache to scale horizontally to achieve higher storage and throughput than a cluster-mode disabled configuration. ElastiCache serverless is only available in a cluster-mode enabled configuration.
https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/WorkingWithRedis.html
레디스를 스케일 아웃하여 CPU, 메모리, 대역폭 등을 늘리는 것이 레디스 클러스터의 목적인데, 그 목적성과 맞지 않는 것입니다.
Sharded Pub/Sub의 동작 방식
이와 달리 sharded pub/sub은 각 채널을 슬롯에 매핑합니다. 레디스 클러스터에서는 데이터를 샤딩하기 위해 16,384개의 해시 슬롯을 사용하며, 각 슬롯들은 노드가 나눠서 가져가게 됩니다. 각 키들은 해시함수를 거쳐 특정 해시 슬롯에 할당되며, 이 해시 슬롯을 담당하는 노드가 해당 키를 저장하는 구조입니다.
예를 들어, 세 개의 노드가 존재한다고 하면
- user:1000 키 -> CRC 16 해시 -> 슬롯 12539 -> Node C가 담당
- order:5678 키 -> CRC 16 해시 -> 슬롯 3921 -> Node A가 담당
이와 같이 해시 슬롯을 담당하게 됩니다.
Sharded Pub/Sub에서는 채널이 슬롯에 할당됩니다. 특정 채널을 해시화하여 슬롯을 할당받고, 해당 슬롯을 담당하는 노드에 메시지를 발행/구독처리하는 것입니다.
위와 같은 예시의 상황이라면
- orders 채널에 publish -> CRC 16 해시 -> 슬롯 7259 -> Node B가 담당
이와 같이 해시 슬롯을 담당하여 Pub/Sub을 처리합니다. Node A나 Node C가 불필요하게 관여하지 않는 것입니다.
그런데 레디스 채널을 구독하려는 Subscriber는 내가 구독할 채널이 어떤 노드에 할당되었는지 어떻게 알 수 있을까요? 일반적으로 redis-cli를 사용한다면 cluster 모드를 사용했을 때, 슬롯이 해당된 노드로 알아서 subscribe 처리를 해줍니다.

로컬 환경에서 레디스 클러스터를 구성하고 위와 같이 SSUBSCRIBE 요청을 보냈을 때, 알아서 슬롯이 해당된 노드로 리다이렉트되는 모습을 확인할 수 있습니다.
이처럼 Sharded Pub/Sub을 사용하면 굳이 모든 노드에 데이터를 전파할 필요 없이, 필요한 노드만 해당 데이터를 저장하여 조금 더 효율적으로 클러스터 환경에서 Pub/Sub 기능을 사용할 수 있습니다.
마무리
현재 회사에서 레디스 Pub/Sub을 활용하는 기능에서 네트워크 송신 트래픽을 개선한 사례가 있었습니다. 하지만, 제가 예측한 만큼 네트워크 트래픽이 개선되지 않았고 그 문제를 딥다이브 하다가 레디스 클러스터 환경에서 Pub/Sub을 사용하는 것의 문제점을 알게 되었습니다.
무엇을 개발하든 그 기술의 동작 방식을 이해하고 탐구하는 것이 중요하다는 것을 깨달은 순간입니다. node 진영에서 sharded Pub/Sub을 지원하는 라이브러리가 많지 않고 있어도 아직 레퍼런스가 적어서 조금 더 시간이 지난 후에 도입해보면 좋을 만한 기능인 것 같습니다. :)
'백엔드' 카테고리의 다른 글
| BullMQ로 중복된 이벤트 제거하기 (0) | 2025.02.18 |
|---|