Message Broker
메시지 브로커는 크게 메시징 큐와 이벤트 스트림 두 가지 형태로 나뉘는데, 레디스는 일반적으로 List 자료구조를 활용한 메시징 큐(Message Queue)로 활용된다.
Messaging Queue vs Event Stream
섹션 제목: “Messaging Queue vs Event Stream”Redis는 Stream 자료구조를 활용한 이벤트 스트림(Event Stream)도 지원하고 있으며, 카프카와 유사한 기능을 갖고 있다.
| 항목 | 메시징 큐 (Message Queue) | 이벤트 스트림 (Event Stream) |
|---|---|---|
| 메시지 소비 방식 | 소비 후 큐에서 제거 | 여러 소비자가 독립적으로 구독 가능 |
| 메시지 순서 보장 | 일반적으로 순서 보장 | 파티션 내 순서 보장, 전체 순서는 비보장 |
| 처리 방식 | 작업 단위(Task) 처리 중심 | 이벤트 기록(Event Log) 중심 |
| 재처리 지원 | 기본적으로 지원되지 않음 | 오프셋 기반으로 재처리 가능 |
| 데이터 흐름 방향 | 생산자가 소비자의 큐로 직접 전송 (Push) | 생산자가 로그 저장소에 저장, 소비자가 직접 Pull |
| 데이터 영속성 | 일반적으로 단기 저장 (일정 시간 후 삭제) | 디스크 기반 장기 저장 가능 |
| 소비자 관계 | 일반적으로 일대일 관계 | 일대다(다대다) 구독 모델 지원 |
| 대표 예시 | RabbitMQ, ActiveMQ | Kafka, AWS Kinesis |
레디스를 활용한 메시지 브로커 구현
섹션 제목: “레디스를 활용한 메시지 브로커 구현”pub/sub 메시징 큐
섹션 제목: “pub/sub 메시징 큐”레디스의 Pub/Sub 기능은 다음과 같은 특징을 갖는 메시징 큐(Message Queue)로 활용된다.
- 동작 방식: 발행자(Publisher)가 특정 채널에 메시지를 보내면, 해당 채널을 구독(Subscribe)하고 있는 모든 구독자에게 메시지가 즉시 전달
- 비영속성: 메시지는 메모리에만 존재하며, 구독자가 오프라인 상태이거나 구독 중이 아닐 경우 메시지가 유실
- 전달 보장 없음: 수신 여부 확인이나 재전송 기능이 없어, 메시지는 수신자가 구독 중이 아닐 경우 유실되며
- 알림, 캐시 무효화 등 신뢰성보다 속도가 중요한 fire-and-forget 상황에 적합
- 브로드캐스트 방식: 구독 중인 모든 소비자에게 메시지를 브로드캐스트하여 전달하기 때문에, 불필요한 트래픽이 발생할 수 있음
# 소비자 (구독)SUBSCRIBE channel-name
# 생산자 (발행)PUBLISH channel-name "message content"클러스터 구조에서의 pub/sub 한계
섹션 제목: “클러스터 구조에서의 pub/sub 한계”레디스 클러스터 구조에서도 Pub/Sub 기능을 사용할 수 있지만, 권장되는 사용 방식은 아닌데, 그 이유는 다음과 같다.
- 메시지 발행 절차: 클러스터의 한 노드에서 메시지를 발행하면, 해당 메시지는 클러스터 내 모든 노드로 전파
- 클러스터 목적과의 충돌: 클러스터는 데이터를 분산 저장하고 병렬 처리 효율을 높이기 위해 사용되는데, 모든 노드에 동일 메시지를 복제하는 구조는 목적에 맞지 않음
- 부작용: 메시지 전파로 인해 각 노드가 동일 데이터를 처리하게 되어 리소스 낭비, 네트워크 부하 등의 문제가 발생함
sharded pub/sub - 클러스터 환경에서의 pub/sub 극복
섹션 제목: “sharded pub/sub - 클러스터 환경에서의 pub/sub 극복”Redis 7.0부터 도입된 Sharded Pub/Sub은 기존 Pub/Sub의 클러스터 비호환 문제를 해결하기 위해 고안된 방식이다.
- 메시지 해싱 및 라우팅: 채널명이 해시되어 특정 슬롯에 매핑되며, 해당 슬롯을 담당하는 노드에서 메시지를 처리
- 노드 간 전파 제거: 메시지가 모든 노드로 퍼지지 않고 특정 노드에서만 처리되어 불필요한 트래픽 및 부하 감소
List 메시징 큐
섹션 제목: “List 메시징 큐”레디스의 List 자료구조는 LPUSH, RPUSH, LPOP, RPOP 명령어로 양쪽 끝에서 삽입과 삭제가 가능한 자료구조로, 메시징 큐에 적합한 특성을 가지고 있다.
- 동작 방식: 생산자는
LPUSH를 이용해 작업 데이터를 리스트의 왼쪽에 추가하고, 소비자(워커)는BRPOP을 이용해 리스트의 오른쪽에서 데이터를 꺼내 처리 - 핵심 특징
- EX 기능
- 데이터를 저장하고자 하는 list가 이미 존재할 때만 데이터를 삽입할 수 있는 기능
- 이미 캐시된(자주 사용되는) 리스트에만 데이터를 삽입할 수 있어, 불필요한 데이터 삽입 방지
- 블로킹 기능
- 이벤트 큐에 데이터가 있는지 확인하는 과정에서 불필요하게 리소스가 소도되는 것을 방지하는 기능
BLPOP,BRPOP명령어는 데이터가 있으면 즉시 반환하고, 데이터가 없으면 설정된 시간 동안 대기하는 기능을 제공
- 원형 큐
- 특정 아이템을 반복 접근해야하는 구조에서 사용할 수 있는 기능
RPOPLPUSH명령어를 사용하여, 리스트의 마지막 아이템을 꺼내고 다시 첫 번째 아이템으로 삽입하는 방식으로 구현
- EX 기능
Stream
섹션 제목: “Stream”Stream 자료구조는 Kafka와 유사한 Append-only Log 형태의 자료구조로, 이벤트 스트림(Event Stream) 구현에 적합하다.
- 동작 방식: 생산자가 스트림에 메시지를 추가하면 고유 ID와 함께 로그 형태로 저장(소비되어도 삭제되지 않음)
- 핵심 특징
- 영속성: 메시지를 메모리에 영구적으로 저장 가능(AOF, RDB 등 레디스의 일반적인 영속성 옵션 사용 가능)
- 소비자 그룹 (Consumer Groups): 여러 소비자가 하나의 그룹을 형성하여 동일한 스트림을 병렬로 처리 가능
- 레디스에서 각 소비자가 어디까지 메시지를 처리했는지 자동으로 기억하고 관리
- 재처리 및 명시적 확인 (ACK): 소비자는 스트림의 특정 시점부터 메시지를 다시 읽기 가능