Kafka是一個分布式消息隊列矿卑,為處理實時數(shù)據(jù)提供一個統(tǒng)一柬焕、高吞吐量、低等待的平臺麻掸,提供了類似于JMS的特性酥夭,但是它并不是JMS規(guī)范的實現(xiàn).
JMS消息傳輸模型
1.點對點模式
2.發(fā)布/訂閱模式(類似于kafka)
生產(chǎn)者消費者模式:Producer->Topic->consumer
ps:消費者組(Consumer Group)才是邏輯上的訂閱者
無論是kafka集群,還是producer和consumer都依賴于zookeeper集群保存一些meta信息。
Kafka文件存儲結(jié)構(gòu):
一臺Kafka服務(wù)器就是一個broker熬北,一個broker中有若干個topic千所,每個topic中有若干partition,所有partition中都有segment分段蒜埋,每個segment都包含兩個文件:index文件和log文件该贾。
broker->topic->partition->segment->index+log
Kafka解決了傳統(tǒng)MQ(MessageQueue)的問題别凤,有別于傳統(tǒng)MQ的新特征:
- 異步處理
- 消峰
- 解耦
一、kafka的partition管理
- kafka提供高可用,每個partition有若干副本低剔,存放在不同節(jié)點上,也就是不同broker上向臀。
- 為了方便管理工三,kafka提供了副本選舉機制,由leader同步數(shù)據(jù)到所有follower讲冠。
- kafka還提供了partition出錯恢復(fù)機制瓜客,包括leader出錯以及follower出錯兩種情況,
當(dāng)leader出錯之后竿开,kafka會重新選擇序列號最小的follower作為新的leader谱仪,然后將其他follower中HW之后的數(shù)據(jù)整合到新的leader中。
當(dāng)follower出錯之后否彩,由leader恢復(fù)HW之前的數(shù)據(jù)疯攒,HW之后的數(shù)據(jù)丟失,然后同步數(shù)據(jù)直到達(dá)到leader的LEO列荔,添加到ISR中敬尺。
HW(High Water):leader中的HW是所有副本中最小的LEO,代表所有partition同步完成的數(shù)據(jù)量
LEO(Log End Offset):每個副本最后一個offset的位置
二、ACK應(yīng)答機制
producer會向leader發(fā)送數(shù)據(jù)贴浙,leader接收數(shù)據(jù)之后需要返回一個信息確認(rèn)信息砂吞,這個確認(rèn)信息就是ack。
1.ack=0
leader收到信息之后崎溃,在落地磁盤之前蜻直,就返回ack。
這種方式延遲會降低笨奠,但是出現(xiàn)異常狀態(tài)袭蝗,容易丟失數(shù)據(jù)。
2.ack=1
leader收到信息之后般婆,將數(shù)據(jù)落地磁盤到腥,之后返回ack。
在未同步完數(shù)據(jù)之前就返回ack蔚袍,如果leader出錯乡范,副本數(shù)據(jù)會丟失配名。
3.ack=all
leader收到信息之后,將數(shù)據(jù)落地磁盤晋辆,數(shù)據(jù)同步到所有副本中渠脉,最后返回ack。
這種方式雖然數(shù)據(jù)不容易丟失瓶佳,但也存在數(shù)據(jù)重復(fù)的可能性芋膘,假如leader同步完數(shù)據(jù)之后,在發(fā)送ack之前出錯霸饲,follower中會選舉出新的leader为朋,同時producer接收不到ack,會重新發(fā)送數(shù)據(jù)到新的leader厚脉,新的leader就有了兩份一摸一樣的數(shù)據(jù)习寸。
三、ISR數(shù)據(jù)同步機制
ISR相當(dāng)于一個數(shù)組列表傻工,里面包含所有follower以及l(fā)eader自身霞溪,初始狀態(tài)所有的副本都處于ISR中,當(dāng)一個消息發(fā)送給leader的時候中捆,leader會等待ISR中所有的副本告訴它已經(jīng)接收了這個消息鸯匹,如果一個副本失敗了,那么它會被移除ISR轨香。下一條消息來的時候忽你,leader就會將消息發(fā)送給當(dāng)前的ISR中節(jié)點了。
四臂容、kafka消息快速存儲的底層實現(xiàn)
讀寫磁盤
不同于Redis和傳統(tǒng)MQ等內(nèi)存消息隊列,Kafka的設(shè)計是把所有的Message都要寫入速度低容量大的硬盤根蟹,以此來換取更強的存儲能力脓杉,事實上這種設(shè)計并沒有帶來更多的性能損耗。
順序讀寫
kafka在磁盤上只做順序讀寫简逮,順序讀寫的效率要比隨機讀寫高很多球散,因為只做順序讀寫,所有規(guī)避了磁盤訪問速度低下對性能可能造成的影響散庶。
PageCache
Kafka依賴底層操作系統(tǒng)提供的PageCache功能蕉堰,當(dāng)讀操作發(fā)生時,先從PageCache中查找悲龟,如果發(fā)生缺頁才進(jìn)行磁盤調(diào)度屋讶,最終返回需要的數(shù)據(jù)。使用PageCache功能同時可以避免在JVM內(nèi)部緩存數(shù)據(jù)须教,不受GC的控制皿渗。
Sendfile
Kafka為了進(jìn)一步的優(yōu)化性能還采用了Sendfile技術(shù),簡化了傳統(tǒng)網(wǎng)絡(luò)I/O操作斩芭。
五、如何消費已經(jīng)消費過的數(shù)據(jù)
我們知道offset記錄consumer group消費的信息乐疆,一般情況下消費者組不能直接消費已經(jīng)消費過的數(shù)據(jù)划乖。我們可以采取以下兩種方式間接消費相同的數(shù)據(jù)。
1.我們可以將消費者移到新的消費者組中去消費挤土,在consumer掛掉或者新增consumer的情況下會觸發(fā)kafka負(fù)載均衡重新分配所有consumer琴庵,形成新的消費者組。
2.通過一些配置仰美,就可以將線上產(chǎn)生的數(shù)據(jù)同步到鏡像中去迷殿,然后再由特定的集群區(qū)處理大批量的數(shù)據(jù)。
六筒占、消費者組和分區(qū)的關(guān)系
消費者組訂閱主題贪庙,主題下的所有分區(qū)都被消費『采唬基于此止邮,消費者組和分區(qū)關(guān)系如下:
- 分區(qū)數(shù)=消費者數(shù),一個消費者分區(qū)的關(guān)系一一對應(yīng)奏窑。
- 分區(qū)數(shù)>消費者數(shù)导披,出現(xiàn)一個消費者消費多個分區(qū)。
- 分區(qū)數(shù)<消費者數(shù)埃唯,出現(xiàn)有的消費者空閑的情況撩匕。
如果多個消費者負(fù)責(zé)一個分區(qū)會導(dǎo)致資源浪費,消息處理重復(fù)墨叛,不能保證消息的順序的問題止毕。
七、zookeeper在kafka中的作用
- 配置管理
- 負(fù)載均衡
- 命名服務(wù)
- 分布式通知(分區(qū)增加漠趁,topic變動扁凛,Broker上線下線等)
- 集群管理和master選舉
- 分布式鎖(用于Controller的選舉)