基本概念的總結
在基本的Kafka架構中,producer將消息發布到Kafka話題中,一個Kafka話題通常指消息的類別或者名稱,Kafka話題被集群中一個充當Kafka server角色的
broker創建。Kafka broker用來存儲消息,consumer可以訂閱一個或者多個話題來獲取話題中的消息。其中Kafka brokers用Zookeeper來獲取消息狀態,
而Kafka consumers則利用Zookeeper來跟蹤消息的offset。具體如下圖所示:
上圖是一個只有一個Kafka broker的架構,其中包含一個topic,該topic包含4個partition,上圖包含了Kafka中最重要的5個組件:Zookeeper, Broker, Topic, Producer, and Consumer。
在Kafka話題中,每一個partition都被映射到一個邏輯日志文件中,日志文件呈現為一組大小相等的段文件。每一個partition是一個有序的,不可變的消息序列;每一次當有消息被發布到這個partition,負責該partition的broker將新來的消息追加到該partition最后一個段文件中。在存儲的消息的條數達到配置的消息條數或者當過了一段時間后,這些段文件將刷寫到磁盤中。一旦段文件被刷寫到磁盤,這些消息就可以被Kafka consumer消費。
每個消息在partition中都有一個稱為offset的標記,該標記是有序,唯一的序號。每個partition可以有選擇的冗余多份,以保證可用性。在多個partition存在的情況下,有一個稱為leader的partition,其他partition都稱為follower。其中leader負責該partition所有的讀寫請求,而follower則異步的更新本地來和leader保持一致,所以在消息的一致性上,follower是要延遲於leader的。
Kafka動態維護一組同步副本(ISR),該副本緊跟leader與其內容保持一致,並將最新的ISR同步給Zookeeper。如果leader掛了,一個follower(在ISR同步副本中)將自動成為新的leader。在Kafka集群中,每個server都扮演雙重角色,它作為一些partition的leader的同時,也作為其他partition的follower,這確保了Kafka集群內的負載平衡。
在Kafka中有一個consumer group的概念,每個consumer只是consumer group中的一個進程。一個話題中的一條消息只能被consumer group中的一個consumer進程消費,也就是說,如果要求該話題中的某消息被多個consumer消費,則這些consumer必須在不同的consumer group中。
consumer總是從一個特定的partition順序地消費消息,並應答消費了的消息的offset,已經應答的offset意味着consumer已經消費了這些信息。consumer發出了一個包含消息offset的異步請求給broker,並得到字節的緩沖區。
在Kafka的設計中,broker是無狀態的,也就是說,在broker中不存儲哪些消息被哪些consumer消費了,這些消費記錄被設計存儲在consumer中,也就是說,broker根本不知道哪些消息被消費了。在Kafka中,給消息定義了一個SLA (service level agreement),SLA表示消息的保留時間,一旦消息保留時間超過SLA,則會被刪除,這種設計有意無意的提示了consumer去消費舊消息,不然就會被刪除。
Kafka設計的一些重點總結:
1. Kafka最重要的基石是消息在文件系統上的緩沖和存儲。在Kafka中,消息是立即寫到操作系統內核頁的,數據的緩沖和刷寫到磁盤都是可配置的。
2. Kafka提供消息的長時間存儲,即使消息已經被消費過,它支持consumer再消費。
3. Kafka利用消息集合來group消息,從而減小網絡帶寬的消耗。消息被消費的元數據不是存儲在server上,而是在consumer上。這可以避免“消息的丟失”和“同一消息的多次傳輸”。
4. consumers將狀態信息儲存在Zookeeper上,Kafka也允許將這些信息存儲到其他存儲系統上。
5. 在Kafka中,producer和consumer以一種推-拉的模式工作,其中producer將信息推到Kafka broker上,然后consumer則從broker上拉取信息。
6. Kafka的設計中沒有master的概念,所有的broker都是對等的。這種設計使得broker的添加和刪除變得簡便,因為broker的元數據信息被Zookeeper維護着並被所有的consumer共享。producer在發送數據給broker時也可以在同步和異步的模式中作選擇。
消息壓縮
在Kafka中,支持對消息分組壓縮,以獲得更高效的信息傳輸,這種壓縮一次壓縮多個消息,而不是一個消息。一組消息壓縮后然后在發送給broker,這能有效減少網絡帶寬的消耗。
在Kafka0.8中,每個分區的leader broker在消息追加到日志上前,需要給每一個消息賦予一個獨一無二的邏輯offset,所以如果消息是壓縮的,broker需要解壓縮,然后才能給每條消息賦予offset,對於壓縮的數據,在賦予完offset后,broker還需要再壓縮這些數據然后再刷寫到磁盤上。所以,數據的壓縮對broker的CPU的負載是一大挑戰。
消息最初的壓縮是發生在producer端的,可支持的壓縮協議包括GZIP和Snappy,具體配置如下:
Property name |
Description |
Default value |
compression.codec |
This parameter specifies the compression codec for all data generated by this producer. Valid values are none, gzip, and snappy. |
none |
compressed.topics |
This parameter allows you to set whether compression should be turned on for particular topics. If the compression codec is anything other than none, enable compression only compressed.topics for specified topics, if any. If the list of compressed topics is empty, then enable the null specified compression codec for all topics. If the compression codec is none, compression is disabled for all topics. |
null |
消息partition
對消息如何partition由producer決定,broker按照消息來的先后順序存儲,在Kafka broker可以為每一個topic配置partition數目。
partition冗余
冗余是Kafka0.8的新特性,冗余可以提高Kafka的可用性,其中producer和consumer都是可感知冗余的。下圖形象展示了冗余的特性:
在冗余機制下,每個擁有n個冗余的partition可以容忍n-1個冗余的不可用,在這n個冗余中,其中有一個擔任leader的冗余,其余的冗余稱為follower,這些可用的follower構成一個ISR集合,Zookeeper維護着每個partition的leader的信息和ISR的信息。
partition冗余方式
1. 同步冗余:消息在producer端分成了不同的partition,對於每一個partition,producer首先同Zookeeper確定該partition的lead broker,然后將消息發布到該broker上,當消息都發布完了,消息將刷寫到lead broker的log上,然后關於該partition的所有follower都在該lead broker拉取該partition,通過單一通道來保證消息的順序。每個follower拉取完畢partition並存儲到本地log后,會返回一個應答給lead broker。當收到所有follower的應答后,lead broker則返回一個應答給producer。此時,該partition可以被consumer消費。
2. 異步冗余:異步冗余則不會等待所有的follower的應該就應答producer,這種機制如果lead broker掛掉的話則不能保證消息的正常消費。
對於某個ISR集合中的follower掛掉后,leader則將該follower從ISR集合中剔除,其他的follower繼續同步信息;
如果是leader掛掉了,就算失敗發生在最后的應答前,producer還是會再次發布該partition到新的leader上。
leader掛掉會經歷如下幾個過程:
1)從ISR集合中,所有follower中最早注冊的replica稱為新的leader,其他的依然為follower;
2)新leader的log end offset(LEO)成為該partition的最終提交消息;
3)新leader在配置時間過了后或者所有的replica都同步好了后,將新的ISR同步給Zookeeper,並啟動讀寫服務。
Kafka學習剛入門,如有理解錯誤請給位指正!