들어가며
Redis도 pub/sub을 지원합니다. 일반적으로 많이 사용되는 pub/sub인 Kafka 와는 그 특징이 조금 다른데요. 그에 대한 비교는 다음에 다루도록 하고,
이 문서를 통해 Redis pub/sub 에 대해 이야기합니다.
hands-on practice를 통해 사용 방법을 정리합니다.
Redis pub/sub
레디스는 메시지(topic)를 주고, 받는 기능을 pub/sub 기능을 제공합니다.
PUBLISH
커맨드로 메시지를 발행하고, SUBSCRIBE
커맨드로 channel
을 구독하여 메시지를 수신하는 식입니다.
웹 소켓을 통해 메시지를 전송하는 경우 추가 네트워크 통신이 필요하지만, In-Memory 기반의 Redis는 메시지를 빠르게 주고 받을 수 있는 것이 장점입니다.
- 현재 Connecting 된 클라이언트에게 간단한 메시지를 빠르게 보내야 할 때
- 메시지를 저장할 필요가 없을 때
- 100% 전송 보장을 하지 않아도 될 때
사용하는 것이 좋습니다.
주요 특징
- 채널은 메시지 저장하지 않음
- 다른 MQ들과는 달리 Channel은 Subscriber의 메시지 수신을 확인하지 않음(전송 보장 X)
- Subscriber는 다수 Channel 구독 가능
- 정규식 Pattern matching으로 다수 Channel 구독 가능
Redis Sentinel
이 상호 health check 하는 채널로 사용
Redis Sentinel 과 pub/sub
Redis Sentinel 에서 Pub/Sub을 사용합니다.
Sentinel은 Redis Pub/Sub 기능을 사용하여 다른 Sentinel과 메시지를 주고 받으며 health check를 하는데요.
__sentinel__:hello 라는 채널로 모든 Sentinel이 메시지를 주고받습니다.
만약 Sentinel이 정상 동작하지 않는다면, 통신 확인을 위해 Redis server의 __sentinel__:채널을 확인하는 것도 하나의 옵션이 될 수 있겠습니다.
커맨드
Redis pub/sub 주요 커맨드를 정리합니다.
[SUBSCRIBE](https://redis.io/commands/subscribe)
,
[SSUBSCRIBE](https://redis.io/commands/ssubscribe)
,
[SUNSUBSCRIBE](https://redis.io/commands/sunsubscribe)
,
[PSUBSCRIBE](https://redis.io/commands/psubscribe)
,
[UNSUBSCRIBE](https://redis.io/commands/unsubscribe)
,
[PUNSUBSCRIBE](https://redis.io/commands/punsubscribe)
,
[PING](https://redis.io/commands/ping)
,
[RESET](https://redis.io/commands/reset)
,
[QUIT](https://redis.io/commands/quit)
과 같은 커맨드가 있지만,
여기서는 SUBSCRIBE
, PUBLISH
, PSUBSCRIBE
, PUNSUBSCRIBE
만 정리합니다.
SUBSCRIBE
SUBSCRIBE <channel> [channel ...]
SUBSCRIBE
채널을 구독합니다. 단일 채널 뿐만 아니라 다수 채널을 구독할 수 있습니다.
이 때 주의할 점은, SUBSCRIBE
커맨드를 사용하는 subscriber 커넥션은, 구독된 채널에서 들어오는 메시지를 기다리는 동안 Blocking 됩니다. (참고)
때문에 subscriber와 관련된 커맨드 이외에 다른 Redis 명령어를 사용할 수 없습니다.
(lettuce의 경우 subscriber 커넥션에서 다른 Redis 명령어를 실행하면 예외가 발생함.)
PUBLISH
PUBLISH <channel> <message>
PUBLISH
메시지를 발행하여 채널로 전송합니다.
이때 SUBSCRIBE
커맨드와는 달리 단일 채널만 설정할 수 있습니다.
PSUBSCRIBE
PSUBSCRIBE <pattern> [pattern ...]
PSUBSCRIBE
정규식 패턴 matching 을 통해 채널을 구독합니다.
패턴 matching을 통해 채널을 구독한다는 특징을 제외하고는 기본적으로 SUBSCRIBE
커맨드와 같은 기능을 합니다.
PUNSCRIBE
PUNSCRIBE <pattern> [pattern ...]
PSUBSCRIBE
정규식 패턴 matching 을 통해 구독한 채널을 구독 해제합니다.
practice
hands-on practice를 통해 Redis pub/sub을 확인합니다.
Redis v6.2.5, 환경은 로컬의 docker container에서 구성했습니다.
PUBLISH / SUBSCRIB
SUBSCRIBE
커맨드를 사용하여 채널을 구독합니다. jude
, liverpoolfc
, cloud
, db
구독 채널의 정보가 아래와 같이 나열됩니다.
1) subscribe
: 타입 플래그, subscribe 정보임을 나타냅니다.
2) <채널 이름>
: 구독중인 채널 네이밍
3) <number>
: 현재 커넥션이 구독중인 채널의 번호. 몇 개째 구독중인지를 말합니다.
ex) “db” 채널을 구독중이며, 위의 다른 채널("jude", ”liverpoolfc”, “cloud”)를 포함해 4개째로 구독중인 채널 이라는 의미
PUBLISH jude engineer
PUBLISH <채널> <메시지>
커맨드를 사용하여 이벤트(토픽, 메시지)를 발행합니다.
이 때, 채널과 메시지를 함께 입력합니다.
jude 채널을 구독하고 있는 커넥션에서 메시지가 수신됩니다.
1) “message”
: 타입 플래그, message임을 구분합니다.
2) <채널 명>
: 어떤 채널을 통한 메시지인지 나타냅니다.
3) <메시지 내용>
: 메시지 내용을 나타냅니다.
위 사진에서 사진에서 메시지는 jude 채널을 통해 전달 받았습니다.
다른 채널을 통하면 채널 명이 구분됩니다.
이번에는 liverpoolfc 채널을 통해 메시지를 전달받았습니다.
메시지를 PUBLISH
할 때, 해당 채널이 활성화 되어 있다면(채널을 SUBSCRIBE 중인 subscriber가 하나라도 있다면),
PUBLISH
커맨드 아래에 (integer) 1
을 출력합니다.
만약 subscriber가 없는 채널에 메시지를 PUBLISH 할 때에는, PUBLISH
커맨드 아래에 (integer) 0
을 출력합니다.
해당 채널을 구독중이지 않은 subscriber들에게는 당연히 메시지가 수신되지 않습니다.
PSUBSCRIBE
Redis pub/sub은 정규식 패턴 matching 을 통해 구독하는 PSUBSCRIBE
기능을 제공합니다.
예를 들어, ch*
을 PSUBSCIBE
하여 “ch”로 시작하는 모든 채널을 구독하는 형태입니다.
ch*
을 PSUBSCIBE
합니다.
ch1
으로 메시지를 PUBLISH 했을 때, ch*
를 PSUBSCRIBE
하고 있는 subscriber가 메시지를 수신합니다.
ch2
, ch5
또한 수신합니다.
nch1
채널은 ch*
와 정규식 매칭이 되지 않기 때문에, subscriber가 메시지를 수신하지 않습니다.
커맨드 응답 또한 (integer) 0
입니다.
Redis Cluster pub/sub
레디스 클러스터에서 메시지를 PUBLISH
하면 슬레이브를 포함한 모든 노드에게 메시지를 전달합니다.
다음과 같은 상황이 모두 가능합니다. (테스트를 통해 확인)
- 마스터에서
PUBLISH
한 메시지를 슬레이브에서SUBSCRIBE
할 수 있음 - 마스터에서
PUBLISH
한 메시지를 마스터에서SUBSCRIBE
할 수 있음 - 슬레이브에서
PUBLISH
한 메시지를 마스터에서SUBSCRIBE
할 수 있음 - 슬레이브에서
PUBLISH
한 메시지를 슬레이브에서SUBSCRIBE
할 수 있음
Sharded pub/sub
Redis 7.0 이후부터 sharded pub/sub
이 new feature로 도입됐습니다.
레디스 클러스터 샤드가 슬롯에 키를 할당하는 것과 같은 알고리즘으로, 샤드 채널이 할당됩니다.
Sharded pub/sub의 기본 절차는 다음과 같습니다.
- 샤드 채널이 해시된 슬롯을 소유한 노드로 샤드 메시지를 보내야 함
- 클러스터는
PUBLISH
된 샤드 메시지가 샤드의 모든 노드로 전달되도록 함 - 클라이언트가 슬롯을 담당하는 마스터, 또는 마스터의 슬레이브에 connecting 하여 채널 구독 가능
SSUBSCRIBE
, SUNSUBSCRIBE
, SPUBLISH
와 같은 커맨드가 사용될 수 있습니다.
레디스 클러스터에서 pub/sub 사용 가능합니다.
참고: 위 테스트는 레디스 v6.2.5 에서 진행되었습니다.
결론
Redis pub/sub 에 대해 이야기했습니다.
Redis Sentinel은 상호 health check를 위한 채널로써 pub/sub 기능을 사용합니다.
hands-on 을 진행하며 pub/sub 주요 사용법에 대해 이야기했습니다.
마지막으로 Redis 7.0부터 Cluster에서의 pub/sub 변경사항에 대해 다뤘습니다.
이하는 Redis pub/sub 에 대한 개인 의견입니다.
- 애플리케이션 인스턴스간의 로컬 캐시 동기화용도로 사용하는 것이 best case로 보임.
- 높은 수준의 데이터 정확성을 요구하는 서비스의 경우 X
- 수신 보장 안함
- 캐시 갱신 이루어지지 않았을 때 노드간 데이터 정합성 X
- 캐시로만 사용하는게 좋을 것
- 데이터 증폭 효과가 있어 오용시 치명적
- 데이터 영속성은 없어서 운영자 입장에서 관리포인트는 별로 없다(채널 정도)
- PSUBSCRIBE 긍정적 +++
- 채널 네이밍 룰만 제대로 맞춰놓는다면, 주기적으로 PSUBSCRIBE <패턴> 커맨드로 채널 등록하여 사용
Reference
https://redis.io/docs/manual/pubsub/
'Redis' 카테고리의 다른 글
여전히 과반이 필요한 Redis Sentinel (1) | 2023.06.30 |
---|---|
Redis pub/sub vs. Kafka (0) | 2023.05.29 |