kafka核心概念講解

1、borker

broker能夠理解成一個kafka服務node,是一個運行的kafka服務。broker與broker之間是平等的關係,任意broker均可以down機而不影響其餘broker正常工做。kafaka在啓動的時候,會將本身的信息同步到zk上。數據存儲使用了zk的零時節點,broker須要經過心跳機制維護與zk的註冊關係,一旦broker宕機,zk上面對應的零時節點也會被刪除。

kafka Controller

咱們能夠把controller當成集羣的管理者,集羣中borker啓動時若是沒有controller回主動的去zk上註冊znode節點來搶奪controller的位置,註冊成功的broker會被當選爲kafka controller。若當前的controller宕機其餘borker會從從新進入controller爭搶流程,從而選出新的controller。controller主要的功能以下:html

  • UpdateMetadataRequest:更新元數據請求。topic分區狀態常常會發生變動(好比leader從新選舉了或副本集合變化了等)。因爲當前clients只能與分區的leader broker進行交互,那麼一旦發生變動,controller會將最新的元數據廣播給全部存活的broker。具體方式就是給全部broker發送UpdateMetadataRequest請求
  • CreateTopics: 建立topic請求。當前不論是經過API方式、腳本方式抑或是CreateTopics請求方式來建立topic,作法幾乎都是在Zookeeper的/brokers/topics下建立znode來觸發建立邏輯,而controller會監聽該path下的變動來執行真正的「建立topic」邏輯。
  • DeleteTopics:刪除topic請求。和CreateTopics相似,也是經過建立Zookeeper下的/admin/delete_topics/<topic>節點來觸發刪除topic,controller執行真正的邏輯
  • 分區重分配:即kafka-reassign-partitions腳本作的事情。一樣是與Zookeeper結合使用,腳本寫入/admin/reassign_partitions節點來觸發,controller負責按照方案分配分區
  • Preferred leader分配:preferred leader選舉當前有兩種觸發方式:1. 自動觸發(auto.leader.rebalance.enable = true);2. kafka-preferred-replica-election腳本觸發。二者「玩法」相同,向Zookeeper的/admin/preferred_replica_election寫數據,controller提取數據執行preferred leader分配
  • 分區擴展:即增長topic分區數。標準作法也是經過kafka-reassign-partitions腳本完成,不過用戶可直接往Zookeeper中寫數據來實現,好比直接把新增分區的副本集合寫入到/brokers/topics/<topic>下,而後controller會爲你自動地選出leader並增長分區
  • 集羣擴展:新增broker時Zookeeper中/brokers/ids下會新增znode,controller自動完成服務發現的工做
  • broker崩潰處理:一樣地,controller經過Zookeeper可實時偵測broker狀態。一旦有broker掛掉了,controller可當即感知併爲受影響分區選舉新的leader
  • ControlledShutdown:broker除了崩潰,還能「優雅」地退出。broker一旦自行終止,controller會接收到一個ControlledShudownRequest請求,而後controller會妥善處理該請求並執行各類收尾工做
  • Controller leader選舉:controller必然要提供本身的leader選舉以防這個全局惟一的組件崩潰宕機致使服務中斷。這個功能也是經過Zookeeper的幫助實現的。

2、topic & partiton

Topic至關於傳統消息系統MQ中的一個隊列queue,能夠把topic當成是消息的分類。partiton能夠當作是topic的一個分區,目的是突破IO瓶頸。kafka在存儲topic日誌的時候,將topic分開存儲,這樣就能將同一個消息的寫壓力分配到不一樣的分區,這樣能夠提高kafka的總體吞吐能力。爲了保證數據的高可用,kafka使用partiton-Replica進行數據備份,若partition leader掛了,kafka controller會自動從partiton-Replica選舉新的leader。提到備份不得不提到ISR,這是一個同步備份列表,每當用戶添加新的消息時,分區leader成功寫入日誌後,後必須保證ISR列表裏面的備份也成功寫入日誌後,才能給客戶端相應成功。所以ISR列表的備份的日誌老是和leader保持一致,在leader宕機的時候,可使用ISR列表的備份取代leader的位置。node

3、log & segment

kafka最終的數據承載是經過log的方式進行,kafka會按照請求的順序將消息存儲到log中。咱們知道一個topic可能會被分配到到個分區partiton來減輕單點負載。每一個partiton實際上在寫log的時候也會存在,單個文件大小物理極限的問題。所以kafka引入了segment解決方案,即將日誌分段存儲。不一樣的segment log組合起來的數據就是分區的存儲消息數據。爲了方便經過offset定位消息,segment log使用first-offset格式進行文件命名,first-offset是該文件存儲的第一條消息的offset。這樣就能經過消費者提供的offset很快定位到文件,而後經過offset偏移量能夠快速定位消息的存儲位置。apache

4、producer消息/數據生產者

生產者負責消息的發送,生產者須要指定消息的topic來區分不一樣消息。kafka收到消息後經過loadbalance策略,使用hash(message) % topic分片數 決定將數據存儲到哪個分片。 而後將message發送到制定分片的leader,leader收到消息後,將消息保存下來,接着等待ISR(a set of in-sync replicas,該列表的備份數據時刻保持和leader數據一致)中的replica消費消息併發送ack,若ISR列表中的備份分區都已經確認收到消息並保存成功後,leader將成功的消息返回給producer以代表,消息被妥善保存。併發

5、consumer [group]消息/數據消費者&offset

與其餘消息系統不一樣的是:kafka不會複製去保存客服端以前消費了那條消息,以及下一條應當消費那條消息,kafka將這些工做交給了消費客服端來作,所以kafka在消息消費能夠作到無狀態。offset就是用來保存某個消費組(consumer group)消費的在當前分區日誌下的偏移量的。一般狀況下,多個客服端在同時消費同一個消息分區消息的時候會存在併發問題,對於offset的控制就會出現問題,這樣就會出現消費重複的狀況,kafka使用無鎖機制解決這個問題。kafka規定,同一個分區(partition)下的數據只能被通一個consumer group中的一個線程消費,這樣就避免了不一樣線程之間爭奪通一個資源,經過這種設計kafka作到了無鎖,這樣能夠避免鎖競爭形成效率降低。所以建議consumer group裏面的線程數應當和分區數保持一致,這樣作能夠有效的利用線程資源,線程多了會被浪費掉,少了一個線程可能會處理多個分區的數據。若是你須要多個業務消費同一個消息,因爲不一樣的consumer group對贊成主題分區的offset是分開存儲的,咱們能夠建立多個consumer group實現多個線程來消費同一個消息的目的。.net

kafaka如何常量時間複雜度?

寫數據:經過上面消息的存儲過程能夠發現,除了數據存儲和備份操做,並無其餘耗時操做。路由分區->leader寫數據->數據複製,這些操做都和現有數據規模沒有任何關係。每次寫數據只會在原來的基礎上作追加存儲。因爲kafka使用了順序存儲而不是非隨機存儲(聽說磁盤的順序存儲效率遠高於磁盤的隨機存儲、有時候甚至比內存的隨機寫效率還高),同時kafka還使用了批量存儲的方式減小了對io的操做,提高了io效率。
讀數據:consumer在消費某個topic的時候,消費者會將全部的分區數據消費完,kafka要求,同一時刻對同一分區的數據只會被一個線程消費,這樣避免了鎖操做。同時經過consumer group提供的offset數據,經過kafka的文件存儲機制能夠快速的定位到一個segment文件,而且經過計算offset偏移量能夠快速定位到數據。從整個消費流程來看,數據規模對每一個過程效率是不敏感的。線程

kafaka如何作到高可用的&動態擴展

高可用的解決方案一般是採用數據冗餘以及快速恢復來解決的。kafka經過分區數據備份(partition replica)&分區數據分散到不一樣的機器以及kafka controller能夠快速檢測到宕機節點,經過讀取節點的分區數據,能夠快速從新選取分區leader,以恢復故障。同時在故障的處理過程當中,就算該分區不可用,不往分區寫入數據便可,對kafka的數據讀取也是沒有影響的。kafka使用hash 取餘的目的在於均衡負載,並不在於爲了經過message能夠快速的查找到這個message所在位置,這個不是kafka關注的業務。kafka經過數據複製和快速恢復作到了高可用,同時基於message不關注經過某個具體message的具體存存儲位置,所以在擴展kafka的時候,或者在擴展消息分區的時候,不須要進行額爲的數據複製操做,下降了擴展時候的成本。設計

引用

更多文章能夠訪問jframe.cn日誌

相關文章
相關標籤/搜索