2011-05-31 44 views
36

我一直在尋找使用Redis Pub/Sub作爲RabbitMQ的替代品。Redis Pub/Sub與可靠性

從我的理解來看,Redis的pub/sub持有與每個訂戶的連接,如果連接終止,所有未來的消息都將丟失並丟棄。

一個可能的解決方案是使用列表(並阻止等待)將所有消息和pub/sub存儲爲通知機制。我認爲這會讓我走到最後,但我仍然對失敗案例有所擔憂。

  1. 當用戶死亡並重新聯機時會發生什麼情況,應該如何處理所有未決消息?
  2. 當系統出現格式錯誤的信息時,您如何處理這些異常? DeadLetter隊列?
  3. 是否有執行重試策略的標準做法?
+0

......我想送位置更新給客戶....而一旦斷開,我不知道如何客戶端和服務器之間的數據同步...你解決問題?如果是的話,怎麼樣? – 2016-05-14 08:15:18

+0

您可以在http://redis.io/commands/rpoplpush檢查一個可靠的隊列Redis的模式 – hgf 2014-10-23 01:21:02

回答

28

當用戶(消費者)死亡後,您的列表將繼續增長,直到客戶端返回。一旦達到特定的限制,你的製作人可以調整列表(從任一側),但這是你需要在應用程序級別處理的事情。如果您在每封郵件中包含時間戳,則假設您在郵件使用年限內擁有要執行的應用程序邏輯,那麼您的客戶可以根據郵件的年齡進行操作。

我不確定一個格式錯誤的消息如何進入系統,因爲與Redis的連接通常是TCP完整性保證。但是,如果發生這種情況,可能是由於生產者層的消息編碼存在錯誤,您可以通過保持每個接收消費者異常消息的生產者隊列來提供處理錯誤的一般機制。

重試策略將取決於您的應用程序需求。如果您需要100%確保已收到並處理消息,則應考慮使用Redis事務(MULTI/EXEC)來包裝消費者完成的工作,以確保客戶端不會除去消息,除非它已經完成了它的工作。如果您需要明確的確認,那麼您可以在專用於生產者進程的隊列上使用明確的ACK消息。

不知道更多關於您的應用程序需求,很難知道如何明智地選擇。通常,如果您的消息需要完整的ACID保護,那麼您可能還需要使用redis事務。如果您的消息只在及時發送時纔有意義,則可能不需要交易。這聽起來好像你不能容忍丟棄的消息,所以你使用列表的方法是好的。如果您需要爲消息實現優先級隊列,則可以使用排序集(Z命令)來存儲消息,並將其優先級用作分數值以及輪詢消費者。

3

我所做的是使用一個使用時間戳作爲分數的排序集,並將數據的關鍵字用作成員值。我使用最後一個項目的得分來檢索接下來的幾個,然後得到密鑰。一旦工作完成,我將Zrem和del包裝在MULTI/EXEC事務中。

本質上是愛德華所說的,但隨着密鑰存儲在有序集中的扭曲,因爲我的信息可能相當大。

希望這會有所幫助!

0

如果您想要一個發佈/訂閱系統,訂閱者在死後不會丟失消息,請考慮使用Redis Streams而不是Redis Pub/sub。

Redis的流有自己的架構和利弊/缺點,Redis的發佈/訂閱。使用Redis Streams,用戶可以發出命令:

我收到的最後一條消息是X,現在給我下一條消息; 如果沒有新消息,則等待一個到達。

上面鏈接的Antirez的文章是一個很好的介紹Redis流與更多的信息。

警告:此功能僅在Redis的不穩定(測試版)版本存在的現在。

我也是有同樣的問題