Redis의 pub/sub에서 모든 데이터는 한 번 채널 전체에 전파된 뒤 삭제되는 일회성의 특징을 가지며, 메시지가 잘 전달됐는지 등의 정보는 보장하지 않는다.
그래서 완벽하게 메시지가 전달되어야 하는 상황에는 적합하지 않을 수 있지만 fire-and-forgot 패턴이 필요한 간단한 알림 서비스에서는 유용하게 사용될 수 있다.
fire-and-forgot 패턴
Redis에서 pub/sub는 매우 가볍기 때문에 최소한의 메시지 전달 기능만 제공한다.
발행자는 메시지를 채널로 보낼 수 있을 뿐, 어떤 구독자가 메시지를 읽어가는지, 정상적으로 모든 구독자에게 메시지가 전달됐는지 확인할 수 없다. 구독자 또한 메시지를 받을 수 있지만 해당 메시지가 언제 어떤 발행자에 의해 생성됐는지 등의 메타데이터는 알 수 없다.
한 번 전파된 데이터는 Redis에 저장되지 않으며 위 그림과 같이 단순한 메시지의 통로 역할만 한다.
만약 특정 구독자에 장애가 생겨 메시지를 받지 못했다 하더라도 그 사실을 알 수 없기 때문에 정합성이 중요한 데이터를 전달하기에는 적합하지 않을 수 있다.
이 경우 애플리케이션 레벨에서 메시지의 송수신과 관련한 로직을 추가해야 할 수 있다.
클러스터 구조에서의 pub/sub
클러스터는 Redis가 자체적으로 제공하는 데이터 분산 형태의 구조이다.
Redis 클러스터에서 pub/sub을 사용할 때, 메시지를 발행하면 해당 메시지는 클러스터에 속한 모든 노드에 자동으로 전달된다. 따라서 아무 노드에 연결해 SUBSCRIBE 커맨드를 사용하면 데이터를 수신할 수 있다.
위 그림은 클러스터 구조에서 메시지가 전파되는 모습을 보여준다.
하나의 노드에 메시지를 발행하면 메시지는 모든 노드에 전파된다. 이 방법은 굉장히 간단하고 명료하지만, 사실 클러스터의 주요 목적을 고려한다면 비효율적인 방식으로 여겨질 수 있다.
클러스터는 주로 대규모 서비스에서 데이터를 분석하고 저장하고 처리하기 위해 도입됐으며, 그렇기 때문에 Redis 클러스터 내에서 pub/sub을 사용할 때 메시지가 모든 Redis 노드에 복제되는 방식은 클러스터 환경의 핵심 목표와는 부합하지 않으며, 이로 인해 불필요한 리소스 사용과 네트워크 부하가 발생할 수 있다.
sharded pub/sub
위의 비효율을 해결하기 위해 Redis 7.0에서는 sharded pub/sub 기능이 도입되었다.
sharded pub/sub 환경에서 각 채널을 슬롯에 매핑된다. 클러스터에서 키가 슬롯에 할당되는 것과 동일한 방식으로 채널이 할당되며, 같은 슬롯을 가지고 있는 노드 간에만 pub/sub 메시지를 전파한다.
sharded pub/sub을 이용한다면 클러스터 구조에서 pub/sub되는 메시지는 모든 노드로 전파되지 않기 때문에 불필요한 복제를 줄여 자원을 절약할 수 있다는 장점이 있다.
메시징 미들웨어와 Redis의 Pub/Sub 차이점
•
보통 kafaka, RabbitMQ, ActiveMQ 같은 메시징 미들웨어의 장점은 낮은 결합도로 직접 서로 의존치 않고 미들웨어에 의존한다.
•
두 번째는 탄력성으로 느슨한 연결로 인해 장애가 생겨도 영향이 최소화 된다.
•
세 번째는 통신을 비동기 처리해서 API 호출을 제거하여 처리 시간을 감소한다.
반면 Redis의 Pub/Sub은 메시지가 큐에 저장되지 않고, kafka의 컨슈머 그룹 같은 분산 처리 개념이 없다. 또한 메시지 발행 시 push 방식으로 구독자들에게 전송하고, 구독자가 늘어날 수록 성능이 저하된다.
보통 언제 사용하냐면 실시간으로 빠르게 전송해야 하는 메시지나, 메시지 유실을 감수할 수 있는 케이스, 최대 1회 전송 패턴이 적합하고, 구독자들이 다양한 채널을 유동적으로 바꿔서 한시적으로 구독하는 경우에 사용된다.