【12图】你管这破玩意叫Pulsar
這兩年pulsar發展比較快,有好多大公司引入了pulsar,相關的資料和課程也多了,今天一起來了解一下pulsar這款中間件。
下圖是幾款消息中間件的歷史:
2012年pulsar在Yahoo內部開發,2016年開源并捐獻給Apache,2018成為Apache頂級項目。
1架構
pulsar的架構圖如下:
總結一下,pulsar有下面的幾個特性。
1.1 計算存儲分離
pulsar采用計算和存儲相分離的架構,Broker集群負責把producer發出的消息發送給consumer,同時承擔負載均衡的作用。
Pulsar用 Apache BookKeeper作為持久化存儲,Broker持有BookKeeper client,把未確認的消息發送到BookKeeper進行保存。
BookKeeper是一個分布式的WAL(Write Ahead Log)系統,pulsar使用BookKeeper有下面幾個便利:
可以為Topic創建多個ledgers
Ledger是一個只追加的數據結構,并且只有一個writer,這個writer負責多個BookKeeper存儲節點(就是Bookies)的寫入。Ledger的條目會被復制到多個bookies。
Broker可以創建、關閉和刪除Ledger,也可以追加內容到Ledger。
Ledger被關閉后,只能以只讀狀態打開,除非要明確地寫數據或者是因為writer掛掉導致的關閉。
Ledger只能有writer這一個進程寫入,這樣寫入不會有沖突,所以寫入效率很高。如果writer掛了,Ledger會啟動恢復進程來確定Ledger最終狀態和最后提交的日志,保證之后所有Ledger進程讀取到相同的內容。
除了保存消息數據外,還會保存cursors,也就是消費端訂閱消費的位置。這樣所有cursors消費完一個Ledger的消息后這個Ledger就可以被刪除,這樣可以實現ledgers的定期翻滾從頭寫。
1.2 節點對等
從架構圖可以看出,broker節點不保存數據,所有broker節點都是對等的。如果一個broker宕機了,不會丟失任何數據,只需要把它服務的topic遷移到一個新的broker上就行。
Broker的topic擁有多個邏輯分區,同時每個分區又有多個segment,writer寫數據時,首先會選擇Bookies,比如圖中的segment1,選擇了Bookie1、Bookie2、Bookie4,然后并發地寫下去。這樣這三個節點并沒有主從關系,協調完全依賴于writer,因此它們也是對等的。
1.3 擴展和擴容
在遇到雙十一等大流量的場景時,必須增加consumer,這時因為Broker不存儲任何數據,可以方便的增加broker。broker集群會有一個或多個broker做消息負載均衡,當新的broker加入后,流量會自動從壓力大的broker上遷移過來。
對于BookKeeper,如果對存儲要求變高,比如之前存儲2個副本,現在需要存儲4個副本,這時可以單獨擴展bookies而不用考慮broker。因為節點對等,之前節點的segment又堆放整齊,加入新節點并不用搬移數據。writer會感知新的節點并優先選擇使用。
1.4 容錯機制
對于broker,因為不保存任何數據,如果節點宕機了,就相當于客戶端斷開,重新連接其他的broker就可以了。
對于BookKeeper,因為保存了多份副本,并且這些副本都是對等的,沒有主從關系,所以當一個節點宕機后,不用立即恢復,后臺有一個線程會檢查宕機節點的數據備份進行恢復。
2 BookKeeper簡介
從上一節的講解看出,Apache Bookkeeper是一個易擴展、高可用、運維簡單的分布式存儲系統。這節再看一下Bookkeeper的其他三個特性。
2.1 客戶端數量
我們知道,在Kafka中,客戶端只能從leader節點讀取數據。但在BookKeeper中,客戶端可以從任何一個bookie副本讀取數據,這有三個好處:
增加了讀高可用
把客戶端流量平均分配到了不同的bookie
可以通過增加客戶端數量來提高讀取效率
客戶端和服務器通信采用Netty實現異步I/O。網絡I/O使用單個TCP連接進行多路復用,這就以很少的資源消耗實現了非常高的吞吐量。
2.3 I/O隔離
為什么要做I/O隔離?在大多數消息系統中,如果consumer處理慢,可能會導致消息積壓。這迫使存儲系統從持久存儲介質中讀取數據。當存儲系統I/O組件共享寫入、追尾讀、追趕讀的單一路徑時,就會出現I/O抖動及頁面緩存的換入換出。
寫入和追尾讀對可預測的低延遲有較高要求,而追趕讀則對吞吐量的要求比較高,分離這三個路徑很重要。
在BookKeeper中,bookie使用三條獨立的I/O路徑,分別用于寫入、追尾讀、追趕讀。如下圖:
參考[1]
3 多租戶
Pulsar可以使用多租戶來管理大集群。Pulsar的租戶可以跨集群分布,每個租戶都可以有單獨的認證和授權機制。租戶也是存儲配額、消息TTL和隔離策略的管理單元。
Pulsar的多租戶性質主要體現在topic的URL中,其結構如下:
persistent://tenant/namespace/topic可以看到,租戶是topic的最基本單位。
假如一個公司有三個部門,tenant1、tenant2、tenant3,可以分配三個租戶,這三個租戶互不干擾,如下圖:
如果消息平臺不支持租戶,那部門之間想要隔離,就要給每個部門部署一套集群,運維成本非常高。
4 消息模型
4.1 消息結構
首先看一下Pulsar的消息結構,如下圖:
消息流由多個獨立的segment組成,(這里的segment就是上面講的ledger),segment又包含獨立的entry,entry又由獨立的message組成。這里的message就是consumer發來的消息。
可以看到,一個message的id組成包括Ledger-id,entry-id,batch-index,partition-index。
需要注意兩點:
segment和entry都是BookKeeper里面的概念。
pulsar作為消息平臺時,一個message就是一個entry。當pulsar作為流平臺時,為了提高吞吐量,會開啟batch,這樣多個message組成一個entry。
4.2 創建過程
消息的創建過程如下圖:
消息創建后主要經歷下面幾步:
選擇一個partition
發送到管理這個partition的broker
broker將消息并發的發送給N個bookie,這個N是可以配置的。broker持有BookKeeper的客戶端,也就是writer,writer收到寫請求后,會并發的寫入N個bookie。上圖中N=3。
bookie寫完消息后會給broker一個回復,broker收到指定數量的確認消息后就會認為寫BookKeeper成功。這個數量是這個配置的,比如M,M越大,寫BookKeeper延遲越大,數據一致性越高。因此這個配置要對一致性和延遲到進行。
5 消費模型
5.1 概要
Pulsar的消費模型如下圖:
producer將消息發送給topic,topic下有多個partition,partition下面又有多個broker。
broker負責接收消息并把消息分配給給consumer,并把消息寫到BookKeeper。
broker還具有限流功能,可以根據限流閾值對producer的消息進行限流。
consumer并不能直接從broker中獲取消息,consumer和broker之間有一個Subscription,Consumer通過Subscription獲取消息。
5.2 subscription
subscription有四種類型:
獨占模式(Exclusive):同一個topic只能有一個消費者,如果多個消費者,就會出錯。
災備模式(Failover):同一個topic可以有多個消費者,但是只能有一個消費者消費,其他消費者作為故障轉移備用,如果當前消費者出了故障,就從備用消費者中選擇一個進行消費。如下圖:
共享模式(Shared):同一個topic可以由多個消費者訂閱和消費。消息通過round robin輪詢機制分發給不同的消費者,并且每個消息僅會被分發給一個消費者。當消費者斷開,發送給它的沒有被消費的消息還會被重新分發給其它存活的消費者。如下圖:
Key_Shared:消息和消費者都會綁定一個key,消息只會發送給綁定同一個key的消費者。如果有新消費者建立連接或者有消費者斷開連接,就需要更新一些消息的key。如下圖:
跟Shared模式相比,Key_Shared的好處是既可以讓消費者并發地消費消息,又能保證同一Key下的消息順序。
5.3 Cursor
當多個consumer訂閱同一個topic時,Subscription為每一個consumer分配一個Cursor,這樣多個Consumer之間就不會相互影響了。如下圖:
Subscription會維護一個消息的ACK狀態,consumer處理完消息后,會給broker返回ACK,表示消息已經處理完成。如果broker一直沒有收到ACK,就會把消息發送到其他consumer。
如果客戶端想要重新消費Cursor以前的消息,Cursor是支持reset的,reset之后,Cursor就回退回去了,這時consumer可以從新的Cursor位置進行消費。
Cursor的位置是會實時寫入BookKeeper的,這必定會有一定的性能損耗。因此,Pulsar提供了一種非持久化的Subscription(Non-durable Exclusive)。Pulsar的Reader接口內嵌了Non—durable Exclusive Cursor,它讀取消息不會返回ACK。
6 broker代理
通過前面的講解可以看到,consumer和producer只需要跟broker進行交互,而不用跟底層的BookKeeper交互,事實上,broker還有一層代理,consumer和producer直接跟代理進行交互。如下圖:
7 Zookeeper
Pulsar提供了System topic用來保存策略之類的元數據,盡量減少對Zookeeper的依賴。
Zookeeper也保存一些策略相關的元數據,還保存了broker和BookKeeper集群相關的配置元數據,比如服務發現相關的元數據。
8 總結
Pulsar是一款非常優秀的中間件,實現了計算和存儲相分離,支持多租戶,擴展和擴容、容錯都是非常容易的。
·············· END ··············參考資料
[1]
參考: https://zhuanlan.zhihu.com/p/158550358
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的【12图】你管这破玩意叫Pulsar的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面向.NET开发人员的Dapr——入门
- 下一篇: WPF Grid动态显示或隐藏一列的一种