Redis從入門到放棄(3):釋出與訂閱

2023-07-28 12:00:44

1、介紹

Redis是一個快速、開源的記憶體資料庫,支援多種資料結構,如字串、雜湊、列表、集合、有序集合等。除了基本的資料儲存和檢索功能外,Redis還提供了許多高階功能,其中之一就是釋出訂閱(Pub/Sub)。

釋出訂閱是一種訊息傳遞模式,它允許訊息的釋出者(釋出者)將訊息傳送給多個訂閱者(訂閱者)而不必知道訂閱者的存在。這種模式在許多應用中都非常有用,例如實時通知、事件處理、聊天應用等。

2、如何使用釋出訂閱

2.1、訂閱頻道

要訂閱一個頻道,首先需要使用 SUBSCRIBE 命令。假設我們有一個頻道名為 notifications,下面是訂閱該頻道的範例程式碼:

[root@ds-huangshan-01 src]# ./redis-cli 
127.0.0.1:6379> SUBSCRIBE notifications
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "notifications"
3) (integer) 1      # 返回值為當前已訂閱的頻道數量

當執行以上命令後,當前使用者端就會進入訂閱狀態,它將持續等待來自 notifications 頻道的訊息。如果頻道不存在,那麼使用者端將一直阻塞,直到有訊息釋出到該頻道。

2.2、釋出訊息

要釋出一條訊息到指定的頻道,使用 PUBLISH 命令。下面是釋出一條訊息到 notifications 頻道的範例程式碼:

釋出端(釋出訊息):

[root@ds-huangshan-01 src]# ./redis-cli 
127.0.0.1:6379> publish notifications "hello world!"
(integer) 1

執行以上命令後,所有已經訂閱 notifications 頻道的使用者端都會收到訊息 "hello world!"。

"message"
"notifications"
"hello world!"

2.3、取消訂閱

如果使用者端不再需要接收特定頻道的訊息,可以使用 UNSUBSCRIBE 命令來取消訂閱。如果沒有指定頻道名,則使用者端將取消所有頻道的訂閱。

UNSUBSCRIBE notifications

2.4、模式訂閱

除了普通的頻道訂閱,Redis還支援模式訂閱(Pattern Subscriptions)。模式訂閱允許使用者端訂閱滿足特定模式的頻道。

例如,假設我們有多個頻道名以 "notifications:" 開頭,後面跟著不同的分類(例如 "notifications:news"、"notifications:sports" 等)。要訂閱所有以 "notifications:" 開頭的頻道,可以使用以下命令:

PSUBSCRIBE notifications:*

2.5、取消模式訂閱

取消模式訂閱使用 PUNSUBSCRIBE 命令,用法與取消普通頻道訂閱類似。

PUNSUBSCRIBE notifications:*

有關訂閱命令有兩點需要注意:

  1. 使用者端在執行訂閱命令之後進入了訂閱狀態,只能接收 subscribe、psubscribe、 unsubscribe、 punsubscribe 的四個命令。
  2. 新開啟的訂閱使用者端,無法收到該頻道之前的訊息,因為 Redis 不會對釋出的訊息進行持久化。

3、使用案例(虛擬碼)

訊息通知: 在一個Web應用程式中,可以使用釋出訂閱功能來向所有線上使用者傳送實時通知,比如新訊息、新訂單等。

Redis釋出者程式碼:

import redis.clients.jedis.Jedis;

public class RedisPublisher {

    public static void main(String[] args) {
        // 連線到Redis伺服器
        Jedis jedis = new Jedis("localhost");

        // 釋出訊息到頻道
        jedis.publish("notifications", "Hello, world!");

        // 關閉連線
        jedis.close();
    }
}

// Redis訂閱者程式碼

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

public class RedisSubscriber extends JedisPubSub {

    @Override
    public void onMessage(String channel, String message) {
        System.out.println("Received message: " + message + " from channel: " + channel);
        // 在這裡可以實現傳送通知給線上使用者的邏輯
    }

    public static void main(String[] args) {
        // 連線到Redis伺服器
        Jedis jedis = new Jedis("localhost");

        // 建立訂閱者範例
        RedisSubscriber subscriber = new RedisSubscriber();

        // 訂閱頻道
        jedis.subscribe(subscriber, "notifications");

        // 關閉連線
        jedis.close();
    }
}

4、Redis的釋出訂閱與ActiveMQ、RocketMQ區別

Redis的釋出訂閱與ActiveMQ、RocketMQ是不同型別的訊息傳遞系統,它們有以下區別:

  1. 訊息佇列模式 vs. 釋出訂閱模式:

    • ActiveMQ和RocketMQ是訊息佇列系統,它們遵循訊息佇列模式。訊息佇列將訊息傳送到一個或多個消費者,每個訊息只能由一個消費者處理。
    • Redis的釋出訂閱是一種釋出者-訂閱者模式,其中一個訊息可以廣播給多個訂閱者。
  2. 永續性:

    • ActiveMQ和RocketMQ通常支援訊息的永續性,可以確保即使在消費者離線的情況下,訊息不會丟失。
    • Redis的釋出訂閱預設不支援永續性。一旦訊息被傳送,如果沒有訂閱者接收,那麼訊息就會丟失;
  3. 功能特性:

    • ActiveMQ和RocketMQ提供了豐富的功能,如訊息重試、訊息順序保證、延遲訊息等。
    • Redis的釋出訂閱相對簡單,主要用於實時通知和簡單訊息的釋出與訂閱。
  4. 分散式特性:

    • ActiveMQ和RocketMQ都是為分散式環境而設計的,支援叢集和負載均衡。
    • Redis可以在分散式環境中使用,但其釋出訂閱功能相對來說較為簡單,不如ActiveMQ和RocketMQ在複雜分散式場景下靈活。

總的來說,如果需要一個功能豐富且專注於訊息佇列模式的訊息傳遞系統,可以選擇ActiveMQ或RocketMQ。而如果只需簡單的釋出訂閱功能,Redis的釋出訂閱是個不錯的選擇。