Redis Pub/Sub 정리

Ahn·2026년 9월 2일

Redis Pub/Sub 정리

1. Redis Pub/Sub이란?

Redis Pub/Sub(Publish/Subscribe)은 메시지를 발행하는 Publisher와 메시지를 구독하는 Subscriber를 분리하여 통신할 수 있도록 해주는 메시징 기능이다.

Publisher는 특정 Subscriber를 직접 알 필요 없이 Channel에 메시지를 발행(Publish)하고, 해당 Channel을 구독하고 있는 Subscriber들이 메시지를 전달받는다.

즉, 다음과 같은 구조이다.

Publisher
    │
    │ PUBLISH
    ▼
 Redis Channel
    │
    ├──────────────┐
    ▼              ▼
Subscriber A    Subscriber B
   │               │
   └── 메시지 수신 ──┘

Publisher와 Subscriber가 서로 직접 연결되지 않는다는 점이 핵심이다.


2. 왜 Pub/Sub이 필요한가?

일반적인 애플리케이션에서는 한 컴포넌트가 다른 컴포넌트에게 직접 메시지를 전달하는 방식이 흔하다.

예를 들어 채팅 애플리케이션에서 사용자가 메시지를 전송하면 다음과 같은 구조가 될 수 있다.

Client A
   │
   ▼
Web Server 1
   │
   ▼
Client B

그런데 서버가 여러 대로 확장되면 문제가 발생할 수 있다.

              ┌─ Web Server 1 ─ Client A
Client ───────┤
              ├─ Web Server 2 ─ Client B
              └─ Web Server 3 ─ Client C

Client A와 Client B가 서로 다른 서버에 연결되어 있다면,

Server 1에서 발생한 메시지를 Server 2에 어떻게 전달할 것인가?

이때 Redis Pub/Sub을 사용할 수 있다.

                Redis
             ┌─────────┐
             │ Channel │
             └─────────┘
              ▲   ▲   ▲
              │   │   │
              │   │   │
          Publish Subscribe
              │   │   │
              │   │   │
        ┌─────┘   │   └─────┐
        ▼         ▼         ▼
     Server 1  Server 2  Server 3

각 서버가 동일한 Channel을 구독하고 있다면 어느 서버에서 메시지를 발행하더라도 해당 Channel을 구독하는 서버들이 메시지를 받을 수 있다.


3. 핵심 개념

Redis Pub/Sub에서는 크게 세 가지 개념을 이해하면 된다.

Publisher

메시지를 발행하는 주체이다.

PUBLISH chat "Hello"

Publisher는 누가 해당 메시지를 받을지 알 필요가 없다.


Channel

메시지가 전달되는 논리적인 통로이다.

예를 들어:

chat
notification
order
payment

와 같은 Channel을 만들 수 있다.

Publisher
    │
    │ "Hello"
    ▼
  "chat"
    │
    ├── Subscriber A
    ├── Subscriber B
    └── Subscriber C

Subscriber

특정 Channel을 구독하고 메시지를 받는 주체이다.

SUBSCRIBE chat

이후 chat Channel에 메시지가 발행되면 해당 Subscriber가 메시지를 전달받는다.


4. 실제 동작 과정

Redis CLI를 사용하면 Pub/Sub을 간단하게 확인할 수 있다.

먼저 Subscriber에서 다음 명령을 실행한다.

SUBSCRIBE chat

그러면 Redis는 해당 클라이언트가 chat Channel을 구독하고 있다는 상태를 유지한다.

다른 Redis 클라이언트에서 다음 명령을 실행한다.

PUBLISH chat "Hello Redis!"

그러면 Redis가 chat을 구독하고 있는 Subscriber에게 메시지를 전달한다.

결과적으로:

Publisher

PUBLISH chat "Hello Redis!"
        │
        ▼
┌─────────────────┐
│      Redis      │
│                 │
│ Channel: chat   │
└─────────────────┘
        │
        ├─────────────► Subscriber A
        │
        ├─────────────► Subscriber B
        │
        └─────────────► Subscriber C

5. Pub/Sub의 가장 중요한 특징

5-1. 메시지를 저장하지 않는다

Redis Pub/Sub에서 가장 중요한 특징 중 하나이다.

Publisher가 메시지를 발행했을 때 그 순간 Channel을 구독하고 있는 Subscriber에게 메시지를 전달할 뿐, 메시지를 저장하지 않는다.

예를 들어:

10:00:00
Subscriber A 연결

10:00:01
Publisher → "Hello"

10:00:02
Subscriber A 연결 종료

10:00:03
Publisher → "World"

10:00:04
Subscriber A 다시 연결

Subscriber A가 10:00:03에 발행된 "World" 메시지를 받을 수 있을까?

받을 수 없다.

왜냐하면 Pub/Sub은 메시지를 저장하지 않기 때문이다.

Publisher
    │
    │ "World"
    ▼
 Redis
    │
    └── 현재 구독 중인 Subscriber에게만 전달

Subscriber가 연결되어 있지 않았다면 메시지는 사라진다.


6. 따라서 Pub/Sub은 어떤 상황에 적합한가?

Pub/Sub은 메시지의 유실을 어느 정도 허용할 수 있고, 실시간 전달이 중요한 상황에 적합하다.

대표적으로:

  • 실시간 채팅
  • 실시간 알림
  • 실시간 상태 변경
  • WebSocket 서버 간 메시지 전달
  • 게임의 실시간 이벤트
  • 간단한 이벤트 브로드캐스팅

등에 사용할 수 있다.

예를 들어 채팅 서버에서는:

Client A
   │
   │ 메시지 전송
   ▼
Server 1
   │
   │ PUBLISH
   ▼
Redis
   │
   │
   ├────────► Server 1
   ├────────► Server 2
   └────────► Server 3
                    │
                    ▼
                 Client B

여러 서버가 같은 Channel을 구독하고 있으면 서버 간 메시지 전달에 사용할 수 있다.


7. Pub/Sub의 Broadcast 특성

Redis Pub/Sub은 기본적으로 Broadcast 방식으로 동작한다.

예를 들어:

Channel: chat

Subscriber A
Subscriber B
Subscriber C

가 모두 chat을 구독하고 있을 때,

PUBLISH chat "Hello"

를 실행하면 A, B, C 모두 메시지를 받는다.

                 "Hello"
                    │
                    ▼
                  Redis
             ┌──────┼──────┐
             ▼      ▼      ▼
             A      B      C

즉,

"이 메시지를 한 명에게 전달한다"

가 아니라

"이 Channel을 구독하고 있는 모든 Subscriber에게 전달한다"

라는 개념이다.


8. Queue와 Pub/Sub의 차이

Pub/Sub을 이해할 때 Message Queue와 비교하면 훨씬 쉽다.

Pub/Sub

             Message
                │
                ▼
              Redis
          ┌─────┼─────┐
          ▼     ▼     ▼
          A     B     C

모든 Subscriber가 메시지를 받는다.


Queue

Queue에서는 일반적으로 하나의 메시지를 하나의 Consumer가 처리하는 형태를 생각할 수 있다.

             Message
                │
                ▼
              Queue
                │
          ┌─────┼─────┐
          ▼     ▼     ▼
        Worker Worker Worker

메시지를 분산 처리하는 목적에 적합하다.

따라서 둘의 목적이 다르다.

특징Pub/SubQueue
전달 방식BroadcastConsumer에게 분배
메시지 저장X시스템에 따라 O
늦게 접속한 Consumer과거 메시지 수신 불가저장되어 있다면 가능
실시간성높음높거나 중간
메시지 유실가능구현에 따라 방지 가능
대표 사용 사례채팅, 실시간 알림작업 처리, 비동기 작업

9. Redis Pub/Sub과 Redis Stream의 차이

Redis에서 메시징을 구현할 때는 Pub/Sub뿐만 아니라 Redis Streams도 사용할 수 있다.

가장 큰 차이는 메시지를 저장하느냐이다.

Pub/Sub

Publisher
    │
    ▼
 Redis
    │
    ▼
Subscriber

메시지 전달 후 저장하지 않음

Redis Streams

Publisher
    │
    ▼
 Redis Stream
    │
    ├── Consumer A
    ├── Consumer B
    └── Consumer C

메시지를 Stream에 저장

따라서 다음과 같이 생각하면 쉽다.

Pub/Sub = 실시간 방송

Stream = 기록이 남는 메시지 스트림

메시지 유실이 허용되지 않거나 나중에 다시 처리해야 한다면 Redis Streams 같은 영속적인 메시징 방식을 고려하는 것이 좋다.


10. Redis Pub/Sub의 장점

10-1. 구현이 간단하다

Redis의 기본적인 Pub/Sub 명령어만으로 사용할 수 있다.

SUBSCRIBE chat
PUBLISH chat "Hello"

구조가 매우 단순하다.


10-2. 빠른 메시지 전달

Redis는 메모리 기반 데이터 저장소이기 때문에 메시지를 매우 빠르게 전달할 수 있다.

따라서 실시간성이 중요한 시스템에 적합하다.


10-3. Publisher와 Subscriber의 결합도를 낮출 수 있다

Publisher가 Subscriber의 위치나 개수를 알 필요가 없다.

Publisher
    │
    ▼
 Redis Channel
    │
    ├── Subscriber A
    ├── Subscriber B
    └── Subscriber C

Publisher는 단순히 Channel에 메시지를 발행하면 된다.


10-4. 서버가 여러 대인 환경에서 활용할 수 있다

WebSocket 서버가 여러 대 존재할 때 Redis를 중간 메시지 브로커처럼 활용할 수 있다.

                 Redis
              chat channel
             ▲     ▲     ▲
             │     │     │
          Server1 Server2 Server3
             │       │      │
           Client  Client  Client

이런 구조를 통해 서버 간 이벤트 전달을 구현할 수 있다.


11. Redis Pub/Sub의 단점

11-1. 메시지 유실 가능성

가장 중요한 단점이다.

Subscriber가 연결되어 있지 않은 순간에 메시지가 발행되면 메시지를 받을 수 없다.

Publisher
    │
    ▼
 Redis
    │
    X
Subscriber 없음

→ 메시지 유실

따라서 절대 유실되면 안 되는 메시지에는 적합하지 않을 수 있다.


11-2. 메시지 재처리가 어렵다

Pub/Sub은 메시지를 저장하지 않기 때문에,

"어제 발생했던 메시지를 다시 처리해줘"

같은 요구사항을 구현하기 어렵다.


11-3. Consumer의 처리 상태를 관리하지 않는다

Redis Pub/Sub 자체는 다음과 같은 것을 관리하지 않는다.

  • 누가 메시지를 받았는지
  • 누가 처리했는지
  • 처리에 성공했는지
  • 실패했는지
  • 다시 처리해야 하는지

즉, 단순한 메시지 전달 기능에 가깝다.


12. Spring에서 Redis Pub/Sub 사용하기

Spring Boot에서는 Redis를 이용해서 Pub/Sub 구조를 구현할 수 있다.

일반적인 구조는 다음과 같다.

┌──────────────────────┐
│      Publisher       │
│                      │
│ RedisTemplate        │
└──────────┬───────────┘
           │
           │ publish
           ▼
┌──────────────────────┐
│        Redis         │
│                      │
│      Channel         │
└──────────┬───────────┘
           │
           │ subscribe
           ▼
┌──────────────────────┐
│      Subscriber      │
│                      │
│ MessageListener      │
└──────────────────────┘

13. Publisher 구현

Spring에서는 RedisTemplate을 이용해서 메시지를 발행할 수 있다.

예를 들어:

@Service
@RequiredArgsConstructor
public class RedisPublisher {

    private final RedisTemplate<String, Object> redisTemplate;

    public void publish(String channel, Object message) {
        redisTemplate.convertAndSend(channel, message);
    }
}

사용할 때는:

redisPublisher.publish(
    "chat",
    new ChatMessage("hello")
);

와 같이 사용할 수 있다.

내부적으로는 Redis의 PUBLISH와 비슷한 역할을 한다.


14. Subscriber 구현

Subscriber는 Redis의 Channel을 구독하고 메시지가 들어왔을 때 처리한다.

Spring에서는 MessageListener 등을 사용할 수 있다.

@Component
public class RedisSubscriber implements MessageListener {

    @Override
    public void onMessage(Message message, byte[] pattern) {
        String body = new String(message.getBody());

        System.out.println("받은 메시지: " + body);
    }
}

그리고 해당 Listener가 특정 Channel을 구독하도록 설정한다.


15. RedisMessageListenerContainer

Spring에서는 RedisMessageListenerContainer를 이용해서 Redis Pub/Sub Listener를 관리할 수 있다.

개념적으로 다음과 같은 구조이다.

Redis
  │
  │ Message
  ▼
RedisMessageListenerContainer
  │
  ▼
MessageListener
  │
  ▼
Business Logic

예를 들어:

@Bean
public RedisMessageListenerContainer redisMessageListener(
        RedisConnectionFactory connectionFactory,
        MessageListenerAdapter listenerAdapter,
        ChannelTopic topic
) {
    RedisMessageListenerContainer container =
            new RedisMessageListenerContainer();

    container.setConnectionFactory(connectionFactory);

    container.addMessageListener(listenerAdapter, topic);

    return container;
}

이런 식으로 Redis Channel과 Listener를 연결할 수 있다.


16. 채팅 서버에서의 활용

Redis Pub/Sub의 대표적인 사용 사례가 WebSocket 기반 채팅 시스템이다.

예를 들어 서버가 3대 있다고 가정한다.

                    Redis
                  chat:room:1
                ▲     ▲     ▲
                │     │     │
             Server1 Server2 Server3
                │       │       │
             User A   User B   User C

User A가 Server 1에 연결되어 있고,

User B가 Server 2에 연결되어 있다고 하자.

User A가 메시지를 전송하면:

User A
  │
  ▼
Server 1
  │
  │ PUBLISH
  ▼
Redis
  │
  │ chat:room:1
  ▼
Server 2
  │
  ▼
User B

이렇게 다른 서버에 연결된 User B에게도 메시지를 전달할 수 있다.


17. Channel 설계

Channel을 어떻게 설계할지도 중요하다.

예를 들어 채팅방마다 Channel을 만든다면:

chat:room:1
chat:room:2
chat:room:3

와 같이 사용할 수 있다.

특정 채팅방의 메시지는 해당 방의 Channel에 발행한다.

User
 │
 ▼
chat:room:1
 │
 ├── Server 1
 └── Server 2

이렇게 하면 room:1을 구독한 서버들만 메시지를 받게 된다.


18. Pattern Subscribe

Redis Pub/Sub에서는 특정 Channel뿐만 아니라 패턴을 이용해서 구독할 수도 있다.

예:

PSUBSCRIBE chat:room:*

그러면 다음과 같은 Channel을 모두 받을 수 있다.

chat:room:1
chat:room:2
chat:room:3

즉,

chat:room:*

라는 패턴으로 여러 Channel을 한 번에 구독할 수 있다.

다만 Channel이 매우 많아지고 메시지량이 많아지는 환경에서는 패턴 구독에 따른 부하도 고려해야 한다.


19. Pub/Sub을 사용할 때 고려해야 할 것

Redis Pub/Sub은 단순하고 빠르지만 다음 질문을 먼저 생각해야 한다.

① 메시지가 유실되어도 되는가?

YES → Pub/Sub 고려
NO  → Stream / Message Queue 등 고려

② 과거 메시지를 다시 처리해야 하는가?

YES → Pub/Sub과 맞지 않음
NO  → Pub/Sub 사용 가능

③ 메시지 처리 성공 여부를 추적해야 하는가?

YES → Pub/Sub만으로는 부족할 수 있음

④ 단순히 실시간으로 전달하면 되는가?

YES → Pub/Sub에 적합

20. Pub/Sub을 선택하기 위한 기준

정리하면 다음과 같다.

                메시지 전달 필요
                       │
                       ▼
              메시지 저장이 필요한가?
                 /             \
               YES              NO
                │                │
                ▼                ▼
          Redis Stream       Redis Pub/Sub
                │
                ▼
       재처리 / 소비 상태 관리

물론 실제 시스템에서는 Kafka, RabbitMQ, SQS 등의 메시징 시스템도 요구사항에 따라 선택할 수 있다.


21. Redis Pub/Sub의 핵심 요약

Redis Pub/Sub은 Publisher와 Subscriber가 Channel을 통해 메시지를 주고받는 실시간 메시징 기능이다.

핵심 특징은 다음과 같다.

  1. Publisher는 Channel에 메시지를 발행한다.
  2. Subscriber는 Channel을 구독한다.
  3. Channel을 구독 중인 Subscriber가 메시지를 전달받는다.
  4. 메시지는 기본적으로 저장되지 않는다.
  5. Subscriber가 연결되어 있지 않으면 메시지를 놓칠 수 있다.
  6. Broadcast 방식이므로 같은 Channel을 구독한 Subscriber들에게 메시지가 전달된다.
  7. 빠르고 구조가 단순하다.
  8. 실시간 채팅, 알림, WebSocket 서버 간 통신 등에 적합하다.
  9. 메시지 유실 방지, 재처리, 처리 상태 관리가 필요하다면 Pub/Sub만으로는 부족할 수 있다.
  10. 이런 경우 Redis Streams나 Kafka, RabbitMQ 등의 다른 메시징 시스템을 고려할 수 있다.

22. 내가 이해한 Redis Pub/Sub

Redis Pub/Sub을 처음 공부하면서 가장 중요하게 이해해야 하는 부분은 Redis를 단순한 캐시 저장소가 아니라 서버 간 메시지를 전달해주는 중간 매개체로 사용할 수 있다는 것이다.

특히 서버가 여러 대인 환경에서는 각 서버가 독립적으로 동작하기 때문에 서버 간 실시간 이벤트 전달이 필요하다.

이때 Redis Pub/Sub을 사용하면 다음과 같은 구조를 만들 수 있다.

                 ┌─────────────┐
                 │    Redis    │
                 │    Pub/Sub  │
                 └──────┬──────┘
                        │
        ┌───────────────┼───────────────┐
        │               │               │
        ▼               ▼               ▼
    Server 1        Server 2        Server 3
        │               │               │
        ▼               ▼               ▼
     Client A        Client B        Client C

각 서버는 Redis Channel을 구독하고 있다가 메시지가 발생하면 해당 메시지를 자신의 연결된 클라이언트들에게 전달한다.

다만 Redis Pub/Sub은 메시지 브로커의 기능을 모두 제공하는 것이 아니라 "실시간 메시지 전달"에 초점을 맞춘 기능이라는 점을 기억해야 한다.

특히 메시지를 저장하지 않기 때문에,

"메시지를 반드시 전달해야 하는가?"

라는 질문이 Redis Pub/Sub을 사용할지 결정하는 중요한 기준이 된다.


23. 한 줄 정리

Redis Pub/Sub은 Redis Channel을 중심으로 Publisher가 발행한 메시지를 해당 Channel의 Subscriber들에게 실시간으로 Broadcast하는 메시징 방식이며, 메시지를 저장하지 않기 때문에 빠르고 단순하지만 메시지 유실과 재처리가 필요한 시스템에는 적합하지 않다.

profile
dophamine

0개의 댓글