0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

探究Kafka宕機(jī)引發(fā)的高可用問題

馬哥Linux運(yùn)維 ? 來源:掘金 ? 作者:JanusWoo ? 2021-10-20 15:41 ? 次閱讀

一、Kafka宕機(jī)引發(fā)的高可用問題

問題要從一次Kafka的宕機(jī)開始說起。

筆者所在的是一家金融科技公司,但公司內(nèi)部并沒有采用在金融支付領(lǐng)域更為流行的RabbitMQ ,而是采用了設(shè)計(jì)之初就為日志處理而生的Kafka,所以我一直很好奇Kafka的高可用實(shí)現(xiàn)和保障。從Kafka部署后,系統(tǒng)內(nèi)部使用的Kafka一直運(yùn)行穩(wěn)定,沒有出現(xiàn)不可用的情況。

但最近系統(tǒng)測試人員常反饋偶有Kafka消費(fèi)者收不到消息的情況,登陸管理界面發(fā)現(xiàn)三個(gè)節(jié)點(diǎn)中有一個(gè)節(jié)點(diǎn)宕機(jī)掛掉了。但是按照高可用的理念,三個(gè)節(jié)點(diǎn)還有兩個(gè)節(jié)點(diǎn)可用怎么就引起了整個(gè)集群的消費(fèi)者都接收不到消息呢?

要解決這個(gè)問題,就要從Kafka的高可用實(shí)現(xiàn)開始講起。

二、Kafka的多副本冗余設(shè)計(jì)

不管是傳統(tǒng)的基于關(guān)系型數(shù)據(jù)庫設(shè)計(jì)的系統(tǒng),還是分布式的如ZooKeeper 、Redis 、Kafka 、HDFS等等,實(shí)現(xiàn)高可用的辦法通常是采用冗余設(shè)計(jì),通過冗余來解決節(jié)點(diǎn)宕機(jī)不可用問題。

首先簡單了解Kafka的幾個(gè)概念:

物理模型

邏輯模型

Broker (節(jié)點(diǎn)):Kafka服務(wù)節(jié)點(diǎn),簡單來說一個(gè)Broker就是一臺(tái)Kafka服務(wù)器,一個(gè)物理節(jié)點(diǎn);

Topic (主題):在Kafka中消息以主題為單位進(jìn)行歸類,每個(gè)主題都有一個(gè) Topic Name,生產(chǎn)者根據(jù)Topic Name將消息發(fā)送到特定的Topic,消費(fèi)者則同樣根據(jù)Topic Name從對(duì)應(yīng)的Topic進(jìn)行消費(fèi);

Partition (分區(qū)):Topic(主題)是消息歸類的一個(gè)單位,但每一個(gè)主題還能再細(xì)分為一個(gè)或多個(gè) Partition(分區(qū)),一個(gè)分區(qū)只能屬于一個(gè)主題。主題和分區(qū)都是邏輯上的概念,舉個(gè)例子,消息1和消息2都發(fā)送到主題1,它們可能進(jìn)入同一個(gè)分區(qū)也可能進(jìn)入不同的分區(qū)(所以同一個(gè)主題下的不同分區(qū)包含的消息是不同的),之后便會(huì)發(fā)送到分區(qū)對(duì)應(yīng)的Broker節(jié)點(diǎn)上;

Offset (偏移量):分區(qū)可以看作是一個(gè)只進(jìn)不出的隊(duì)列(Kafka只保證一個(gè)分區(qū)內(nèi)的消息是有序的),消息會(huì)往這個(gè)隊(duì)列的尾部追加,每個(gè)消息進(jìn)入分區(qū)后都會(huì)有一個(gè)偏移量,標(biāo)識(shí)該消息在該分區(qū)中的位置,消費(fèi)者要消費(fèi)該消息就是通過偏移量來識(shí)別。

其實(shí),根據(jù)上述的幾個(gè)概念,是不是也多少猜到了Kafka的多副本冗余設(shè)計(jì)實(shí)現(xiàn)了?別急,咱繼續(xù)往下看。

在Kafka 0.8版本以前,是沒有多副本冗余機(jī)制的,一旦一個(gè)節(jié)點(diǎn)掛掉,那么這個(gè)節(jié)點(diǎn)上的所有 Partition的數(shù)據(jù)就無法再被消費(fèi)。這就等于發(fā)送到Topic的有一部分?jǐn)?shù)據(jù)丟失了。

在0.8版本后引入副本記者則很好地解決宕機(jī)后數(shù)據(jù)丟失的問題。副本是以 Topic 中每個(gè) Partition的數(shù)據(jù)為單位,每個(gè)Partition的數(shù)據(jù)會(huì)同步到其他物理節(jié)點(diǎn)上,形成多個(gè)副本。

每個(gè) Partition 的副本都包括一個(gè) Leader 副本和多個(gè) Follower副本,Leader由所有的副本共同選舉得出,其他副本則都為Follower副本。在生產(chǎn)者寫或者消費(fèi)者讀的時(shí)候,都只會(huì)與Leader打交道,在寫入數(shù)據(jù)后Follower就會(huì)來拉取數(shù)據(jù)進(jìn)行數(shù)據(jù)同步。

就這么簡單?是的,基于上面這張多副本架構(gòu)圖就實(shí)現(xiàn)了Kafka的高可用。當(dāng)某個(gè) Broker 掛掉了,甭?lián)?,這個(gè)Broker上的Partition在其他Broker節(jié)點(diǎn)上還有副本。你說如果掛掉的是Leader怎么辦?那就在Follower中在選舉出一個(gè)Leader即可,生產(chǎn)者和消費(fèi)者又可以和新的Leader愉快地玩耍了,這就是高可用。

你可能還有疑問,那要多少個(gè)副本才算夠用?Follower和Leader之間沒有完全同步怎么辦?一個(gè)節(jié)點(diǎn)宕機(jī)后Leader的選舉規(guī)則是什么?

直接拋結(jié)論:

多少個(gè)副本才算夠用?

副本肯定越多越能保證Kafka的高可用,但越多的副本意味著網(wǎng)絡(luò)、磁盤資源的消耗更多,性能會(huì)有所下降,通常來說副本數(shù)為3即可保證高可用,極端情況下將 Replication Factor參數(shù)調(diào)大即可。

Follower和Lead之間沒有完全同步怎么辦?

Follower和Leader之間并不是完全同步,但也不是完全異步,而是采用一種 ISR機(jī)制(In-Sync Replica)。每個(gè)Leader會(huì)動(dòng)態(tài)維護(hù)一個(gè)ISR列表,該列表里存儲(chǔ)的是和Leader基本同步的Follower。如果有Follower由于網(wǎng)絡(luò)、GC等原因而沒有向Leader發(fā)起拉取數(shù)據(jù)請(qǐng)求,此時(shí)Follower相對(duì)于Leader是不同步的,則會(huì)被踢出ISR列表。所以說,ISR列表中的Follower都是跟得上Leader的副本。

一個(gè)節(jié)點(diǎn)宕機(jī)后Leader的選舉規(guī)則是什么?

分布式相關(guān)的選舉規(guī)則有很多,像ZooKeeper的Zab、Raft、Viewstamped Replication 、微軟的 PacificA 等。而Kafka的Leader選舉思路很簡單,基于我們上述提到的 ISR列表,當(dāng)宕機(jī)后會(huì)從所有副本中順序查找,如果查找到的副本在ISR列表中,則當(dāng)選為Leader。

另外還要保證前任Leader已經(jīng)是退位狀態(tài)了,否則會(huì)出現(xiàn)腦裂情況(有兩個(gè)Leader)。怎么保證?Kafka通過設(shè)置了一個(gè)Controller來保證只有一個(gè)Leader。

三、Ack參數(shù)決定了可靠程度

另外,這里補(bǔ)充一個(gè)面試考Kafka高可用必備知識(shí)點(diǎn):request.required.asks 參數(shù)。

Asks這個(gè)參數(shù)是生產(chǎn)者客戶端的重要配置,發(fā)送消息的時(shí)候就可設(shè)置這個(gè)參數(shù)。該參數(shù)有三個(gè)值可配置:0、1、All 。

第一種是設(shè)為0

意思是生產(chǎn)者把消息發(fā)送出去之后,之后這消息是死是活咱就不管了,有那么點(diǎn)發(fā)后即忘的意思,說出去的話就不負(fù)責(zé)了。不負(fù)責(zé)自然這消息就有可能丟失,那就把可用性也丟失了。

第二種是設(shè)為1

意思是生產(chǎn)者把消息發(fā)送出去之后,這消息只要順利傳達(dá)給了Leader,其他Follower有沒有同步就無所謂了。存在一種情況,Leader剛收到了消息,F(xiàn)ollower還沒來得及同步Broker就宕機(jī)了,但生產(chǎn)者已經(jīng)認(rèn)為消息發(fā)送成功了,那么此時(shí)消息就丟失了。注意,設(shè)為1是Kafka的默認(rèn)配置,可見Kafka的默認(rèn)配置也不是那么高可用,而是對(duì)高可用和高吞吐量做了權(quán)衡折中。

第三種是設(shè)為All(或者-1)

意思是生產(chǎn)者把消息發(fā)送出去之后,不僅Leader要接收到,ISR列表中的Follower也要同步到,生產(chǎn)者才會(huì)任務(wù)消息發(fā)送成功。

進(jìn)一步思考, Asks=All 就不會(huì)出現(xiàn)丟失消息的情況嗎?答案是否。當(dāng)ISR列表只剩Leader的情況下, Asks=All 相當(dāng)于 Asks=1 ,這種情況下如果節(jié)點(diǎn)宕機(jī)了,還能保證數(shù)據(jù)不丟失嗎?因此只有在 Asks=All并且有ISR中有兩個(gè)副本的情況下才能保證數(shù)據(jù)不丟失。

四、解決問題

繞了一大圈,了解了Kafka的高可用機(jī)制,終于回到我們一開始的問題本身,Kafka 的一個(gè)節(jié)點(diǎn)宕機(jī)后為什么不可用?

我在開發(fā)測試環(huán)境配置的 Broker 節(jié)點(diǎn)數(shù)是3,Topic 是副本數(shù)為3,Partition數(shù)為6,Asks參數(shù)為1。

當(dāng)三個(gè)節(jié)點(diǎn)中某個(gè)節(jié)點(diǎn)宕機(jī)后,集群首先會(huì)怎么做?沒錯(cuò),正如我們上面所說的,集群發(fā)現(xiàn)有Partition的Leader失效了,這個(gè)時(shí)候就要從ISR列表中重新選舉Leader。如果ISR列表為空是不是就不可用了?并不會(huì),而是從Partition存活的副本中選擇一個(gè)作為Leader,不過這就有潛在的數(shù)據(jù)丟失的隱患了。

所以,只要將Topic副本個(gè)數(shù)設(shè)置為和Broker個(gè)數(shù)一樣,Kafka的多副本冗余設(shè)計(jì)是可以保證高可用的,不會(huì)出現(xiàn)一宕機(jī)就不可用的情況(不過需要注意的是Kafka有一個(gè)保護(hù)策略,當(dāng)一半以上的節(jié)點(diǎn)不可用時(shí)Kafka就會(huì)停止)。那仔細(xì)一想,Kafka上是不是有副本個(gè)數(shù)為1的Topic?

問題出在了 consumer_offset 上, consumer_offset 是一個(gè)Kafka自動(dòng)創(chuàng)建的 Topic,用來存儲(chǔ)消費(fèi)者消費(fèi)的 offset (偏移量)信息,默認(rèn) Partition數(shù)為50。而就是這個(gè)Topic,它的默認(rèn)副本數(shù)為1。如果所有的 Partition 都存在于同一臺(tái)機(jī)器上,那就是很明顯的單點(diǎn)故障了!當(dāng)將存儲(chǔ) __consumer_offset 的Partition的Broker給Kill后,會(huì)發(fā)現(xiàn)所有的消費(fèi)者都停止消費(fèi)了。

這個(gè)問題怎么解決?

需要將 __consumer_offset 刪除,注意這個(gè)Topic時(shí)Kafka內(nèi)置的Topic,無法用命令刪除,我是通過將 logs 刪了來實(shí)現(xiàn)刪除。

需要通過設(shè)置 offsets.topic.replication.factor 為3來將 __consumer_offset 的副本數(shù)改為3。

通過將 __consumer_offset 也做副本冗余后來解決某個(gè)節(jié)點(diǎn)宕機(jī)后消費(fèi)者的消費(fèi)問題。

最后,關(guān)于為什么 __consumer_offset的Partition會(huì)出現(xiàn)只存儲(chǔ)在一個(gè)Broker上而不是分布在各個(gè)Broker上感到困惑,如果有朋友了解的煩請(qǐng)指教~

作者:JanusWoo

來源:https://juejin.im/post/6874957625998606344

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • HDFS
    +關(guān)注

    關(guān)注

    1

    文章

    30

    瀏覽量

    9537
  • kafka
    +關(guān)注

    關(guān)注

    0

    文章

    49

    瀏覽量

    5195

原文標(biāo)題:從一次 Kafka 節(jié)點(diǎn)宕機(jī)探究 Kafka 的高可用實(shí)現(xiàn)

文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    華為云 FunctionGraph 構(gòu)建可用系統(tǒng)的實(shí)踐

    ,詳細(xì)介紹如何構(gòu)建可用的 Serverless 計(jì)算平臺(tái),實(shí)現(xiàn)客戶和平臺(tái)雙贏。 可用介紹 可用
    的頭像 發(fā)表于 05-09 23:14 ?329次閱讀
    華為云 FunctionGraph 構(gòu)建<b class='flag-5'>高</b><b class='flag-5'>可用</b>系統(tǒng)的實(shí)踐

    面試官:Kafka會(huì)丟消息嗎?

    許多開發(fā)人員普遍認(rèn)為,Kafka 的設(shè)計(jì)本身就能保證不會(huì)丟失消息。然而,Kafka 架構(gòu)和配置的細(xì)微差別會(huì)導(dǎo)致消息的丟失。我們需要了解它如何以及何時(shí)可能丟失消息,并防止此類情況的發(fā)生。
    的頭像 發(fā)表于 04-29 17:32 ?827次閱讀
    面試官:<b class='flag-5'>Kafka</b>會(huì)丟消息嗎?

    華為云網(wǎng)站可用解決方案引爆華為云開年采購季:助力多場景下業(yè)務(wù)可用、數(shù)據(jù)可靠

    隨著數(shù)字化轉(zhuǎn)型進(jìn)程不斷深入,企業(yè)核心系統(tǒng)的穩(wěn)定性、云上業(yè)務(wù)的連續(xù)性逐漸成為影響企業(yè)持續(xù)運(yùn)營的關(guān)鍵因素。為了讓中小企業(yè)上云之旅走得更加穩(wěn)健,華為云開年采購季重點(diǎn)向企業(yè)客戶推薦網(wǎng)站可用解決方案,面向
    的頭像 發(fā)表于 03-17 12:30 ?222次閱讀

    kafka基本原理詳解

    今天浩道跟大家分享一篇關(guān)于kafka相關(guān)原理的硬核干貨,可以說即使你沒有接觸過kafka,也可以秒懂,一起看看!
    的頭像 發(fā)表于 01-03 09:57 ?786次閱讀
    <b class='flag-5'>kafka</b>基本原理詳解

    kafka支持哪些消息交付語義?

    在讀完kafka官方文檔,kafka設(shè)計(jì)里的消息交付語義一章后,給我的第一印象是內(nèi)容很抽象,于是草擬和總結(jié)了給個(gè)副標(biāo)題,并把相關(guān)內(nèi)容進(jìn)行了歸類;有些生澀的句子,盡量用大白話和舉例進(jìn)行說明,并加入了總結(jié)。
    的頭像 發(fā)表于 12-22 11:27 ?394次閱讀
    <b class='flag-5'>kafka</b>支持哪些消息交付語義?

    如何保證kafka消息不丟失

    如果在簡歷上寫了使用過kafka消息中間件,面試官大概80%的概率會(huì)問你:"如何保證kafka消息不丟失?"反正我是屢試不爽。
    的頭像 發(fā)表于 12-19 09:52 ?611次閱讀
    如何保證<b class='flag-5'>kafka</b>消息不丟失

    zookeeper和kafka的關(guān)系

    Kafka。 Zookeeper是一個(gè)用于協(xié)調(diào)分布式系統(tǒng)的開源軟件。它提供了一種分布式的協(xié)同服務(wù),可以管理和維護(hù)大規(guī)模集群中的配置信息、命名服務(wù)、分布式鎖和分布式隊(duì)列等。Zookeeper的設(shè)計(jì)目標(biāo)是提供一種簡單而效率的分布式一致性解決方案,能夠在分布式環(huán)境中保持?jǐn)?shù)據(jù)
    的頭像 發(fā)表于 12-03 16:39 ?1352次閱讀

    golang中使用kafka的綜合指南

    kafka是一個(gè)比較流行的分布式、可拓展、高性能、可靠的流處理平臺(tái)。在處理kafka的數(shù)據(jù)時(shí),這里有確保處理效率和可靠性的多種最佳實(shí)踐。本文將介紹這幾種實(shí)踐方式,并通過sarama實(shí)現(xiàn)他們。
    的頭像 發(fā)表于 11-30 11:18 ?457次閱讀

    如何構(gòu)建彈性、可用的微服務(wù)?

    基于微服務(wù)的應(yīng)用程序可實(shí)現(xiàn)戰(zhàn)略性數(shù)字轉(zhuǎn)型和云遷移計(jì)劃,對(duì)于開發(fā)團(tuán)隊(duì)來說,這種架構(gòu)十分重要。那么,如何來構(gòu)建彈性、可用的微服務(wù)呢?RedisEnterprise給出了一個(gè)完美的方案。文況速覽
    的頭像 發(fā)表于 11-26 08:06 ?384次閱讀
    如何構(gòu)建彈性、<b class='flag-5'>高</b><b class='flag-5'>可用</b>的微服務(wù)?

    如何將Kafka使用到我們的后端設(shè)計(jì)中

    本文介紹了以下內(nèi)容: 1.什么是Kafka? 2.為什么我們需要使用Kafka這樣的消息系統(tǒng)及使用它的好處 3.如何將Kafka使用到我們的后端設(shè)計(jì)中。 譯自timber.io
    的頭像 發(fā)表于 10-30 14:30 ?417次閱讀
    如何將<b class='flag-5'>Kafka</b>使用到我們的后端設(shè)計(jì)中

    kafka相關(guān)命令詳解

    kafka常用命令詳解
    的頭像 發(fā)表于 10-20 11:34 ?734次閱讀

    Kafka架構(gòu)技術(shù):Kafka的架構(gòu)和客戶端API設(shè)計(jì)

    Kafka 給自己的定位是事件流平臺(tái)(event stream platform)。因此在消息隊(duì)列中經(jīng)常使用的 "消息"一詞,在 Kafka 中被稱為 "事件"。
    的頭像 發(fā)表于 10-10 15:41 ?726次閱讀
    <b class='flag-5'>Kafka</b>架構(gòu)技術(shù):<b class='flag-5'>Kafka</b>的架構(gòu)和客戶端API設(shè)計(jì)

    Spring Kafka的各種用法

    最近業(yè)務(wù)上用到了Spring Kafka,所以系統(tǒng)性的探索了下Spring Kafka的各種用法,發(fā)現(xiàn)了很多實(shí)用的特性,下面介紹下Spring Kafka的消息重試機(jī)制。 0. 前言 原生
    的頭像 發(fā)表于 09-25 17:04 ?809次閱讀

    kafka client在 spring如何實(shí)現(xiàn)

    消息中間件,比如 Kafka、RabbitMq,只需要簡單的引入 jar,就可以通過注解+配置快速集成到項(xiàng)目中。 開始一個(gè) Pulsar Starter 既然已經(jīng)了解了 Apache Pulsar ,又
    的頭像 發(fā)表于 09-25 11:21 ?399次閱讀
    <b class='flag-5'>kafka</b> client在 spring如何實(shí)現(xiàn)