在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ 數(shù)據(jù)庫/ 設計
nsqadmin
常見問題
安裝
編譯客戶端庫
特性和擔保
工具
拓撲模式
設計
Docker
nsqd
內(nèi)幕
性能
TCP 協(xié)議規(guī)范
nsqlookupd
介紹
產(chǎn)品配置
客戶端庫
快速開始

設計

注意:可視化的演示參見 slide deck。

NSQ 是繼承于 simplequeue(部分的 simplequeue),因此被設計為(排名不分先后)

  • 提供更簡單的拓撲方案,達到高可用性和消除單點故障
  • 滿足更強的消息可靠傳遞的保證
  • 限制單個進程的內(nèi)存占用(通過持久化一些消息到硬盤上)
  • 極大簡化了生產(chǎn)者和消費者的配置要求
  • 提供了一個簡單的升級路徑
  • 提升效率

簡化配置和管理

單個 nsqd 實例被設計成可以同時處理多個數(shù)據(jù)流。流被稱為“話題”和話題有 1 個或多個“通道”。每個通道都接收到一個話題中所有消息的拷貝。在實踐中,一個通道映射到下行服務消費一個話題.

話題和通道都沒有預先配置。話題由第一次發(fā)布消息到命名的話題或第一次通過訂閱一個命名話題來創(chuàng)建。通道被第一次訂閱到指定的通道創(chuàng)建。

話題 和通道的所有緩沖的數(shù)據(jù)相互獨立,防止緩慢消費者造成對其他通道的積壓(同樣適用于話題級別)。

一個通道一般會有多個客戶端連接。假設所有已連接的客戶端處于準備接收消息的狀態(tài),每個消息將被傳遞到一個隨機的客戶端。例如:

http://wiki.jikexueyuan.com/project/nsq-guide/images/design1.gif" alt="nsqd clients" />

總之,消息從話題->通道是多路傳送的(每個通道接收的所有該話題消息的副本),即使均勻分布在通道->消費者之間(每個消費者收到該通道的消息的一部分)。

NSQ 還包括一個輔助應用程序,nsqlookupd,它提供了一個目錄服務,消費者可以查找到提供他們感興趣訂閱話題的 nsqd 地址 。在配置方面,把消費者與生產(chǎn)者解耦開(它們都分別只需要知道哪里去連接 nsqlookupd 的共同實例,而不是對方),降低復雜性和維護。

在更底的層面,每個 nsqd 有一個與 nsqlookupd 的長期 TCP 連接,定期推動其狀態(tài)。這個數(shù)據(jù)被 nsqlookupd 用于給消費者通知 nsqd 地址。對于消費者來說,一個暴露的 HTTP /lookup 接口用于輪詢。

為話題引入一個新的消費者,只需啟動一個配置了 nsqlookup 實例地址的 NSQ 客戶端。無需為添加任何新的消費者或生產(chǎn)者更改配置,大大降低了開銷和復雜性。

注:在將來的版本中,啟發(fā)式 nsqlookupd 可以基于深度,已連接的客戶端數(shù)量,或其他“智能”策略來返回地址。當前的實現(xiàn)是簡單的返回所有地址。最終的目標是要確保所有深度接近零的生產(chǎn)者被讀取。

值得注意的是,重要的是 nsqdnsqlookupd 守護進程被設計成獨立運行,沒有相互之間的溝通或協(xié)調(diào)。

我們還認為重要的是有一個方式來聚合查看,監(jiān)測,并管理集群。我們建立 nsqadmin 做到這一點。它提供了一個 Web UI 來瀏覽 topics/channels/consumers 和深度檢查每一層的關鍵統(tǒng)計數(shù)據(jù)。此外,它還支持幾個管理命令例如,移除通道和清空通道(這是一個有用的工具,當在一個通道中的信息可以被安全地扔掉,以使深度返回到 0)。

http://wiki.jikexueyuan.com/project/nsq-guide/images/design2.png" alt="nsqadmin" />

簡單的升級路徑

這是我們的高優(yōu)先級之一。我們的生產(chǎn)系統(tǒng)處理大量的流量,都建立在我們現(xiàn)有的消息工具上,所以我們需要一種方法來慢慢地,有條不紊地升級我們特定部分的基礎設施,而不產(chǎn)生任何影響。

首先,在消息生產(chǎn)者方面,我們建立 nsqd 匹配 simplequeue。具體來說,nsqd 暴露了一個 HTTP /PUT 端點,就像 simplequeue,上傳二進制數(shù)據(jù)(需要注意的一點是 endpoint 需要一個額外的查詢參數(shù)來指定”話題”)。想切換到發(fā)布消息到 nsqd 的服務只需要很少的代碼變更。

第二,我們建立了兼容已有庫功能和語義的 Python 和 Go 庫。這使得消息的消費者通過很少的代碼改變就可使用。所有的業(yè)務邏輯保持不變。

最后,我們建立工具連接起新舊組件。這些都在倉庫的示例(examples)目錄中:

  • nsq_pubsub - 在 NSQ 集群中以 HTTP 接口的形式暴露的一個 pubsub
  • nsq_to_file - 將一個給定話題的所有消息持久化到文件
  • nsq_to_http - 對一個話題的所有消息的執(zhí)行 HTTP 請求到(多個)endpoints。

消除單點故障

NSQ被設計以分布的方式被使用。nsqd 客戶端(通過 TCP )連接到指定話題的所有生產(chǎn)者實例。沒有中間人,沒有消息代理,也沒有單點故障:

http://wiki.jikexueyuan.com/project/nsq-guide/images/design3.png" alt="nsq clients" />

這種拓撲結構消除單鏈,聚合,反饋。相反,你的消費者直接訪問所有生產(chǎn)者。從技術上講,哪個客戶端連接到哪個 NSQ 不重要,只要有足夠的消費者連接到所有生產(chǎn)者,以滿足大量的消息,保證所有東西最終將被處理。

對于 nsqlookupd,高可用性是通過運行多個實例來實現(xiàn)。他們不直接相互通信和數(shù)據(jù)被認為是最終一致。消費者輪詢所有的配置的 nsqlookupd 實例和合并 response。失敗的,無法訪問的,或以其他方式故障的節(jié)點不會讓系統(tǒng)陷于停頓。

消息傳遞擔保

NSQ 保證消息將交付至少一次,雖然消息可能是重復的。消費者應該關注到這一點,刪除重復數(shù)據(jù)或執(zhí)行idempotent等操作

這個擔保是作為協(xié)議和工作流的一部分,工作原理如下(假設客戶端成功連接并訂閱一個話題):

  1. 客戶表示他們已經(jīng)準備好接收消息
  2. NSQ 發(fā)送一條消息,并暫時將數(shù)據(jù)存儲在本地(在 re-queue 或 timeout)
  3. 客戶端回復 FIN(結束)或 REQ(重新排隊)分別指示成功或失敗。如果客戶端沒有回復, NSQ 會在設定的時間超時,自動重新排隊消息

這確保了消息丟失唯一可能的情況是不正常結束 nsqd 進程。在這種情況下,這是在內(nèi)存中的任何信息(或任何緩沖未刷新到磁盤)都將丟失。

如何防止消息丟失是最重要的,即使是這個意外情況可以得到緩解。一種解決方案是構成冗余 nsqd對(在不同的主機上)接收消息的相同部分的副本。因為你實現(xiàn)的消費者是冪等的,以兩倍時間處理這些消息不會對下游造成影響,并使得系統(tǒng)能夠承受任何單一節(jié)點故障而不會丟失信息。

附加的是 NSQ 提供構建基礎以支持多種生產(chǎn)用例和持久化的可配置性。

限定內(nèi)存占用

nsqd 提供一個 --mem-queue-size 配置選項,這將決定一個隊列保存在內(nèi)存中的消息數(shù)量。如果隊列深度超過此閾值,消息將透明地寫入磁盤。nsqd 進程的內(nèi)存占用被限定于 --mem-queue-size * #of_channels_and_topics

http://wiki.jikexueyuan.com/project/nsq-guide/images/design4.png" alt="message overflow" />

此外,一個精明的觀察者可能會發(fā)現(xiàn),這是一個方便的方式來獲得更高的傳遞保證:把這個值設置的比較低(如 1 或甚至是 0)。磁盤支持的隊列被設計為在不重啟的情況下存在(雖然消息可能被傳遞兩次)。

此外,涉及到信息傳遞保證,干凈關機(通過給 nsqd 進程發(fā)送 TERM 信號)堅持安全地把消息保存在內(nèi)存中,傳輸中,延遲,以及內(nèi)部的各種緩沖區(qū)。

請注意,一個以 #ephemeral 結束的通道名稱不會在超過 mem-queue-size 之后刷新到硬盤。這使得消費者并不需要訂閱頻道的消息擔保。這些臨時通道將在最后一個客戶端斷開連接后消失。

效率

NSQ 被設計成一個使用簡單 size-prefixed 為前綴的,與“memcached-like”類似的命令協(xié)議。所有的消息數(shù)據(jù)被保持在核心中,包括像嘗試次數(shù)、時間截等元數(shù)據(jù)類。這消除了數(shù)據(jù)從服務器到客戶端來回拷貝,當重新排隊消息時先前工具鏈的固有屬性。這也簡化了客戶端,因為他們不再需要負責維護消息的狀態(tài)。

此外,通過降低配置的復雜性,安裝和開發(fā)的時間大大縮短(尤其是在有超過 > 1 消費者的話題)。

對于數(shù)據(jù)的協(xié)議,我們做了一個重要的設計決策,通過推送數(shù)據(jù)到客戶端最大限度地提高性能和吞吐量的,而不是等待客戶端拉數(shù)據(jù)。這個概念,我們稱之為 RDY 狀態(tài),基本上是客戶端流量控制的一種形式。

當客戶端連接到 nsqd 和并訂閱到一個通道時,它被放置在一個 RDY 為 0 狀態(tài)。這意味著,還沒有信息被發(fā)送到客戶端。當客戶端已準備好接收消息發(fā)送,更新它的命令 RDY 狀態(tài)到它準備處理的數(shù)量,比如 100。無需任何額外的指令,當 100 條消息可用時,將被傳遞到客戶端(服務器端為那個客戶端每次遞減 RDY 計數(shù))。

客戶端庫的被設計成在 RDY 數(shù)達到配置 max-in-flight 的 25% 發(fā)送一個命令來更新 RDY 計數(shù)(并適當考慮連接到多個 nsqd 情況下,適當?shù)胤峙洌?/p>

http://wiki.jikexueyuan.com/project/nsq-guide/images/design5.png" alt="nsq protocol" />

這是一個重要的性能控制,使一些下游系統(tǒng)能夠更輕松地批量處理信息,并從更高的 max-in-flight 中受益。

值得注意的是,因為它既是基于緩沖和推送來滿足需要(通道)流的獨立副本的能力,我們已經(jīng)提供了行為像 simplequeue 和 pubsub 相結合的守護進程。這是簡化我們的系統(tǒng)拓撲結構的強大工具,如上述討論那樣我們會維護傳統(tǒng)的 toolchain。

Go

我們很早做了一個戰(zhàn)略決策,利用 Go 來建立 NSQ 的核心。我們最近的博客上講述我們在 bitly 如何使用 Go,并提到這個適合的項目-通過瀏覽那篇文章可能對理解我們?nèi)绾沃匾曔@么語言有所幫助。

關于 NSQ ,Go channels(不要與 NSQ 通道混淆),并且內(nèi)置并發(fā)性功能的語言的非常適合于的 nsqd的內(nèi)部工作。我們充分利用緩沖的通道來管理我們在內(nèi)存中的消息隊列和無縫把溢出消息放到硬盤。

標準庫讓我們很容易地編寫網(wǎng)絡層和客戶端代碼。只需要付出很少的努力,來整合內(nèi)置的內(nèi)存和 CPU 剖析進行優(yōu)化。我們還發(fā)現(xiàn)它易于單獨測試組件,模擬類型接口,以迭代方式構建功能。

上一篇:常見問題下一篇:nsqd