<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          9張圖,Kafka為什么要放棄Zookeeper

          共 4388字,需瀏覽 9分鐘

           ·

          2021-04-28 15:49

          最近,confluent社區(qū)發(fā)表了一篇文章,主要講述了Kafka未來(lái)的2.8版本將要放棄Zookeeper,這對(duì)于Kafka用戶(hù)來(lái)說(shuō),是一個(gè)重要的改進(jìn)。之前部署Kafka就必須得部署Zookeeper,而之后就只要單獨(dú)部署Kafka就行了。[1]

          1.Kafka 簡(jiǎn)介

          Apache Kafka最早是由Linkedin公司開(kāi)發(fā),后來(lái)捐獻(xiàn)給了Apack基金會(huì)。

          Kafka被官方定義為分布式流式處理平臺(tái),因?yàn)榫邆涓咄掏隆⒖沙志没⒖伤綌U(kuò)展等特性而被廣泛使用。目前Kafka具體如下功能:

          • 消息隊(duì)列,Kafka具有系統(tǒng)解耦、流量削峰、緩沖、異步通信等消息隊(duì)列的功能。
          • 分布式存儲(chǔ)系統(tǒng),Kafka可以把消息持久化,同時(shí)用多副本來(lái)實(shí)現(xiàn)故障轉(zhuǎn)移,可以作為數(shù)據(jù)存儲(chǔ)系統(tǒng)來(lái)使用。
          • 實(shí)時(shí)數(shù)據(jù)處理,Kafka提供了一些和數(shù)據(jù)處理相關(guān)的組件,比如Kafka StreamsKafka Connect,具備了實(shí)時(shí)數(shù)據(jù)的處理功能。

          下面這張圖是Kafka的消息模型:[2]

          通過(guò)上面這張圖,介紹一下Kafka中的幾個(gè)主要概念:

          • producerconsumer: 消息隊(duì)列中的生產(chǎn)者和消費(fèi)者,生產(chǎn)者將消息推送到隊(duì)列,消費(fèi)者從隊(duì)列中拉取消息。
          • consumer group,消費(fèi)者集合,這些消費(fèi)者可以并行消費(fèi)同一個(gè)topic下不同partition中的消息。
          • brokerKafka集群中的服務(wù)器叫做broker
          • topic:消息的分類(lèi)。
          • partitiontopic物理上的分組,一個(gè)topic可以有partition,每個(gè)partition中的消息會(huì)被分配一個(gè)有序的id作為offset。并且每個(gè)partition只能給某個(gè)consumer group的一個(gè)消費(fèi)者消費(fèi)。

          2.Kafka 和 Zookeeper 關(guān)系

          Kafka 架構(gòu)如下圖:從圖中可以看到,Kafka的工作需要Zookeeper的配合。那他們到底是怎么配合工作呢?

          看下面這張圖:

          2.1 注冊(cè)中心

          2.1.1 broker 注冊(cè)

          從上面的圖中可以看到,broker分布式部署,就需要一個(gè)注冊(cè)中心來(lái)進(jìn)行統(tǒng)一管理。Zookeeper用一個(gè)專(zhuān)門(mén)節(jié)點(diǎn)保存Broker服務(wù)列表,也就是 /brokers/ids

          broker在啟動(dòng)時(shí),向Zookeeper發(fā)送注冊(cè)請(qǐng)求,Zookeeper會(huì)在/brokers/ids下創(chuàng)建這個(gè)broker節(jié)點(diǎn),如/brokers/ids/[0...N],并保存brokerIP地址和端口。

          這個(gè)節(jié)點(diǎn)臨時(shí)節(jié)點(diǎn),一旦broker宕機(jī),這個(gè)臨時(shí)節(jié)點(diǎn)會(huì)被自動(dòng)刪除。

          2.1.2 topic 注冊(cè)

          Zookeeper也會(huì)為topic分配一個(gè)單獨(dú)節(jié)點(diǎn),每個(gè)topic都會(huì)以/brokers/topics/[topic_name]的形式記錄在Zookeeper

          一個(gè)topic的消息會(huì)被保存到多個(gè)partition,這些partitionbroker的對(duì)應(yīng)關(guān)系也需要保存到Zookeeper

          partition是多副本保存的,上圖中紅色partitionleader副本。當(dāng)leader副本所在的 broker 發(fā)生故障時(shí),partition需要重新選舉leader,這個(gè)需要由Zookeeper類(lèi)主導(dǎo)完成。

          broker啟動(dòng)后,會(huì)把自己的Broker ID注冊(cè)到到對(duì)應(yīng)topic節(jié)點(diǎn)的分區(qū)列表中。

          我們查看一個(gè)topicxxx,分區(qū)編號(hào)是1的信息,命令如下:

          [root@master] get /brokers/topics/xxx/partitions/1/state
          {"controller_epoch":15,"leader":11,"version":1,"leader_epoch":2,"isr":[11,12,13]}

          當(dāng)broker退出后,Zookeeper會(huì)更新其對(duì)應(yīng)topic的分區(qū)列表。

          2.1.3 consumer 注冊(cè)

          消費(fèi)者組也會(huì)向Zookeeper進(jìn)行注冊(cè),Zookeeper會(huì)為其分配節(jié)點(diǎn)來(lái)保存相關(guān)數(shù)據(jù),節(jié)點(diǎn)路徑為/consumers/{group_id},有3個(gè)子節(jié)點(diǎn),如下圖:這樣Zookeeper可以記錄分區(qū)跟消費(fèi)者的關(guān)系,以及分區(qū)的offset

          [3]

          2.2 負(fù)載均衡

          brokerZookeeper進(jìn)行注冊(cè)后,生產(chǎn)者根據(jù)broker節(jié)點(diǎn)來(lái)感知broker服務(wù)列表變化,這樣可以實(shí)現(xiàn)動(dòng)態(tài)負(fù)載均衡。

          consumer group中的消費(fèi)者,可以根據(jù)topic節(jié)點(diǎn)信息來(lái)拉取特定分區(qū)的消息,實(shí)現(xiàn)負(fù)載均衡。

          實(shí)際上,KafkaZookeeper中保存的元數(shù)據(jù)非常多,看下面這張圖:隨著 broker、topic 和 partition 增多,保存的數(shù)據(jù)量會(huì)越來(lái)越大。

          3.Controller 介紹

          經(jīng)過(guò)上一節(jié)的講述,我們看到了Kafka對(duì)Zookeeper的依賴(lài)非常大,Kafka離開(kāi)Zookeeper是沒(méi)有辦法獨(dú)立運(yùn)行的。那Kafka是怎么跟Zookeeper進(jìn)行交互的呢?

          如下圖:[4]Kafka集群中會(huì)有一個(gè)broker被選舉為Controller負(fù)責(zé)跟Zookeeper進(jìn)行交互,它負(fù)責(zé)管理整個(gè)Kafka集群中所有分區(qū)和副本的狀態(tài)。其他broker監(jiān)聽(tīng)Controller節(jié)點(diǎn)的數(shù)據(jù)變化。

          Controller的選舉工作依賴(lài)于Zookeeper,選舉成功后,Zookeeper會(huì)創(chuàng)建一個(gè)/controller臨時(shí)節(jié)點(diǎn)。

          Controller具體職責(zé)如下:

          • 監(jiān)聽(tīng)分區(qū)變化

            比如當(dāng)某個(gè)分區(qū)的 leader 出現(xiàn)故障時(shí),Controller 會(huì)為該分區(qū)選舉新的 leader。當(dāng)檢測(cè)到分區(qū)的 ISR 集合發(fā)生變化時(shí),Controller 會(huì)通知所有 broker 更新元數(shù)據(jù)。當(dāng)某個(gè) topic 增加分區(qū)時(shí),Controller 會(huì)負(fù)責(zé)重新分配分區(qū)。

          • 監(jiān)聽(tīng)topic相關(guān)的變化
          • 監(jiān)聽(tīng)broker相關(guān)的變化
          • 集群元數(shù)據(jù)管理

          下面這張圖展示了 Controller、Zookeeper 和 broker 的交互細(xì)節(jié):Controller選舉成功后,會(huì)從Zookeeper集群中拉取一份完整的元數(shù)據(jù)初始化ControllerContext,這些元數(shù)據(jù)緩存在Controller節(jié)點(diǎn)。當(dāng)集群發(fā)生變化時(shí),比如增加topic分區(qū),Controller不僅需要變更本地的緩存數(shù)據(jù),還需要將這些變更信息同步到其他Broker

          Controller監(jiān)聽(tīng)到Zookeeper事件、定時(shí)任務(wù)事件和其他事件后,將這些事件按照先后順序暫存到LinkedBlockingQueue中,由事件處理線程按順序處理,這些處理多數(shù)需要跟Zookeeper交互,Controller則需要更新自己的元數(shù)據(jù)。

          4.Zookeeper 帶來(lái)的問(wèn)題

          Kafka本身就是一個(gè)分布式系統(tǒng),但是需要另一個(gè)分布式系統(tǒng)來(lái)管理,復(fù)雜性無(wú)疑增加了。

          4.1.1 運(yùn)維復(fù)雜度

          使用了Zookeeper,部署Kafka的時(shí)候必須要部署兩套系統(tǒng),Kafka的運(yùn)維人員必須要具備Zookeeper的運(yùn)維能力。

          4.1.2 Controller 故障處理

          Kafaka依賴(lài)一個(gè)單一Controller節(jié)點(diǎn)跟Zookeeper進(jìn)行交互,如果這個(gè)Controller節(jié)點(diǎn)發(fā)生了故障,就需要從broker中選擇新的Controller。如下圖,新的Controller變成了Broker3

          新的Controller選舉成功后,會(huì)重新從Zookeeper拉取元數(shù)據(jù)進(jìn)行初始化,并且需要通知其他所有的broker更新ActiveControllerId。老的Controller需要關(guān)閉監(jiān)聽(tīng)、事件處理線程和定時(shí)任務(wù)。分區(qū)數(shù)非常多時(shí),這個(gè)過(guò)程非常耗時(shí),而且這個(gè)過(guò)程中Kafka集群是不能工作的。

          4.1.3 分區(qū)瓶頸

          當(dāng)分區(qū)數(shù)增加時(shí),Zookeeper保存的元數(shù)據(jù)變多,Zookeeper集群壓力變大,達(dá)到一定級(jí)別后,監(jiān)聽(tīng)延遲增加,給Kafaka的工作帶來(lái)了影響。

          所以,Kafka單集群承載的分區(qū)數(shù)量是一個(gè)瓶頸。而這又恰恰是一些業(yè)務(wù)場(chǎng)景需要的。

          5.升級(jí)

          升級(jí)前后的架構(gòu)圖對(duì)比如下:

          KIP-500Quorum Controller代替之前的ControllerQuorum中每個(gè)Controller節(jié)點(diǎn)都會(huì)保存所有元數(shù)據(jù),通過(guò)KRaft協(xié)議保證副本的一致性。這樣即使Quorum Controller節(jié)點(diǎn)出故障了,新的Controller遷移也會(huì)非常快。

          官方介紹,升級(jí)之后,Kafka可以輕松支持百萬(wàn)級(jí)別的分區(qū)。

          Kafak 團(tuán)隊(duì)把通過(guò) Raft 協(xié)議同步數(shù)據(jù)的方式 Kafka Raft Metadata mode,簡(jiǎn)稱(chēng) KRaft

          Kafka的用戶(hù)體量非常大,在不停服的情況下升級(jí)是必要的。

          目前 Kafka2.8 版本已經(jīng)在 4 月 19 號(hào)發(fā)布。Kafaka計(jì)劃在3.0版本會(huì)兼容Zookeeper ControllerQuorum Controller,這樣用戶(hù)可以進(jìn)行灰度測(cè)試。[5]

          6.總結(jié)

          在大規(guī)模集群和云原生的背景下,使用ZookeeperKafka的運(yùn)維和集群性能造成了很大的壓力。去除Zookeeper的必然趨勢(shì),這也符合大道至簡(jiǎn)的架構(gòu)思想。

          參考資料

          [1]

          參考1: https://www.confluent.io/blog/kafka-without-zookeeper-a-sneak-peek/

          [2]

          參考2: https://blog.csdn.net/Zidingyi_367/article/details/110490910

          [3]

          參考3: https://www.jianshu.com/p/a036405f989c

          [4]

          參考4: https://honeypps.com/mq/kafka-controller-analysis/

          [5]

          參考5: https://mp.weixin.qq.com/s/ev6NM6hptltQBuTaCHJCQQ


          < END >

          推薦?? :1049天,100K!簡(jiǎn)單復(fù)盤(pán)!

          推薦?? :年薪 40W Java 開(kāi)發(fā)是什么水平?

          推薦?? :Github掘金計(jì)劃:Github上的一些優(yōu)質(zhì)項(xiàng)目搜羅

          我是 Guide哥,擁抱開(kāi)源,喜歡烹飪。Github 接近 10w 點(diǎn)贊的開(kāi)源項(xiàng)目 JavaGuide 的作者。未來(lái)幾年,希望持續(xù)完善 JavaGuide,爭(zhēng)取能夠幫助更多學(xué)習(xí) Java 的小伙伴!共勉!凎!點(diǎn)擊查看我的2020年工作匯報(bào)!
          原創(chuàng)不易,歡迎點(diǎn)贊分享。咱們下期再會(huì)!
          瀏覽 51
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  三级久久| 国产99久久九九精品无码免费 | 囯产精品久久久久久久免牛肉蒲团 | 2023午夜福利 | 国产一级二级三级片 |