您好,登錄后才能下訂單哦!
如何進行高性能消息隊列CKafka核心原理的分析,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
Ckafka是基礎架構部開發(fā)的高性能、高可用消息中間件,其主要用于消息傳輸、網站活動追蹤、運營監(jiān)控、日志聚合、流式處理、事件追蹤、提交日志等等需要高性能的場景,,目前已經上線騰訊云。Ckafka完全兼容現(xiàn)有的Kafka協(xié)議,使現(xiàn)有Kafka用戶可以零成本遷入Ckafka。Ckafka基于現(xiàn)有的Kafka進行了擴展開發(fā)和優(yōu)化,為了方便用戶理解Ckafka本文也將對Kafka的實現(xiàn)原理進行較為詳細的介紹。
Kafka是一種高吞吐量的采用發(fā)布訂閱模式的分布式消息系統(tǒng),最初由LinkedIn采用Scala語言開發(fā),用作LinkedIn的活動流追蹤和運營系統(tǒng)數(shù)據(jù)處理管道的基礎?,F(xiàn)已成為Apache開源項目,其主要的設計目標如下:
以時間復雜度為O(1)的方式提供消息持久化能力,即使對TB級以上的數(shù)據(jù)也能保證常數(shù)時間復雜度的訪問性能。注:其實對于寫Kafka的確保證了O(1)的常數(shù)時間性能。但對于讀,是segment分片級別對數(shù)O(logn)時間復雜度。
高吞吐率。Kafka力爭即使在非常廉價的商用機上也能做到單機支持100Kqps的消息傳輸能力。
支持Kafka Server間的消息分區(qū)(partition),及分布式消費,同時保證每個partition內的消息順序傳輸。注:其實Kafka本身實現(xiàn)邏輯并不做該保證,主要的算法是集中在消費者端,由消費者的分配算法保證,詳情下面會介紹。
同時支持離線數(shù)據(jù)處理和實時數(shù)據(jù)處理。
支持在線水平擴展,Kafka的水平擴展主要來源于其分區(qū)(partition)的設計理念。
RabbitMQ | RocketMQ | CMQ | Kafka | |
---|---|---|---|---|
模式 | 發(fā)布訂閱 | 發(fā)布訂閱 | 傳統(tǒng)queue/發(fā)布訂閱 | 發(fā)布訂閱 |
同步算法 | GM | 同步雙寫 | Raft | ISR(Replica) |
分布式擴展 | 否 | 支持 | 支持 | 支持 |
堆積能力 | 磁盤容量 | 磁盤容量 | 磁盤(水平擴展) | 磁盤(水平擴展) |
性能 | 中 | 高 | 高 | 很高 |
可靠性 | 一般 | 一般 | 極高 | 一般 |
持久化 | 內存/硬盤 | 磁盤 | 磁盤 | 磁盤 |
Kafka系統(tǒng)強依賴的組件。其存儲了Kafka核心原數(shù)據(jù) (如topic信息配置、broker信息、 消費分組等等,相當于DB充當了Kafka的配置管理中心) 。 Kafka的leader選舉(如coordinator選舉、controller選舉、partition leader選舉等等),同樣也會借助于zookeeper。
coordinator協(xié)調器模塊,主要用來管理消費分組和消費offset,充當中介管理消費者并從消費分組中選舉出一個消費者作為leader,然后將消費分組中所有消費者信息發(fā)往該leader由該leader負責分配partition。該模塊為Kafka 0.9版本新加入的新的模塊,Kafka集群中可以存在多個協(xié)調器分別管不同的消費分組,提高整個系統(tǒng)的擴展能力,主要用于解決之前消費者(high level消費者api)都需要通過與zookeeper連接進行相關的選舉,導致zookeeper壓力大、驚群及腦裂問題。
controller模塊,主要負責partition leader選舉、監(jiān)聽創(chuàng)建及刪除Topic事件然后下發(fā)到指定broker進行處理等功能,整個Kafka集群中只能有一個controller,Kafka利用zookeeper的臨時節(jié)點特性來進行controller選舉。
消息緩存代理,Kafka集群包含一個或多個服務器,這些服務器被稱為Broker,負責消息的存儲于轉發(fā),作為代理對外提供生產和消費服務。
消息主題(類別),邏輯上的概念,特指Kafka處理的消息源的不同分類,用戶可以根據(jù)自己的業(yè)務形態(tài)將不同業(yè)務類別的消息分別存儲到不同Topic。用戶生產和消費時只需指定所關注的topic即可,不用關注該topic的數(shù)據(jù)存放的具體位置。
Topic物理上的分組,在創(chuàng)建Topic時可以指定分區(qū)的數(shù)量,每個partition是一個有序的隊列,按生產順序存儲著每條消息,而且每條消息都會分配一個64bit的自增長的有序offset(相當于消息id)。Partition是整個Kafka可以平行擴展的關鍵因素。
副本,topic級別的配置,可以理解為topic消息的副本數(shù)。Kafka 0.8版本加入的概念,主要目的就是提高系統(tǒng)的可用性。防止broker意外崩潰導致部分partition不可以服務。
In-Sync Replicas ,Kafka用來維護跟上leader數(shù)據(jù)的broker列表,當leader崩潰后,優(yōu)先從該列中選舉leader
Producer 生產者,采用Push方式進行消息發(fā)布生產。Producer可以通過與zookeeper連接獲取broker信息, topic信息等等元數(shù)據(jù),然后再與broker交互進行消息發(fā)布。在此過程中zookeeper相當于一個配置管理中心(類似于Name Server提供相關的路由信息)。采用直接向Producer暴露zookeeper信息存在以下兩個非常大的弊端:
zookeeper屬于整個Kafka系統(tǒng)的核心結構,其性能直接影響了整個集群的規(guī)模,故當暴露給生產者過多的生產者會導致zookeeper性能下降最終影響整個Kafka集群的規(guī)模和穩(wěn)定性。
zookeeper存儲著Kafka的核心數(shù)據(jù),若公開暴露出去則容易受到惡意用戶的攻擊,最終導致Kafka集群不可服務,故非常不建議Kafka服務提供方向使用者暴露zookeeper信息。
正因為存在上面的問題,Kafka也提供了Metadata RPC,通過該RPC生產者可以獲取到broker信息、topic信息以及topic下partition的leader信息,然后生產者在訪問指定的broker進行消息生產,從而對生產者隱藏了zookeeper信息使的整個系統(tǒng)更加安全、穩(wěn)定、高效。
消費者,采用Pull方式,從Broker端拉取消息并進行處理。當采用訂閱方式(一般通過使用consumer high level api或new consumer來進行訂閱)訂閱感興趣的Topic時,Consumer必須屬于一個消費分組,而且Kafka保證同一個Topic的一條消息只能被同一個消費分組中的一個Consumer消費,但多個消費分組可以同時消費這一條消息。
其實Kafka本身不對這個(同一個topic的一條消息只能被同一個消費分組中一個消費者消費)做任何保證,尤其是在0.9版本之前Kafka Broker根本都沒有消費分組的概念也沒有消費offset概念,Kafka只是提供FetchMessage RPC供使用者去拉取消息,至于是誰來取,取多少次其根本不關心,該保證是由消費者api內部的算法自己完成。
在0.9版本之前消費分組只是消費者端的概念,同一個消費分組的所有消費者都通過與zookeeper連接注冊,然后自主選擇一個leader(一個消費分組一個leader),再通過該leader進行partition分配(分配算法默認是range,也可以配置成round robin甚至自己實現(xiàn)一個算法非常的靈活)。所有消費者都按照約定訪問分配給自己的partition,并且可以選擇將消費offset保持在zookeeper或自己存。該方式會暴露zookeeper從而導致存在和暴露zookeeper給Producer一樣的問題,并且因為任何一個消費者退出都會觸發(fā)zookeeper事件,然后重新進行rebalance,從而導致zookeeper壓力非常大、而且還存在驚群及無法解決的腦裂問題,針對這個問題0.9版本(含)之后,Kafka Broker添加了coordinator協(xié)調器模塊。
但coordinator模塊也未進行任何分配算法相關的處理,只是替換了zookeeper的一些功能,充當了中介將之前消費者都要通過zookeeper自己選擇leader, 變成統(tǒng)一和coordinator通信,然后由coordinator選擇leader,然后將同一個消費分組中的消費者都發(fā)送給leader(消費者api),由leader負責分配。另一個方面就是coordinator當前多了管理offset的功能,消費者可以選擇將offset提交給coordinator,然后由coordinator進行保存,當前默認情況下coordinator會將offset信息保存在一個特殊的topic(默認名稱_
consumer_offsets)中,從而減少zookeeper的壓力。消費分組中partition的分配具體可以看下一個小結中消費分組的相關說明。
消費分組,消費者標簽,用于將消費者分類。可以簡單的理解為隊列,當一個消費分組訂閱了一個topic則相當于為這個topic創(chuàng)建了一個隊列,當多個消費分組訂閱同一個topic則相當于創(chuàng)建多個隊列,也變相的達到了廣播的目的,而且該廣播只用存儲一份數(shù)據(jù)。 為了方便理解,通過下面的圖片對消費分組相關概念進行講解。
一個消費分組可以訂閱多個topic,同理一個topic可以被多個消費分組訂閱
topic中的partition只會分配給同一個消費分組中的一個消費者,基于這種分配策略,若在生產消息時采用按照消息key進行hash將同一個用戶的消息分配到同一partition則可以保證消息的先進先出。Kafka正是基于這種分配策略實現(xiàn)了消息的先進先出。
同一個消費分組中,不同的消費者訂閱的topic可能不一樣,但Kafka的partition分配策略保證在同一個消費分組的topic只會分配給訂閱了該topic的消費者,即消費分組中會按照topic再劃分一個維度。以上圖為例Consumer group1中C1和C2同時訂閱了Topic 1所以將Topic1下面的P0 ~ P3四個partition均分給C1和C2。同樣Consumer group1中只有C1訂閱了Topic0故Topic0中的兩個partition只分配給了C1未分配給C2。
消息,是通信和存儲的最小單位。其包含一個變長頭部,一個變長key,和一個變長value。其中key和value是用戶自己指定,對用戶來說是不透明的。
看完上述內容,你們掌握如何進行高性能消息隊列CKafka核心原理的分析的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。