大伙評評理,Kafka與Pulsar 誰更牛?
Apache Kafka(簡稱Kafka)是由LinkedIn公司開發的分布式消息流平臺,于2011年開源。Kafka是使用Scala和Java編寫的,當下已成為最流行的分布式消息流平臺之一。Kafka基于發布/訂閱模式,具有高吞吐、可持久化、可水平擴展、支持流數據處理等特性。
Apache Pulsar(簡稱Pulsar)是雅虎開發的“下一代云原生分布式消息流平臺”,于2016年開源,目前也在快速發展中。Pulsar集消息、存儲、輕量化函數式計算為一體,采用計算與存儲分離架構設計,支持多租戶、持久化存儲、多機房跨區域數據復制,具有強一致性、高吞吐、低延時及高可擴展性等流數據存儲特性。
Kafka與Pulsar都是優秀的分布式消息流平臺,它們都提供了以下基礎功能:
(1) 消息系統:Kafka與Pulsar都可以實現基于發布/訂閱模式的消息系統,消息系統可以實現由消息驅動的程序—生產者負責產生并發送消息到消息系統,消息系統將消息投遞給消費者,消費者收到消息后,執行自己的邏輯。
這種消息驅動機制具有以下優點:
- 系統解耦:生產者與消費者邏輯解耦,互不干預。如果需要對消息添加新的處理邏輯,則只需要添加新的消費者即可,非常方便。
- 流量削峰:消息系統作為消息緩沖區,以低成本將上游服務(生產者)的流量洪峰緩存起來,下游服務(消費者)按照自身處理能力從消息隊列中讀取數據并進行處理,避免下游服務由于大量的請求流量而崩潰。
- 數據冗余:消息系統將數據緩存起來,直到數據被處理,避免下游服務由于崩潰下線、網絡阻塞等原因無法及時處理數據而導致數據丟失。
(2) 存儲系統:Kafka與Pulsar可以存儲大量數據,并且客戶端控制自己讀取數據的位置,所以它們也可以作為存儲系統,存儲大量歷史數據。
(3) 實時流數據管道:Kafka與Pulsar可以構建實時流數據管道,流數據管道從MySQL、MongoDB等數據源加載數據到Kafka與Pulsar中,其他系統或應用就可以穩定地從Kafka與Pulsar中獲取數據,而不需要再與MySQL等數據源對接。為此,Kafka提供了Kafka Connect模塊,Pulsar提供了Pulsar IO模塊,它們都可以構建實時流數據管道。
(4) 流計算應用:流計算應用不斷地從Kafka與Pulsar中獲取流數據,并對數據進行處理,最后將處理結果輸出到Kafka與Pulsar中(或其他系統)。流計算應用通常需要根據業務需求對流數據進行復雜的數據變換,如流數據聚合或者join等。為此,Kafka提供了Kafka Streams模塊,Pulsar提供了Pulsar Functions模塊,它們都可以實現流計算應用。另外,Kafka與Pulsar也可以與流行的Spark、Flink等分布式計算引擎結合,構建實時流應用,實時處理大規模數據。
Kafka與Pulsar都具有(或追求)以下特性
- 高吞吐、低延遲:它們都具有高吞吐量處理大規模消息流的能力,并且能夠低延遲處理消息。這也是大多數消息流平臺追求的目標。
- 持久化、一致性:Kafka與Pulsar都支持將消息持久化存儲,并提供數據備份(副本)功能,保證數據安全及數據一致性,它們都是優秀的分布式存儲系統。
- 高可擴展性(伸縮性):Kafka與Pulsar都是分布式系統,會將數據分片存儲在一組機器組成的集群中,并支持對集群進行擴容,從而支持大規模的數據。
- 故障轉移(容錯):Kafka與Pulsar支持故障轉移,即集群中某個節點因故障下線后,并不會影響集群的正常運行,這也是優秀的分布式系統的必備功能。
Kafka與Pulsar雖然提供的基礎功能類似,但它們的設計、架構、實現并不相同,本書將深入分析Kafka與Pulsar如何實現一個分布式、高擴展、高吞吐、低延遲的消息流平臺。另外,本書也會介紹Kafka與Pulsar中連接器、流計算引擎等功能的應用實踐。
Kafka與Pulsar涉及的基礎概念
將Kafka與Pulsar都視為一個簡單的消息系統,消息流轉流程如下圖所示。
圖中展示了消息系統中的4個基本概念。它們在Kafka與Pulsar中都存在,并且含義相同。
- 消息Message:Kafka與Pulsar中的數據實體。
- 生產者Producer:發布消息的應用。
- 消費者Consumer:訂閱消息的應用。
- 主題Topic:Kafka與Pulsar將某一類消息劃分到一個主題,主題是消息的邏輯分組,不同主題的消息互不干預。
下面結合一個例子說明上述概念。假如存在一個用戶服務,該用戶服務創建了一個主題“userTopic”,每當有新用戶注冊時,用戶服務都會將一個消息發送到該主題中,消息內容為“新用戶注冊”。當前有兩個服務訂閱了該主題的消息:權益服務和權限服務。權益服務收到消息后,負責給新用戶創建權益。權限服務收到消息后,負責給新用戶分配權限。該例子中的消息即用戶服務發送的數據實體,生產者是用戶服務。消費者是權益服務與權限服務。ka的基礎概念
下面介紹Kafka的一些基礎概念
(1) Kafka消費組:Kafka將多個消費者劃分到一個邏輯分組中,該分組即一個消費組。這個概念比較重要,結合上面的例子進行說明,在Kafka中,權益服務所有的消費者都可以加入一個權益消費組rightsGroup,而權限服務所有的消費者都可以加入一個權限消費組guthorityGroup。不同消費者之間消費消息互不干預。
(2) Broker:Kafka服務節點,可以將Broker理解為一個Kafka的服務節點或者服務進程(下面將其統稱為Broker節點),多個Broker節點可以組成一個Broker集群。
(3) 分區Partition:Kafka定義了分區的概念,一個主題由一個或多個分區組成,Kafka將一個主題的消息劃分到不同的分區,并將不同分區存儲到不同的Broker,從而實現分布式存儲(典型的數據分片思想),每個分區都有對應的下標,下標從0開始。
(4) 副本Replica:Kafka中每個分區都有一個或多個副本,其中有1個leader副本,0個或多個follow副本,每個副本都保存了該分區全部的內容。Kafka會將一個分區的不同副本保存到不同的Broker節點中,以保證數據的安全。本書后面會詳細分析Kafka副本同步機制。
(5) AR(Assigned Replicas):分區的副本列表,即一個分區所有副本所在Broker的列表。
(6) ISR:分區中所有與leader副本保持一定程度同步(即不能落后太多)的副本會組成ISR(In-Sync Replicas)集合。ISR集合中包括leader副本,可以將其理解為已同步副本(不一定完全同步,但不會落后太多)。
(7) ACK機制:ACK(消息確認)機制是消息系統中的一個很重要的機制,消息系統ACK機制與HTTP的ACK機制非常類似。消息系統ACK機制可以分為兩部分:
- mBroker收到生產者發送的消息并成功存儲這些消息后,返回成功響應(可以將該成功響應理解為一種ACK)給生產者,這時生產者可以認為消息已經發送成功,否則生產者可能需要做一些補償操作,如重發消息。
- m消費者收到Broker投遞的消息并成功處理后,返回消費成功響應給Broker,Broker收到這些消費成功響應后,可以認為消費者已經成功消費了消息,否則Broker可能需要做一些補償操作,如重新投遞消息。該場景下消費者通常需要將消費成功的消息位置(或者消息Id等)發送給Broker,并且Broker需要存儲這些消費成功的位置,以便后續消費者重啟后從該位置繼續消費。該場景也是我們關注的重點。
在Kafka中,每個消息都存在一個偏移量offset,如果將一個Kafka主題理解為一個簡單的消息數組,那么可以將消息偏移量理解為該消息在該數組中的索引。消費者會將最新消費成功的消息的下一個偏移量發送給Broker(代表該偏移量前面的消息都已經消費成功),Broker會存儲這些偏移量,以記錄消費者的最新消費位置。為了方便描述,本書后面將消費者提交ACK信息中的偏移量稱為ACK偏移量。
另外,Kafka與Pulsar都使用ZooKeeper存儲元數據,完成分布式協作等操作,ZooKeeper是一種分布式協作服務,專注于協作多個分布式進程之間的活動,可以幫助開發人員專注于應用程序的核心邏輯,而不必擔心應用程序的分布式特性。
下圖展示了Kafka集群的基礎架構:
下面介紹Pulsar的基礎概念
(1) Pulsar訂閱組:Pulsar可以將多個消費者綁定到一個訂閱組中,類似于Kafka的消費組。同樣使用前面“用戶服務”的例子進行說明,在Pulsar中,權益服務所有的消費者都可以綁定一個權益訂閱組rightsSubscription,而權限服務所有的消費者都可以綁定一個權限訂閱組guthoritySubscription,不同訂閱組之間消費消息互不干預。
(2) 非分區主題、分區主題:Kafka中每個分區都與一個Broker綁定,而Pulsar中每個主題都與一個Broker綁定,某主題的消息固定發送給相應的Broker節點。而Pulsar中也有“分區主題”的概念,分區主題由一組非分區的內部主題組成(下面將Pulsar中組成分區主題的非分區內部主題簡稱為內部主題),每一個內部主題都與一個Broker綁定,這樣一個分區主題可以將消息發送到多個Broker,避免Pulsar單個主題的性能受限于單個Broker節點。
(3) Broker:Pulsar集群中的服務節點。需要注意,Pulsar由于采用計算、存儲分離的架構,因此Pulsar Broker節點只負責計算,并不負責存儲,Pulsar Broker節點會完成數據檢驗、負載均衡等工作,并將消息轉發給Bookie節點。
(4) Bookie:Pulsar利用BookKeeper服務實現存儲功能,BookKeeper中的節點被稱為Bookie節點。BookKeeper框架是一個分布式日志存儲服務框架,本書后面會詳細分析它。Pulsar中的Bookie節點負責完成消息存儲工作。
(5) Ledger:BookKeeper的數據集合,生產者會將數據寫入Ledger,而消費者從Ledger中讀取數據。為了數據安全,BookKeeper會將一個Ledger的數據存儲到多個Bookie節點中,實現數據備份。
(6) Entry:Ledger中的數據單元,Ledger中的每個數據都是一個Entry。可以將Ledger理解為一個賬本,Entry則是賬本中的一個條目。
(7) 租戶、命名空間:Pulsar定義了租戶、命名空間的概念,Pulsar是一個多租戶系統,它給不同的租戶分配不同的資源,并保證不同租戶之間的數據相互隔離,互不干預,這樣可以支持多團隊、多用戶同時使用一個Pulsar服務。每個租戶還可以創建多個命名空間,命名空間為主題的邏輯分組。可以將Pulsar理解為一個大房子,每個租戶是房子里的一個房間,并且這個房間的空間劃分為不同的區域(命名空間),不同區域存放不同的物件。例如,用戶服務可以創建一個租戶“user”,存儲用戶服務的消息。該租戶可以按自己的業務場景,創建多個命名空間,存放不同的主題,如下圖所示。
(8) Cluster集群:Pulsar為集群定義了一個Cluster概念,每個Pulsar Broker節點都運行在一個Cluster集群下,不同的Cluster集群之間可以相互復制數據,從而實現跨地域復制。
(9) ACK機制:與Kafka類似,Pulsar同樣需要完成“Broker存儲消息后返回成功響應給生產者”“消費者成功處理消息后發送ACK給Broker”。Pulsar中的每個消息都有一個消息Id,Pulsar消費者會將消費成功的消息Id作為ACK請求內容發送給Broker。
下圖展示了Pulsar集群的基礎架構。
? ?