歡迎你們前往騰訊雲技術社區,獲取更多騰訊海量技術實踐乾貨哦~算法
做者:閆燕飛api
Ckafka是基礎架構部開發的高性能、高可用消息中間件,其主要用於消息傳輸、網站活動追蹤、運營監控、日誌聚合、流式處理、事件追蹤、提交日誌等等須要高性能的場景,目前已經上線騰訊雲。Ckafka徹底兼容現有的Kafka協議,使現有Kafka用戶能夠零成本遷入Ckafka。Ckafka基於現有的Kafka進行了擴展開發和優化,爲了方便用戶理解Ckafka本文也將對Kafka的實現原理進行較爲詳細的介紹。緩存
Kafka是一種高吞吐量的採用發佈訂閱模式的分佈式消息系統,最初由LinkedIn採用Scala語言開發,用做LinkedIn的活動流追蹤和運營系統數據處理管道的基礎。現已成爲Apache開源項目,其主要的設計目標以下:安全
RabbitMQ | RocketMQ | CMQ | Kafka | |
---|---|---|---|---|
模式 | 發佈訂閱 | 發佈訂閱 | 傳統queue/發佈訂閱 | 發佈訂閱 |
同步算法 | GM | 同步雙寫 | Raft | ISR(Replica) |
分佈式擴展 | 否 | 支持 | 支持 | 支持 |
堆積能力 | 磁盤容量 | 磁盤容量 | 磁盤(水平擴展) | 磁盤(水平擴展) |
性能 | 中 | 高 | 高 | 很高 |
可靠性 | 通常 | 通常 | 極高 | 通常 |
持久化 | 內存/硬盤 | 磁盤 | 磁盤 | 磁盤 |
Kafka系統強依賴的組件。其存儲了Kafka核心原數據 (如topic信息配置、broker信息、 消費分組等等,至關於DB充當了Kafka的配置管理中心) 。 Kafka的leader選舉(如coordinator選舉、controller選舉、partition leader選舉等等),一樣也會藉助於zookeeper。服務器
coordinator協調器模塊,主要用來管理消費分組和消費offset,充當中介管理消費者並從消費分組中選舉出一個消費者做爲leader,而後將消費分組中全部消費者信息發往該leader由該leader負責分配partition。該模塊爲Kafka 0.9版本新加入的新的模塊,Kafka集羣中能夠存在多個協調器分別管不一樣的消費分組,提升整個系統的擴展能力,主要用於解決以前消費者(high level消費者api)都須要經過與zookeeper鏈接進行相關的選舉,致使zookeeper壓力大、驚羣及腦裂問題。架構
controller模塊,主要負責partition leader選舉、監聽建立及刪除Topic事件而後下發到指定broker進行處理等功能,整個Kafka集羣中只能有一個controller,Kafka利用zookeeper的臨時節點特性來進行controller選舉。分佈式
消息緩存代理,Kafka集羣包含一個或多個服務器,這些服務器被稱爲Broker,負責消息的存儲於轉發,做爲代理對外提供生產和消費服務。性能
消息主題(類別),邏輯上的概念,特指Kafka處理的消息源的不一樣分類,用戶能夠根據本身的業務形態將不一樣業務類別的消息分別存儲到不一樣Topic。用戶生產和消費時只需指定所關注的topic便可,不用關注該topic的數據存放的具體位置。優化
Topic物理上的分組,在建立Topic時能夠指定分區的數量,每一個partition是一個有序的隊列,按生產順序存儲着每條消息,並且每條消息都會分配一個64bit的自增加的有序offset(至關於消息id)。Partition是整個Kafka能夠平行擴展的關鍵因素。網站
副本,topic級別的配置,能夠理解爲topic消息的副本數。Kafka 0.8版本加入的概念,主要目的就是提升系統的可用性。防止broker意外崩潰致使部分partition不能夠服務。
In-Sync Replicas ,Kafka用來維護跟上leader數據的broker列表,當leader崩潰後,優先從該列中選舉leader
Producer 生產者,採用Push方式進行消息發佈生產。Producer能夠經過與zookeeper鏈接獲取broker信息, topic信息等等元數據,而後再與broker交互進行消息發佈。在此過程當中zookeeper至關於一個配置管理中心(相似於Name Server提供相關的路由信息)。採用直接向Producer暴露zookeeper信息存在如下兩個很是大的弊端:
正由於存在上面的問題,Kafka也提供了Metadata RPC,經過該RPC生產者能夠獲取到broker信息、topic信息以及topic下partition的leader信息,而後生產者在訪問指定的broker進行消息生產,從而對生產者隱藏了zookeeper信息使的整個系統更加安全、穩定、高效。
消費者,採用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甚至本身實現一個算法很是的靈活)。全部消費者都按照約定訪問分配給本身的partition,而且能夠選擇將消費offset保持在zookeeper或本身存。該方式會暴露zookeeper從而致使存在和暴露zookeeper給Producer同樣的問題,而且由於任何一個消費者退出都會觸發zookeeper事件,而後從新進行rebalance,從而致使zookeeper壓力很是大、並且還存在驚羣及沒法解決的腦裂問題,針對這個問題0.9版本(含)以後,Kafka Broker添加了coordinator協調器模塊。
但coordinator模塊也未進行任何分配算法相關的處理,只是替換了zookeeper的一些功能,充當了中介將以前消費者都要經過zookeeper本身選擇leader, 變成統一和coordinator通訊,而後由coordinator選擇leader,而後將同一個消費分組中的消費者都發送給leader(消費者api),由leader負責分配。另外一個方面就是coordinator當前多了管理offset的功能,消費者能夠選擇將offset提交給coordinator,而後由coordinator進行保存,當前默認狀況下coordinator會將offset信息保存在一個特殊的topic(默認名稱_
consumer_offsets)中,從而減小zookeeper的壓力。消費分組中partition的分配具體能夠看下一個小結中消費分組的相關說明。
消費分組,消費者標籤,用於將消費者分類。能夠簡單的理解爲隊列,當一個消費分組訂閱了一個topic則至關於爲這個topic建立了一個隊列,當多個消費分組訂閱同一個topic則至關於建立多個隊列,也變相的達到了廣播的目的,並且該廣播只用存儲一份數據。 爲了方便理解,經過下面的圖片對消費分組相關概念進行講解。
消息,是通訊和存儲的最小單位。其包含一個變長頭部,一個變長key,和一個變長value。其中key和value是用戶本身指定,對用戶來講是不透明的。Message的詳細格式下面會有介紹,這裏先不展開說明。
下一篇:《高性能消息隊列 CKafka 核心原理介紹(下)》
此文已由做者受權騰訊雲技術社區發佈,轉載請註明文章出處
原文連接:
此文已由做者受權騰訊雲技術社區發佈,轉載請註明文章出處
原文連接:https://www.qcloud.com/community/article/549934