kafka是乙個分布式流式處理平台,具有三大主要功能:
1、發布和訂閱訊息
2、高度容錯機制,訊息持久化儲存
3、實時訊息處理
kafka具有非常高的吞吐量,通常廣泛應用於兩大場景:
1、做為系統或應用程式間的資料通道,進行資料傳輸
2、做為應用程式來進行實時資料處理
kafka提供了四大核心api:
1、producer api。生產訊息
2、consumer api。消費訊息
3、stream api。流式處理
4、connector api。連線多種資料來源
kafka集群包括五大核心元件:
1、broker。每台節點啟動的kafka例項
2、zookeeper。kakfa集群協調者,包括leader選舉和元資料儲存
3、producer。生產者負責將訊息推送到topic中
4、consumer。消費者通常屬於某乙個消費者組
5、topic。主題即為訊息的擁有者,每個topic有1-n個分割槽partition
kafka以topic來儲存訊息,每條訊息都有乙個topic標籤。生產者可以將訊息寫入不同的topic,消費者按照自己需要訂閱對應的topic來獲取訊息。
通常topic由乙個或多個分割槽partition,每個分割槽對應乙個日誌檔案log,每個log包含多個segment file。裡面儲存該分割槽的訊息,訊息在分區內是有序的。
topic中分割槽資料儲存方式如圖:
當生產者向topic中寫入一條訊息時,該訊息會以追加方式寫入對應的日誌檔案尾部。每個分割槽接收的訊息都會分配乙個單調遞增的序列號,通常我們稱為offset,因此在分區內訊息是有序的,但不是所有分割槽全域性有序。同時在記憶體中會維護乙個segment file的offset列表,記錄每乙個檔案offset的起始位置,方便進行定位查詢。
producer生產者負責向topic中寫入訊息資料,通常傳送訊息預設都是非同步傳送,即不會等待傳送結果,不會阻塞執行緒。
眾所周知訊息是儲存在分割槽中的,因此傳送訊息時如何確定該訊息屬於哪個分割槽呢?
通常在發訊息時不指定key或key為null時,會預設觸發partitioner使用roundrobin演算法,將訊息均勻分布在各個分割槽中。
傳送訊息時指定key,partitioner會預設按照key進行hash計算,對分割槽數取模運算,判斷訊息屬於哪個分割槽,然後將資料寫入對應的分割槽中。因此相同key的訊息會永遠寫入同乙個分割槽中。
如果以上都不滿足使用者需求,使用者可繼承partitioner介面,自定義partitioner,按照自己邏輯決定訊息該進入哪個分割槽,然後在傳送訊息時指定自定義的partitioner即可。
kakfa訊息是持久化並提供一定可靠性的,有引數acks控制。
當acks=0時,表示客戶端只管傳送,不等待服務端確認訊息是否寫入成功。會造成訊息丟失。
當acks=1時,表示等待服務端leader成功收到訊息並寫入磁碟檔案,如果在leader同步副本時掛掉,導致副本沒有正常同步,會造成訊息丟失。
當acks=all或-1時,表示等待leader和所有副本都寫入成功,才會認為這條訊息寫入成功了。當然這種情況是最安全的,但是也會降低生產者的生產效率。雖然這種情況最安全,但是也不能保證訊息不丟失。因為假設partition只有乙個leader,沒有其他副本,當leader接受完訊息後宕機,也會造成訊息丟失。
因此在設定asks=all或-1之外,還要設定min.insync.replicas>=2。保證在isr中至少有乙個副本寫入成功,這樣就保證了乙個leader和乙個副本資料寫入成功。
kafka做為乙個分布式平台,為了實現高容錯,避免單點故障,採取了冗餘副本機制。主副本和副本分散在各個節點,即使某個節點宕機,在其他節點也會有該節點資料副本,從而保證集群高度容錯機制。當消費者訪問的節點出現宕機情況時,會觸發rebalance,將請求轉移到其他節點。
kafka集群有leader和follower,leader節點資料做為主檔案,follower節點資料做為副本,需要從leader節點將資料同步過來。
kafka如何實現副本同步?由於生產者會先將資料寫入leader節點,所以leader節點肯定儲存完整的資料。leader節點維護乙個isr(in sync replicas)集合,裡面存放著正在同步的副本資訊。isr中副本不能落後主副本太多,否則會被leader從isr集合中踢出,這些被踢出的副本叫osr(out sync replicas)。
at least once:至少一次。如果生產者傳送訊息失敗會進行重試,重試可能會導致訊息重複寫入,消費者重複消費。同時也可能會導致訊息亂序。
如果服務端在成功寫入日誌檔案後,正要給客戶端傳送ack時宕機,然後客戶端重試傳送訊息,這樣就會造成訊息重複寫入。
如果當第一次ack返回失敗,客戶端要進行重試的時候,第二條訊息已經發出去了,這樣就會導致分區內資料亂序。
delivery.timeout.ms控制客戶端重試,表示傳送訊息到收到服務端成功或失敗ack時間。這個值不能小於request.timeout.ms 和 linger.ms之和。
max.in.flight.requests.per.connection引數表示producer端儲存未得到響應的請求數量,設定為1可以保證訊息順序性
at most once:至多一次。當ack返回錯誤或超時,不會進行重試。當retries=0時,當訊息沒有成功寫入,則會造成訊息丟失。
exactly once:剛好一次。無論生產者是否重**送訊息,消費者也只會消費一次。此方式通過kafka事務進行實現。
實現exactly once有兩種方式:
方式一:冪等producer方式,保證單個分割槽訊息只會寫入一次,不會出現重複訊息。需要設定enable.idempotence=true,並且max.in.flight.requests.per.connection<=5,retries>0,acks ='all』或-1。
此方式缺點是單分割槽冪等性和單會話冪等性。單分割槽冪等性只能保證單個分割槽不會出現重複資料。單會話冪等性,producer啟動時會有乙個pid,如果重啟後producer的pid發生變化,不能保證冪等性。
方式二:事務。kafka提供了事務的api,保證訊息原子性寫入多個分割槽,要麼全部成功,要麼全部失敗。啟動事務,在producer端設定transactional.id,enable.idempotence引數會自動設定為true,replication.factor>=3,min.insync.replicas=2。
kafka消費者不是單獨存在的,它屬於某個消費者組。每個消費者都有乙個group id,相同group id的消費者位於同乙個消費者組。
消費者有幾種不同的消費方式,指定分割槽、不指定分割槽。offset管理可由zookeeper管理,也可消費者管理。當消費者管理offset時,需要手動提交offset。通常消費者管理offset時,會將消費進度(offset)儲存在外部儲存中,例如hbase。
kafka中消費者有幾個特點:
1、同乙個消費者組的消費者採用合作模式進行消費,同一條訊息只會被乙個消費者消費
2、不同消費者組獲取的訊息是相同的
3、消費者不是以訊息為單位進行消費,而是以分割槽為單位進行消費,每個分割槽在同一消費者組中只能有乙個消費者
4、同一消費者組內,消費者數量不能大於分割槽數量
水平一般,能力有限,大資料小學生一枚。文章主要用於個人學習和總結,如果能給他人帶來幫助,純屬意外。
Kafka架構原理詳解
kafka 儲存的訊息來自任意多被稱為 producer 生產者的程序。資料從而可以被發布到不同的 topic 主題下的不同 partition 分割槽。在乙個分區內,這些訊息被索引並連同時間戳儲存在一起。其它被稱為 consumer 消費者的程序可以從分割槽訂閱訊息。kafka 執行在乙個由一台或...
Kafka基礎 Kafka架構
目錄kakfa 架構 kafka最初是由linkedin公司採用scala語言開發的乙個多分割槽 多副本並且基於zookeeper協調的分布式訊息系統,現在已經捐獻給了apache 會。目前kafka已經定位為乙個分布式流式處理平台,它以 高吞吐 可持久化 可水平擴充套件 支援流處理等多種特性而被廣...
Kafka 基礎架構
1 producer 訊息生產者,就是向 kafka broker 發訊息的客戶端 2 consumer 訊息消費者,向 kafka broker 取訊息的客戶端 3 consumer group cg 消費者組,由多個 consumer 組成。消費者組內每個消費者負責消費不同分割槽的資料,乙個分割...