電子商務網(wǎng)站服務器百度站長平臺網(wǎng)站提交
使用 Redis List 和 Pub/Sub 實現(xiàn)簡單的消息隊列
Redis 本身不是專門的消息隊列系統(tǒng),但它提供了多種數(shù)據(jù)結構(如 List、Pub/Sub、Stream)來實現(xiàn)消息隊列功能。根據(jù)不同的業(yè)務需求,可以選擇不同的方式:
在 Redis 中,可以使用 List 或 Pub/Sub 模塊實現(xiàn)簡單的消息隊列。兩者的適用場景和實現(xiàn)方式有所不同:
- List(列表):適用于任務隊列(Task Queue),支持持久化存儲,消費者可以消費歷史消息,支持 多消費者競爭消費(類似于 Kafka)。
- Pub/Sub(發(fā)布/訂閱):適用于實時推送(Event Notification),不存儲消息,消費者只能接收發(fā)布時刻的消息,適合 多消費者廣播消費(類似于 RabbitMQ Fanout)。
方式一:使用 Redis List 實現(xiàn)簡單的消息隊列
Redis 的 LPUSH
和 BRPOP
操作可以用來構建一個 基于拉取的消息隊列。
1. 生產(chǎn)者(Producer)
生產(chǎn)者將消息推送到 Redis List 的尾部:
LPUSH my_queue "message1"
LPUSH my_queue "message2"
或在 Python 中:
import redisr = redis.Redis(host='localhost', port=6379, decode_responses=True)
r.lpush('my_queue', 'message1')
r.lpush('my_queue', 'message2')
LPUSH my_queue "message"
:將新消息插入隊列的 左側(頭部)。RPUSH my_queue "message"
也可以使用,它會將消息插入隊列的 右側(尾部)。
2. 消費者(Consumer)
消費者使用 BRPOP
(阻塞)或 RPOP
(非阻塞)從隊列的 右側 彈出消息:
BRPOP my_queue 0
或在 Python 中:
while True:msg = r.brpop('my_queue', timeout=0) # 阻塞模式if msg:print("Received:", msg[1]) # msg[1] 是消息內容
BRPOP my_queue 0
:如果隊列為空,則 阻塞 等待新的消息。RPOP my_queue
:如果隊列為空,直接返回None
,不會阻塞。
3. 多消費者
多個消費者可以競爭消費消息,即每條消息只會被 其中一個 消費者消費。例如,有兩個消費者在 BRPOP
同一個隊列,Redis 只會把某個消息分配給其中一個。
4. 消息確認與持久化
由于 Redis List 只存儲消息,不支持自動重試,因此可以配合 LPUSH+RPOPLPUSH 事務 實現(xiàn)持久化:
- 先用
RPOPLPUSH my_queue processing_queue
把消息從my_queue
轉移到processing_queue
,然后再處理。 - 處理完成后,從
processing_queue
中刪除該消息。
msg = r.rpoplpush('my_queue', 'processing_queue') # 轉移到處理中隊列
if msg:process_message(msg) # 處理消息r.lrem('processing_queue', 1, msg) # 處理完成后刪除
方式二:使用 Redis Pub/Sub 實現(xiàn)消息隊列
Pub/Sub 適用于實時消息推送,消息不會存儲,適合事件廣播。
1. 生產(chǎn)者(Publisher)
發(fā)布者向某個頻道(channel)發(fā)送消息:
PUBLISH my_channel "message1"
或在 Python 中:
r.publish('my_channel', 'message1')
2. 消費者(Subscriber)
訂閱者監(jiān)聽消息:
SUBSCRIBE my_channel
或在 Python:
pubsub = r.pubsub()
pubsub.subscribe('my_channel')for message in pubsub.listen():if message['type'] == 'message':print("Received:", message['data'].decode())
3. Pub/Sub 適用場景
- 實時消息推送(如 WebSocket、聊天室)。
- 事件驅動系統(tǒng)(如日志收集、狀態(tài)變更通知)。
- 多消費者廣播消費,所有訂閱者都會收到相同的消息。
4. Pub/Sub 局限性
- 消息 不會持久化,如果訂閱者掉線,它不會收到丟失的消息。
- 不能確保 消息按順序消費。
- 無法回溯歷史消息(相比 Kafka)。
總結:Redis List vs Pub/Sub
特性 | Redis List | Redis Pub/Sub |
---|---|---|
消息存儲 | 存儲在 List,直到被消費 | 不存儲,實時傳輸 |
消費者模型 | 多消費者競爭消費(類似任務隊列) | 多消費者廣播消費(類似事件通知) |
可靠性 | 支持重試和確認機制 | 訂閱者掉線會丟失消息 |
適用場景 | 任務隊列(如延遲任務、任務分發(fā)) | 實時推送(如聊天、事件通知) |
如果需要 持久化隊列,建議使用 Redis List;如果只是 實時推送,可以用 Pub/Sub。