Disque:Redis之父新開源的分散式記憶體作業佇列

謝麗發表於2015-05-03

DisqueRedis之父Salvatore Sanfilippo新開源的一個分散式記憶體訊息代理。它適應於“Redis作為作業佇列”的場景,但採用了一種專用、獨立、可擴充套件且具有容錯功能的設計,兼具Redis的簡潔和高效能,並且用C語言實現為一個非阻塞網路伺服器。有一點需要提請讀者注意,在Disque專案文件及本文中,“訊息(Message)”和“作業(Job)”可互換。

Disque是一個獨立於Redis的新專案,但它重用了Redis網路原始碼、節點訊息匯流排、庫和客戶端協議的一大部分。由於Disque使用了與Redis相同的協議,所以可以直接使用Redis客戶端連線Disque叢集,只是需要注意,Disque的預設埠是7711,而不是6379。

作為訊息代理,Disque充當了需要進行訊息交換的程式之間的一箇中間層,生產者向其中新增供消費者使用的訊息。這種生產者-消費者佇列模型非常常見,其主要不同體現在一些細節方面:

  • Disque是一個同步複製作業佇列,在預設情況下,新增任務會複製到W個節點上,W-1個節點發生故障也不會影響訊息的傳遞。
  • Disque支援至少一次和至多一次傳遞語義,前者是設計和實現重點,而後者可以透過將重試時間設為0來實現。每個訊息的傳遞語義都是單獨設定的,因此,在同一個訊息佇列中,語義不同的訊息可以共存。
  • 按照設計,Disque的至少一次傳遞是近似一次傳遞,它會盡力避免訊息的多次傳遞。
  • Disque叢集的所有節點都有同樣的角色,也就是“多主節點(multi-master)”。生產者和消費者可以連線到不同的佇列或節點,節點會根據負載和客戶端請求自動交換訊息。
  • Disque支援可選的非同步命令。在這種模式下,生產者在向一個複製因子不為1的佇列中新增一個作業後,可以不必等待複製完成就可以轉而執行其它操作,節點會在後臺完成複製。
  • 在超過指定的訊息重試時間後,Disque會自動將未收到響應的訊息重新放入佇列。
  • 在Disque中,消費者使用顯式應答來標識訊息已經傳遞完成。
  • Disque只提供盡力而為排序。佇列根據訊息建立時間對訊息進行排序,而建立時間是透過本地節點的時鐘獲取的。因此,在同一個節點上建立的訊息通常是按建立順序傳遞的,但Disque並不提供嚴格的FIFO語義保證。比如,在訊息重新排隊或者因為負載均衡而移至其它節點時,訊息的傳遞順序就無法保證了。所以,Salvatore指出,從技術上講,Disque嚴格來說並不是一個佇列,而更應該稱為訊息代理。
  • Disque透過四個引數提供了細粒度的作業控制,分別是複製因子(指定訊息的副本數)、延遲時間(將訊息放入佇列前的最小等待時間)、重試時間(設定訊息何時重新排隊)、過期時間(設定何時刪除訊息)。

需要注意的是,Disque專案尚處於Alpha預覽測試階段,程式碼和演算法未經充分測試,還不適合用於生產環境。在接下來的幾個月裡,其實現和API很可能會發生重大變化。此外,它還有如下限制:

  • 其中還包含許多沒有用到的Redis程式碼;
  • 它並非源於Salvatore的專案需求,而是源於他看到人們將Redis用作佇列,但他不是這方面的專家;
  • 同Redis一樣,它是單執行緒的,但鑑於它所操作的資料結構並不複雜,將來可以考慮改為多執行緒;
  • Disque程式中的作業數量受可用記憶體限制;
  • Disque沒有進行效能最佳化。

總之,該專案尚處於研究測試階段。感興趣的讀者可以檢視該專案的GitHub頁面,瞭解更多資訊。

相關文章