上一篇說了Kafka consumer的處理邏輯脓恕、實現(xiàn)原理及相關(guān)的特點,本篇來看看Kafka 另一個client Consumer葵腹,作為生產(chǎn)者消費者的另一端垮庐,consumer提供了消費消息的能力,下面來看看Kafka中的consumer 應(yīng)該如何正確使用及實現(xiàn)原理首繁。
發(fā)布訂閱&生產(chǎn)者消費者模式
常見的消息引擎中通常有 經(jīng)典的生產(chǎn)者消費者模式作郭、發(fā)布訂閱模式 兩種
生產(chǎn)者 消費者模式
是一種點對點的方式,消息不會被重復消費弦疮,可以粗暴的理解為消息被消費后就被標記刪除或者已刪除了夹攒,這是常見的消息隊列通常的模式。比如說進程間通信胁塞,這種基于隊列實現(xiàn)消息傳輸服務(wù)的咏尝。
發(fā)布訂閱
相對于生產(chǎn)者 消費者模式,消息可能會被多方消費啸罢,可以簡單的理解為一份報紙的內(nèi)容编检,訂閱它的人都可以讀到它,當一個人讀完之后也就沒必要再次去讀了扰才。并且在發(fā)布訂閱模式中允懂,通常有個概念叫做topic,每個topic 有對應(yīng)的發(fā)布者(publisher)衩匣、訂閱者(subsciber)蕾总。
那Kafka是如何實現(xiàn)生產(chǎn)者消費者兩種模式的呢?往后看~
消費者 & 消費者組
kafka中有一個概念叫做consumer group琅捏,每個group 去訂閱對應(yīng)的topic生百,topic的每條消息只能發(fā)送到訂閱它的消費者組的其中一個實例上,并且每個消費者至多使用一個消費者組來標示自己午绳。這樣不難得出置侍,當某個topic 僅有一個group來消費時(組內(nèi)有一個或者多個consumer),這個topic的消息的消費模式就是典型的生產(chǎn)者消費者模式。
而當某個topic 被多個消費者組訂閱蜡坊,而每個組僅有一個消費者時杠输,每條消息就會被廣播到每個消費者上。
這里需要注意下秕衙,還有個叫做獨立消費者(standalone consumer)的概念蠢甲,對于consumer group 是以group 為單位進行消息消費的,而standalone 會單獨的執(zhí)行消費据忘,以consumer 實例為單位進行消費的鹦牛。
group 狀態(tài)機 & group管理協(xié)議
是時候來看看Kafka consumer 端的實現(xiàn)原理了,先從最基礎(chǔ)的group 開始勇吊,當前較新版本的consumer是依賴于broker端的coordinator來完成組的管理的(主要是把分配方案通知到每個consumer實例上)曼追,當然了這里涉及一個一致性策略,當無法達成這個策略是汉规,就直接拋異常請求人工介入處理了礼殊。
coordinator 實現(xiàn)組的管理,依賴的主要是consumer group的狀態(tài)针史,僅有 Empty(組內(nèi)沒有任何active consumer)晶伦、PreparingRebalance(group 正在準備進行rebalance)、AwaitingSync(所有組員已經(jīng)加入組并等待leader consumer發(fā)送分區(qū)的分配方案)啄枕、Stable(group開始正常消費)婚陪、Dead(該group 已經(jīng)被廢棄)這五個狀態(tài),那他們是如何輪轉(zhuǎn)的可以簡單的看一下狀態(tài)機频祝。
就整個過程來說泌参,可以大致分為加入組階段、狀態(tài)同步階段智润。
加入組階段:當明確group的coordinator之后及舍,組內(nèi)成員需要顯式的發(fā)送JoinGroup請求(主要包括 訂閱信息未辆、成員id等元數(shù)據(jù)信息)給對應(yīng)的coordinator窟绷,然后coordinator選擇對應(yīng)的consumer 作為leader,然后再給其他成員產(chǎn)生響應(yīng)(一個空數(shù)組)咐柜。當然啦兼蜈,如果某個consumer 指定的分配策略是其他consumer 不支持的,那么這個實例是不被接受的∽居眩現(xiàn)有的分區(qū)策略主要有:range为狸、round-robin、sticky遗契,其中sticky是其中可以最大限度保證分區(qū)的負載的均衡分配機rebalance之后的最少分配變動辐棒。
offset & broker 中的offset
offset 概念這里需要單獨抽出來說一下,因為在Kafka 里面存在兩個offset的概念,一個指的是consumer 中的offset漾根,一個是broker中的offset
concumer offset 用來記錄當前消費了多少條消息泰涂,這個offset的狀態(tài)是由consumer group來維護的,通過檢查點機制對于offset的值進行持久化(內(nèi)部就是一個map)
broker offset 消息在broker 端的位移值辐怕,根據(jù)之前說過的幾個概念可以大致的理解為一個<topic逼蒙,partition,offset>可以唯一的標示到一條消息寄疏。
_consumer_offset topic & zookeeper 位移管理
因為新版本和舊版本Kafka 所采用的offset保存策略是不同的是牢,舊版本中主要依賴于Zookeeper,但是zookeeper不是干這事兒的啊陕截,所以kafka 在數(shù)量很大的消費發(fā)生時驳棱,zookeeper讀寫會異常的頻繁,導致很容易成為整個Kafka系統(tǒng)的瓶頸农曲。所以新版本對這種方式作出了重大更新蹈胡,不再依賴于Zookeeper 來進行狀態(tài)的保存,而是在broker 端直接開一個內(nèi)部使用的topic朋蔫,也就是_consumer_offsets topic罚渐,并且kafka 為了兼容老版本的consumer 還提供了 offsets.storage=kafka這樣一個適配參數(shù)。
Rebalance & 場景剖析
最后要說的一點就是consumer 端的Rebalance 過程(rebalance是針對consumer group來說的驯妄,如果是standalone consumer 則沒有這個概念)荷并,rebalance也就是如何達成一致來分配訂閱topic的所有分區(qū)。這個rebalance的代價還是不小的青扔,我們是需要避免高頻的rebalance的源织。常見的rebalance 場景有:新成員加入組、組內(nèi)成員崩潰(這種場景無法主動通知微猖,需要被動的檢測才行谈息,并且需要一個session.timeout 才檢測到)、成員主動離組凛剥。
consumer 是可以執(zhí)行任意次rebalance的侠仇,為了區(qū)分兩次rebalance上的數(shù)據(jù)(防止無效或者延遲的offset提交),consumer 設(shè)計了一個叫做rebalance generation的標示犁珠。
對應(yīng)常見的rebalance請求有:
JoinGroup:consumer 請求加入組
SyncGroup:group leader把分配方案同步給組內(nèi)所有成員
Heartbeat:consumer 定期向coordination匯報心跳表示自己還存活
LeaveGroup:consumer 主動通知coordinator該consumer即將離組
DescribeGroup:查看組的所有信息逻炊。
Consumer端常見的概念大致就這么多。