Kafka概述:
定義:
Kafka是一個分布式的基于發布/訂閱模式的消息隊列,主要應用于大數據實時處理領域。
消息隊列消息隊列的兩種模式:
- 點對點模式:
消息生產者生產消息發送到Queue中,然后消息消費者從Queue中取出并且消費消息。
消息被消費以后,queue中不再有存儲,所以消息消費者不可能消費到已經被消費的消息。Queue支持存在多個消費者,但是對一個消息而言,只會有一個消費者可以消費。
- 發布/訂閱模式(一對多,消費者消費數據之后不會清除消息):
消息生產者(發布)將消息發布到topic中,同時有多個消息消費者(訂閱)消費該消息。和點對點方式不同,發布到topic的消息會被所有訂閱者消費。
?Kafka的基本架構:
基礎架構:
- Producer:消息生產者,就是向kafka broker發消息的客戶端;
- Consumer:消息消費者,向kafka broker取消息的客戶端;
- Consumer Group (CG):消費者組,由多個consumer組成。消費者組內每個消費者負責消費不同分區的數據,一個分區只能由一個消費者消費;消費者組之間互不影響。所有的消費者都屬于某個消費者組,即消費者組是邏輯上的一個訂閱者。
- Broker:一臺kafka服務器就是一個broker。一個集群由多個broker組成。一個broker可以容納多個topic。
- Topic:可以理解為一個隊列,生產者和消費者面向的都是一個topic;
- Partition:為了實現擴展性,一個非常大的topic可以分布到多個broker(即服務器)上,一個topic可以分為多個partition,每個partition是一個有序的隊列;
- Replica:副本,為保證集群中的某個節點發生故障時,該節點上的partition數據不丟失,且kafka仍然能夠繼續工作,kafka提供了副本機制,一個topic的每個分區都有若干個副本,一個leader和若干個follower。
- Leader:每個分區多個副本的“主”,生產者發送數據的對象,以及消費者消費數據的對象都是leader。
- Follower:每個分區多個副本中的“從”,實時從leader中同步數據,保持和leader數據的同步。leader發生故障時,某個follower會成為新的follower。?
kafka中partition和消費者對應關系:
1個partition只能被同組的一個consumer消費,同組的consumer則起到均衡效果。
- 消費者多于partition:同一個partition內的消息只能被同一個組中的一個consumer消費。當消費者數量多于partition的數量時,多余的消費者空閑。
- 消費者少于和等于partition:消息在同一個組之間的消費者之間均分。
- 多個消費者組:啟動多個組,則會使同一個消息被消費多次。
?Kafka文件存儲機制:
Kafka中消息是以topic進行分類的,生產者生產消息,消費者消費消息,都是面向topic的。
topic是邏輯上的概念,而partition是物理上的概念,每個partition對應于一個log文件,該log文件中存儲的就是producer生產的數據。Producer生產的數據會被不斷追加到該log文件末端,且每條數據都有自己的offset。消費者組中的每個消費者,都會實時記錄自己消費到了哪個offset,以便出錯恢復時,從上次的位置繼續消費。
由于生產者生產的消息會不斷追加到log文件末尾,為防止log文件過大導致數據定位效率低下,Kafka采取了分片和索引機制,將每個partition分為多個segment。每個segment對應兩個文件——“.index”文件和“.log”文件。這些文件位于一個文件夾下,該文件夾的命名規則為:topic名稱+分區序號。例如,first這個topic有三個分區,則其對應的文件夾為first-0,first-1,first-2。
index和log文件以當前segment的第一條消息的offset命名;“.index”文件存儲大量的索引信息,“.log”文件存儲大量的數據,索引文件中的元數據指向對應數據文件中message的物理偏移地址。
生產者:
分區原因:
- 方便在集群中擴展,每個Partition可以通過調整以適應它所在的機器,而一個topic又可以有多個Partition組成,因此整個集群就可以適應任意大小的數據了。
- 可以提高并發,因為可以以Partition為單位讀寫了。
如何保證數據可靠性:
為保證producer發送的數據,能可靠的發送到指定的topic,topic的每個partition收到producer發送的數據后,都需要向producer發送ack(acknowledgement確認收到),如果producer收到ack,就會進行下一輪的發送,否則重新發送數據。
副本的同步策略:
方案 | 優點 | 缺點 |
---|---|---|
半數以上完成同步,就發送ack | 延遲低 | 選舉新的leader時,容忍n臺節點的故障,需要2n+1個副本 |
全部完成同步,才發送ack | 選舉新的leader時,容忍n臺節點的故障,需要n+1個副本 | 延遲高 |
Kafka選擇了第二種方案,原因如下:
- 同樣為了容忍n臺節點的故障,第一種方案需要2n+1個副本,而第二種方案只需要n+1個副本,而Kafka的每個分區都有大量的數據,第一種方案會造成大量數據的冗余。
- 雖然第二種方案的網絡延遲會比較高,但網絡延遲對Kafka的影響較小。
ACK應答機制:
Kafka為用戶提供了三種可靠性級別,用戶根據對可靠性和延遲的要求進行權衡,選擇以下的配置。acks參數配置:
- 0:producer不等待broker的ack,這一操作提供了一個最低的延遲,broker一接收到還沒有寫入磁盤就已經返回,當broker故障時有可能丟失數據;
- 1:producer等待broker的ack,partition的leader落盤成功后返回ack,如果在follower同步成功之前leader故障,那么將會丟失數據;
- -1(all):producer等待broker的ack,partition的leader和follower全部落盤成功后才返回ack。但是如果在follower同步完成后,broker發送ack之前,leader發生故障,那么會造成數據重復。
消費者:
消費方式:
consumer采用pull(拉)模式從broker中讀取數據;push(推)模式很難適應消費速率不同的消費者,因為消息發送速率是由broker決定的。它的目標是盡可能以最快速度傳遞消息,但是這樣很容易造成consumer來不及處理消息,典型的表現就是拒絕服務以及網絡擁塞。而pull模式則可以根據consumer的消費能力以適當的速率消費消息。
pull模式不足之處是,如果kafka沒有數據,消費者可能會陷入循環中,一直返回空數據。針對這一點,Kafka的消費者在消費數據時會傳入一個時長參數timeout,如果當前沒有數據可供消費,consumer會等待一段時間之后再返回,這段時長即為timeout。
分區分配策略:
一個consumer group中有多個consumer,一個 topic有多個partition,所以必然會涉及到partition的分配問題,即確定那個partition由哪個consumer來消費。
Kafka有兩種分配策略,一是roundrobin,一是range。
offest維護:
由于consumer在消費過程中可能會出現斷電宕機等故障,consumer恢復后,需要從故障前的位置的繼續消費,所以consumer需要實時記錄自己消費到了哪個offset,以便故障恢復后繼續消費。
Kafka 0.9版本之前,consumer默認將offset保存在Zookeeper中,從0.9版本開始,consumer默認將offset保存在Kafka一個內置的topic中,該topic為__consumer_offsets。