1 kafka consumer消費位移為什么從zookeeper改到kafka內(nèi)部主題__consumer_offsets中?
kafka 0.9版本之前使用zookeeper保存offset案疲,之后版本使用內(nèi)部主題猫缭,網(wǎng)上有一個答案是kafka offset維護方式
主要的點是zookeeper引入了多余的網(wǎng)絡通訊,broker需要多余的連接來訪問offset举塔,存儲在broker端绑警,可以減少該部分的IO損耗,簡化設計
2 kafka是如何使用isr的央渣?
kafka通過isr機制來維持數(shù)據(jù)的一致性计盒,isr即in-sync replica,跟isr相關的參數(shù)有acks芽丹、min.insync.replicas北启、replica.lag.time.max.ms、replica.lag.max.messages(已移除)
isr由leader動態(tài)維護拔第,當副本節(jié)點落后leader太多或者超時未請求同步時暖庄,將副本剔除isr集合,待副本同步后楼肪,會重新加入isr集合
acks:由客戶端配置培廓,表示多少個副本收到消息后,才認為消息寫入成功春叫,0相當于異步肩钠,all,相當于同步暂殖,生產(chǎn)環(huán)境中需要兼顧可用性和性能价匠,一般配置acks=1
min.insync.replicas:控制消息成功寫入最小副本數(shù)
replica.lag.max.messages(已移除):isr集合中副本落后leader的最大值,因為生產(chǎn)環(huán)境中很難定義這個閾值呛每,0.9版本后移除了該參數(shù)
replica.lag.time.max.ms:isr集合中副本落后leader的最大時間間隔
3 kafka如何實現(xiàn)exactly-once語義踩窖?
exactly-once解釋,即使生產(chǎn)者產(chǎn)生重復的消息晨横,消費者也應該只收到一次消息洋腮,這也就是所謂的冪等
配置冪等通過配置enable.idempotence=true實現(xiàn)
實現(xiàn):producer消息是分批發(fā)送,每個分批都有一個序號(單調(diào)遞增)手形,broker追蹤分區(qū)的最大序號啥供,當出現(xiàn)序號相等或者小于最大序號的,不寫入topic
4 kafka使用isr來選主库糠,具體選主流程是什么樣的伙狐,是另外一個raft嗎?還是有其他約束?
答:
1贷屎、大數(shù)據(jù)常用的選主機制
leader的選擇方法非常多罢防,大數(shù)據(jù)領域常用的的選舉方法有如下集中
(1)Zab(zookeeper使用)
a、快速leader選舉(leader election)
b唉侄、發(fā)現(xiàn)或者版本建立(epoch establish)
c咒吐、同步(follower從leader同步數(shù)據(jù)和狀態(tài))
d、廣播(leader廣播數(shù)據(jù)或狀態(tài)到follower)
例如有3個節(jié)點需要選舉leader美旧,編號為1,2贬墩,3. 先啟動1榴嗅,選擇自己為leader,然后啟動2陶舞,首先也選擇自己為leader嗽测。由于1,2都沒有過半肿孵,選擇編號大的為leader唠粥,所以1,2都選擇2為leader停做。然后3啟動后發(fā)現(xiàn)1晤愧,2都已經(jīng)協(xié)商好且數(shù)量過半,于是3也選擇2為leader蛉腌,此時leader選擇結(jié)束官份。
因為zab協(xié)議需要選擇過半以上才能被選舉為leader,所以zab協(xié)議需要奇數(shù)個機器參與選舉(1烙丛,3舅巷,5,7一般不超過7個河咽,因為zk一般同步元數(shù)據(jù)钠右,所以負載不是很高,zk管理的節(jié)點通信負載才比較高忘蟹,5或7個一般能處理大量的集群)飒房,一般為第二個節(jié)點啟動后被選擇為leader。
zookeeper進行選舉時媚值,有兩個典型場景
1 啟動時leader選舉
2 運行過程中l(wèi)eader選舉
(2)Raft協(xié)議
相關角色說明
leader:處理所有客戶端交互情屹,日志復制等,一般只有一個leader
Follower:類似選民杂腰,完全被動
Candidate:候選人垃你,可以為選為一個新的領導,由管理員配置
啟動時在集群中指定一些機器為candidate,然后candidate開始向其他機器(尤其是follower)拉票惜颇,當某一個candidate的票數(shù)超過半數(shù)皆刺,它就成為leader(同美國總統(tǒng)選舉)。
兩種選擇算法的區(qū)別聯(lián)系
(1)他們都是Paxos算法的變種凌摄。
(2)與zab協(xié)議不同的是羡蛾,zab的每一個節(jié)點都有被選為leader的協(xié)議,raft協(xié)議必須從候選人中選擇為leader锨亏。
2痴怨、常用選主機制的缺點
最簡單的方式
由于kafka集群依賴zookeeper集群,所以最簡單直觀的方案是:所有的follower都在zookeeper上設置一個watch器予,一旦leader宕機浪藻,其對應的ephemeral znode(臨時節(jié)點)會自動刪除,此時所有follower都嘗試創(chuàng)建該節(jié)點乾翔,而創(chuàng)建成功者(zookeeper保證只有一個能創(chuàng)建成功)即是新的leader爱葵,其他replica即為follower。
該方式有如下缺點:
a反浓、腦裂(split-brain)
這是由于zookeeper的特性引起的萌丈,雖然zookeeper能保證所有的watch按順序觸發(fā),但并不能保證同一時刻所有的replica看到的狀態(tài)是一樣的雷则,這就可能造成不同的replica的響應不一致辆雾;(如由于網(wǎng)絡原因部分選擇的leader已經(jīng)更新,但是其他follower由于網(wǎng)絡原因沒有看到月劈,部分又選舉出一個leader乾颁,導致一個集群出現(xiàn)兩個leader)
b、羊(驚)群效應(herd effect)
如果宕機的哪個broker上的partition比較多艺栈,會造成多個watch被觸發(fā)英岭,造成集群類大量的調(diào)整(向羊群開一槍所有羊群四處奔散,造成網(wǎng)路資源和負載)湿右。
c诅妹、zookeeper負載過重:每一個replica都要為此在zookeeper上注冊一個watch,當集群規(guī)模增加到幾千個partition時毅人,zookeeper負載會過重吭狡。
3、kafka分區(qū)的選主機制
kafka如何解決以上選舉機制的
kafka的leader election方案解決了上述問題丈莺,它在所有的broker中選出一個controller划煮,所有的partition的leader選舉都有controller決定。controller會將leader的改變直接通過RPC的方式(比zookeeper Queue的方式更高效)通知需要為此作為響應的broker缔俄。
原因:
1弛秋、不用zk選舉器躏,使用controller(Controller會將leader的改變通過rpc方式通知給follower),沒有zk負載過重問題
2蟹略、也沒有注冊watch不會觸發(fā)任何事件-驚群效應
3登失、leader失敗是由一個Controller進行選舉并不會產(chǎn)生任何通信,所以不會有腦裂的情況
問題:
(1)Controller是如何選舉出來的
每一個broker都會在Controller path(/controller)上注冊一個watch挖炬。當前controller失敗時揽浙,對應的Controller path會自動消失(臨時節(jié)點)。此時該watch被觸發(fā)意敛,所有活著的broker都會去競選成為新的Controller(創(chuàng)建新的controller path)馅巷,但是只有一個會競選成功。競選成功者成為新的leader草姻。競選失敗則重新在新的Controller path上注冊watch钓猬,因為zk的watch是一次性的,被觸發(fā)一次之后即失效碴倾,所以需要重新注冊逗噩。
(2)如何使用Controller進行partition選舉
a掉丽、從zk中讀取當前分區(qū)的所有ISR(in-sync-replicas)集合
b跌榔、調(diào)用配置的分區(qū)算法選擇分區(qū)的leader
kafka選擇分區(qū)算法:
i、NoOpLeaderSelector–偏愛分區(qū)(SR中的第一個)捶障,并將leader發(fā)送給為此做出改變的broker僧须,
ii、offlinePartitionLeader–也是選擇偏愛分區(qū)作為leader
iii项炼、reassignedPartitionLeader
iii担平、preferredReplicaPartitionLeader
iiii、ControlledShutdownLeader
上面五中算法都使用偏愛分區(qū)作為leader锭部,區(qū)別是選擇leader之后所做的操作不同暂论。