Kafka的主要特點:
1. 為發布和訂閱提供高吞吐量,每秒可產生25萬消息(50MB),每秒可處理55萬消息(110MB)
2. 可進行持久化操作
3. 分布式系統,支持熱擴展
4. 消息被處理的狀態是consumer維護,不是server維護
5. 支持online和offline場景
Kafka架構:
分布式架構,Producer、Broker、Consumer都有多個,采用Push-and-Pull的模式,消息由Producer產生,Push進Broker,Broker起到中間緩存和分發的作用,Consumer從Broker Pull消息做處理,消息的產生和消費是異步的。
一些概念
1.Broker:Kafka集群中包含的服務器
2.Topic:每條發不到Kafka集群的消息所屬的類別
3.Partition:分區,物理概念,每個topic包含一個或多個partition,Kafka同一個Partition內保證消息有序性
4.Producer:消息生產者,向Broker寫消息
5.Consumer:消費者,從Broker讀取消息
6.Consumer Group:每個Consumer屬于一個特定的ConsumerGroup,每個分區分配給消費者組中不同的而且是唯一的消費者,并確保一個分區只屬于一個消費者
7.replication:partition的副本,保障partition的高可用,同一個partition可能有多個replication,多個replication選舉leader,其他replication作為folloer從leader復制數據
8.leader:replica中的一個角色,producer和consumer只跟leader交互
9.follower:replica中的一個角色,從leader中復制數據
10.controller:Kafka集群中的一個服務器,用來進行leader election以及各種failover
11.zookeeper:Kafka通過zookeeper來存儲集群的meta信息
Topic和Partition
消息發送時都被發送到一個topic,其本質就是一個目錄,而topic由是由一些Partition Logs(分區日志)組成,其組織結構如下圖所示:
每個Partition中的消息都是有序的,生產的消息被不斷追加到PartitionLog上,其中的每一個消息被賦予唯一的offset值。Kafka集群會保存所有的消息,不管消息有沒有被消費,我們可以設定消息的過期時間,只有過期的數據才會被自動清除以釋放磁盤空間。Kafka需要維持的元數據只有一個,消費消息在Partition中的offset值,Consumer每消費一條消息,offset值加1,Consumer可以重置offset值來讀取任意位置的消息。
發布消息
producer 采用 push 模式將消息發布到 broker,每條消息都被 append 到 patition 中,屬于順序寫磁盤(順序寫磁盤效率比隨機寫內存要高,保障 kafka 吞吐率)。
消息路由:
producer 發送消息到 broker 時,會根據分區算法選擇將其存儲到哪一個 partition。其路由機制為:
1.指定了 patition,則直接使用。?
2.未指定 patition 但指定 key,通過對 key 的 value 進行hash 選出一個 patition。
3.patition 和 key 都未指定,使用輪詢選出一個 patition。
Zookeeper在Kafka中的作用
Kafka在zk中的一些存儲結構
1.Broker Node的注冊
當一個Kafka broker啟動后,會向zookeeper注冊自己的節點信息,該節點為一個臨時節點,當broker斷開和zookeeper的連接時,其臨時節點將會被刪除。
路徑:/broker/ids/[0...N]
其中[0..N]表示broker id(broker id唯一,不可以重復),znode的值為對應broker的相關信息,如下:
{
? ? "jmx_port": -1, //JMX的端口號
? ? "timestamp": "1460082147315",//broker啟動的時間戳
? ? "host": "xx.xxx.xxx.xxx",//host
? ? "version": 1,//默認的版本
? ? "port": 9092 //broker進程的對外監聽的端口號
}
2.Broker Topic注冊
當一個broker啟動時,會向zookeeper注冊自己持有的topic和partitions信息,為臨時節點
路徑:/broker/topics/[topic]/partitions/[0...N]
其中[0..N]表示partition索引號。其znode下的信息如下:
{
? ? "controller_epoch": 17,//中央控制器的總的選舉次數
? ? "leader": 0, //此partition的broker leader的id
????"version": 1, //默認版本號
????"leader_epoch": 1,//此partition的leader選舉的次數
????"isr": [ 0 ] //同步副本組brokerId順序列表
}
3.Consumer id注冊
在kafka consumer的配置參數中有consumer.id,為臨時節點
路徑:/consumers/[group_id]/ids/[consumer_id]
{
? ? "version": 1,
? ? "subscription": { "user11": 1 },
? ? "pattern": "static",
? ? "timestamp": "1460083658252"
}{“topic_name”:#streams…},即表示此consumer目前所消費的topic + partitions列表
4.Consumer offset 跟蹤
用來跟蹤每個consumer group目前所消費的partition中最大的offset,此znode為永久節點
路徑:/consumers/[group_id]/offsets/[topic]/[partition_id]
可以看出offset跟group_id有關,以表明當group中一個消費者失效,其他consumer可以繼續消費
5.PartitionOwner注冊
用來標記partition被哪個consumer消費,為臨時節點
路徑:/consumers/[group_id]/owners/[topic]/[partition_id]
問題:
1. Kafka如何保證消息順序一致性?
(1)一個topic只用一個partition,不推薦
(2)使用同一個key,這樣相同key的消息會落在同一個partition
2. 如何刪除Kafka的舊數據?有幾種方式?Kafka讀取消息的時間復雜度?
(1)基于時間:log.retention.hours=168
(2)基于大小:log.retention.bytes=1073741824
3. Kafka消息消費采用什么模型?為什么使用Pull而不用Push?Pull有什么缺點,Kafka是如何解決的?
(1)Push模型很容易使得Consumer來不及處理消息,可能造成消息丟失,典型表現就是拒絕服務以及網絡擁塞
(2)Pull模型,可以使消費者自主控制消費消息的速率,也可控制逐條消費或批量消費
(3)Pull模型缺點,如果沒有數據,consumer會陷入無限循環中等待數據到達,為避免這種情況,pull請求中有參數,允許消費者請求在等待數據到達的長輪詢中進行阻塞。
參考資料:
https://blog.csdn.net/qq_35641192/article/details/80956244
https://blog.csdn.net/taoy86/article/details/80271784
https://www.cnblogs.com/yinchengzhe/p/5111648.html
https://blog.csdn.net/ouyang111222/article/details/51094912