1.Kafka簡介
Kafka是一個分布式的基于發(fā)布訂閱模式的消息隊列,主要針對大規(guī)模數(shù)據(jù)處理場景。
1.1 消息隊列(Message Queue)的好處:
a.解耦
生產(chǎn)者和消費者可以獨立發(fā)布服務枉证,不會導致線上異常和數(shù)據(jù)丟失占调;
b.可恢復性
MQ通常具有重試機制返帕,而且分組消費甲棍,數(shù)據(jù)存儲到磁盤(支持副本),使數(shù)據(jù)不會丟失拔妥;
c.緩沖
避免生產(chǎn)者和消費者處理速度不一致帶來的問題忿危,如數(shù)據(jù)丟失,調用異常和超時等没龙;
d.削峰
使用MQ可以一定程度上解決突發(fā)高流量的情況铺厨,將短時間內的流量,擴大到更長時間的維度兜畸,避免系統(tǒng)超負荷運行努释,甚至系統(tǒng)奔潰碘梢;
e. 異步通信
消費者可以不立即處理MQ中的消息咬摇,讓MQ作為一種臨時的數(shù)據(jù)存儲方式(Kafka默認保存數(shù)據(jù)7天),等在需要的時候在進行消費處理煞躬。
f. 數(shù)據(jù)分發(fā)
當業(yè)務M需要調用多方(如A,B,C)時肛鹏,普通的調用需要逐個調用逸邦,當增加D或者減少C時,當前業(yè)務需要修改代碼以及重新上線等在扰;但是使用MQ之后缕减,當前業(yè)務M只需要將消息發(fā)送到MQ中,不用關心到底是誰消費了消息芒珠,消費者的增加和刪除不影響業(yè)務M桥狡。
1.2 消息隊列(Message Queue)的缺點:
a.系統(tǒng)可用性減低
加入MQ之后,服務就會依賴MQ皱卓,MQ宕機裹芝,那么服務也就不可用了。
b.系統(tǒng)復雜性增加:
同步改成異步之后娜汁,MQ消息的丟失嫂易,重復,順序性等都需要考慮掐禁。
c.數(shù)據(jù)一致性問題:
在不同的分組消費MQ時怜械,有的分組消費成功,有的消費失敗傅事,會導致各系統(tǒng)之間的數(shù)據(jù)不一致缕允。
2.Kafka的架構:
2.1 消息隊列的兩種模式:
Producer A是發(fā)布訂閱模式(一對多,數(shù)據(jù)消費后不會刪除)蹭越;
Producer B是點對點模式(一對一灼芭,一個消息只會有一個消費者消費,數(shù)據(jù)消費后會被刪除)般又;
2.2 架構說明:
1)Producer:
生產(chǎn)者向broker發(fā)送消息
2)Consumer:
消費Broker的消息彼绷,
3)Consumer Group:
一個group由多個consumer組成,消費者組內每個消費者負責消費不同的分區(qū)數(shù)據(jù)茴迁,一個分區(qū)只能由一個組內消費者消費寄悯,消費者組之間互不影響;
4)Broker:
一臺Kafka機器就是一個Broker堕义,一個Kafka集群由多個Broker組成猜旬,一個Broker可以容納多個topic;
5)Topic:
主題隊列,Producer和Consumer都是面向topic隊列的倦卖;
6)Partition:
一個topic可以分成多個Partition洒擦,Partition分不到不同的Broker上,每個Partition是有序的隊列怕膛;
7)Replica:
副本保證集群中一個節(jié)點發(fā)生故障時熟嫩,該節(jié)點的partition不會丟失,保證Kafka仍然能夠繼續(xù)工作褐捻,一個leader partition對應多個follower掸茅;
8)leader:
主分區(qū)椅邓,生產(chǎn)者發(fā)送數(shù)據(jù)和消費者消費數(shù)據(jù)都是這對leader partition的;
9)follower:
從分區(qū)昧狮,從分區(qū)實時從leader主分區(qū)同步數(shù)據(jù)景馁,當leader發(fā)生故障時,某一個從分區(qū)成為leader逗鸣。
2.3 Kafka數(shù)據(jù)的保存:
Kafka中合住,topic是邏輯概念,partition是物理概念撒璧,每個partition對應一個log文件聊疲,log保存producer的產(chǎn)生的數(shù)據(jù),producer的數(shù)據(jù)會被不斷的添加到該log文件的末尾沪悲,且每條數(shù)據(jù)都有自己的offset,消費者組中的每個消費者殿如,實時記錄自己消費到那個offset了贡珊,以便出現(xiàn)錯誤時涉馁,恢復到上次消費的位置繼續(xù)消費烤送。
log文件采取了分片和索引機制妻往,防止log文件過大導致讀取性能問題讯泣;
每個partition由多個segment阅悍,partition對應的文件名是“topic名字+分區(qū)號”文件夾好渠,一個segment對應兩個文件,.index文件和.log文件(以當前文件segment的第一條消息的offset命名)节视,.index保存大量的索引信息拳锚,.log文件保存數(shù)據(jù),.index的索引value對應.log中message的物理偏移量寻行。
如offset=150霍掺,根據(jù)offset獲得對應的segment中.index文件(通過文件名字),然后獲得對應.log中message中的物理地址,最后通過物理地址獲取message抗楔。
2.4 Kafka的高效讀寫:
a.順序寫磁盤
Producer寫的時候,一直是追加到文件的末尾拦坠,這樣避免大量的磁盤尋址時間连躏。如普通的機械磁盤,順序寫能夠達到600M/s贞滨,而隨機寫只有100K/s入热。
b.零拷貝
零拷貝避免了數(shù)據(jù)讀入到應用程序空間的過程,直接由操作系統(tǒng)的kernel完成讀寫晓铆,極大地提高的效率勺良。
c.分布式并發(fā)
kafka采取分布式方式,每個topic數(shù)據(jù)可以有多個partition骄噪,每個partition在不同的broker上尚困,一個partition由一個group中的消費者消費,很大程度上提高了并行度链蕊。
3.Kafka的Producer:
3.1 Producer消息的分區(qū)選擇方式:
1)直接指定partition事甜;
2)沒有指明partition時,通過key計算hash值滔韵,然后通過partition總個數(shù)取模逻谦,得到對應的partition值;
3)沒有key時陪蜻,第一次調用時邦马,生成一個隨機整數(shù)R,然后通過partition總個數(shù)取模宴卖,得到對應的partition值滋将。以后再次調用時根據(jù)R自增。
3.2 Producer消息的可靠性保證:
Producer消息采用acks應答機制症昏,其中l(wèi)eader partition會維護一個ISR(in sync replica set耕渴,即和leader partition保持同步的follower partition集合),當ISR中的follower完成數(shù)據(jù)同步之后齿兔,follower向leader發(fā)送ack橱脸,如果leader 長時間(replica.lag.time.max.ms參數(shù)設定)未收到follower的ack應答,那么該follower會被leader踢出ISR分苇;如果leader發(fā)生故障添诉,那么會從ISR中選舉新的leader。
配置:
Kafka提供三種acks應答機制級別医寿,對數(shù)據(jù)可靠性進行保證:
1)acks=0:
producer不等待broker的ack栏赴,直接返回成功,這樣延遲最低靖秩,但是當broker還沒有寫入到磁盤時须眷,broker故障竖瘾,會導致數(shù)據(jù)丟失;
2)acks=1:
producer等待broker的ack花颗,leader partition落盤成功之后即返回ack捕传,如果follower還沒有同步完成,此時leader故障扩劝,會導致數(shù)據(jù)丟失庸论;
3)acks=-1/all:
producer等待broker的ack,leader partition和follower partition都落盤成功之后即返回ack棒呛;如果follower完成同步聂示,broker發(fā)送ack之前,broker故障簇秒,會導致數(shù)據(jù)重復鱼喉。
3.3 Exactly Once:
針對acks=-1會出現(xiàn)重復數(shù)據(jù)的問題,Kafka 0.11版本引入了冪等性趋观,即不論Producer向kafka集群發(fā)布了多少次重復數(shù)據(jù)蒲凶,kafka集群只會持久化一條數(shù)據(jù)。
Exactly Once原理:
Producer在初始化的時候回分配一個PID拆内,發(fā)往partition的消息會附帶一個Sequence Number旋圆,Broker會對<PID,Partition麸恍,SequenceNumber>做緩存灵巧,保證只會持久化一條,原理更像關系型數(shù)據(jù)的主鍵約束抹沪。
問題:
PID重啟會發(fā)生變化刻肄,不同的partition有不同的主鍵,所以冪等性無法保證跨分區(qū)會話的Exactly Once融欧。
3.4 partition中的高水位:
follower故障恢復:
當follower故障后敏弃,會被踢出ISR中,當follower恢復之后噪馏,讀取自己的舊的高水位HW麦到,將舊高水位HW之后的數(shù)據(jù)截取掉,從舊HW從leader同步數(shù)據(jù)欠肾,當follower將LEO同步到操作新HW的時候瓶颠,即該故障恢復的follower的LEO追上leader之后,該follower可以重新加入到ISR中刺桃。
leader故障恢復:
當leader partition故障之后粹淋,會從ISR中選出一個新的leader,這時候其余的follower要將各自的高水位HW之后的數(shù)據(jù)截取掉,然后從新的leader同步數(shù)據(jù)桃移。
4.Kafka的Consumer:
Consumer采取pull(拉)的方式從broker讀取數(shù)據(jù)屋匕,比push(推)更適合不同性能的consumer機器,避免consumer機器的性能故障問題借杰。
針對pull的時候过吻,沒有數(shù)據(jù)的時候,會陷入循環(huán)第步。這時候可以采用長輪詢的方式疮装,即通過設置超時時間缘琅,consumer會等待一段時間之后才返回粘都。同RocketMQ.
Consumer的分區(qū)分配策略:
即決定哪個partition由哪個consumer消費。
1.Range(默認):
...
1.RoundRobin:
...
Consumer的offset的保存:
Kafka 0.9版本之前刷袍,consumer默認將offset保存到Zookeeper中翩隧,Kafka 0.9版本開始,默認將offset保存在Kafka的內置的topic中呻纹,該topic中為__consumer_offset堆生。
Zookeeper的作用:
Kafka集群中有一個broker中會被選舉為controller,負責broker的上下線雷酪,topic的分區(qū)副本分配和leader的選舉過程淑仆。這些管理工作需要Zookeeper的輔助。
備注:Kafka 2.8已經(jīng)放棄使用Zookeeper哥力。