偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

生產(chǎn)故障|Kafka消息發(fā)送延遲達(dá)到幾十秒的罪魁禍?zhǔn)拙谷皇?..

開發(fā) 架構(gòu) Kafka
通過對(duì)日志分析發(fā)現(xiàn)存在大面積分區(qū)Leader選舉,__consumer_offsets主題的分區(qū)也大量進(jìn)行分區(qū)Leader選舉,從而導(dǎo)致消息發(fā)送幾乎停止,大量消費(fèi)組觸發(fā)重平衡,整個(gè)集群接近癱瘓,最終確定了根因:Broker節(jié)點(diǎn)與Zookeeper會(huì)話超時(shí),觸發(fā)大量分區(qū)重新選舉。

以前我在知其然而知其所以然,為什么Kafka在2.8版本中會(huì)“拋棄”Zookeeper一文中闡述了為什么官方要廢棄Zookeeper,當(dāng)時(shí)我記得有讀者反駁說zookeeper非常穩(wěn)定,基本不會(huì)出現(xiàn)什么問題,筆者在雙十一期間遇到的問題,就證明了Zookeeper的“脆弱性”,而zookeeper的脆弱性將對(duì)Kafka集群造成嚴(yán)重的影響。

1、故障現(xiàn)象

筆者在雙十一期間負(fù)責(zé)的kafka集群的響應(yīng)時(shí)間飆升到了10~30s,嚴(yán)重影響消息的寫入。

通過對(duì)日志分析發(fā)現(xiàn)存在大面積分區(qū)Leader選舉,__consumer_offsets主題的分區(qū)也大量進(jìn)行分區(qū)Leader選舉,從而導(dǎo)致消息發(fā)送幾乎停止,大量消費(fèi)組觸發(fā)重平衡,整個(gè)集群接近癱瘓,最終確定了根因:Broker節(jié)點(diǎn)與Zookeeper會(huì)話超時(shí),觸發(fā)大量分區(qū)重新選舉。

本文借此故障,與大家一起剖析一下Zookeeper在Kafka中起了哪些作用,以及確定“罪魁禍?zhǔn)?rdquo;的過程,希望給大家排查問題能帶來一定的啟發(fā)。

2、Zookeeper在Kafka中具有舉足輕重的作用

在正式進(jìn)入故障分析之前,我們首先介紹一下Zookeeper在kafka架構(gòu)設(shè)計(jì)中所起的角色。

核心理念:kafka的設(shè)計(jì)者對(duì)待Zookeeper的使用是非常謹(jǐn)慎的,即需要依靠Zookeeper進(jìn)行控制器選舉,Broker節(jié)點(diǎn)故障實(shí)時(shí)發(fā)現(xiàn),但又盡量降低對(duì)Zookeeper的依賴。

基于Zookeeper進(jìn)行的程序開發(fā),我們一般可以通過查看zookeeper中的目錄布局,可以窺探出哪些功能是依靠Zookeeper完成,Kafka在Zookeeper中的存儲(chǔ)目錄結(jié)構(gòu)如下圖所示:

上述各個(gè)節(jié)點(diǎn),其背后都關(guān)聯(lián)著Kafka一個(gè)核心工作機(jī)制,大家可以順藤摸瓜進(jìn)行探究,本文需要重點(diǎn)介紹/brokers這個(gè)目錄的布局與作用,目錄詳情如下:

  • /controller Kafka控制器的信息,Kafka控制器的選舉依靠zookeeper。
  • /brokers/ids/{id} 在持久節(jié)點(diǎn)/brokers/ids下創(chuàng)建眾多的臨時(shí)節(jié)點(diǎn),每一個(gè)節(jié)點(diǎn),表示一個(gè)Broker節(jié)點(diǎn),節(jié)點(diǎn)的內(nèi)容存儲(chǔ)了Broker的基本信息,例如端口、版本、監(jiān)聽地址等。
  • /brokers/topics/{topic}/partitions/{partition}/state

在kafka2.8版本一下,Kafka中topic中的路由信息最終持久化在zookeeper中,每一個(gè)broker節(jié)點(diǎn)啟動(dòng)后會(huì)在內(nèi)存中緩存一份數(shù)據(jù)。/brokers節(jié)點(diǎn)每一個(gè)子節(jié)點(diǎn)表示一個(gè)具體的主題,主題的元數(shù)據(jù)主要包括分區(qū)的個(gè)數(shù)與每一個(gè)分區(qū)的狀態(tài)信息。每一個(gè)分區(qū)的狀態(tài)信息主要包括:

  • controller_epoch 當(dāng)前集群控制器的epoch,表示controller選舉的次數(shù),我們可以理解為controller的“版本號(hào)”。
  • leader 當(dāng)前分區(qū)Leader所在的broker id。
  • Leader_epoch 分區(qū)的leader_epoch,表示分區(qū)Leader選舉的次數(shù),從0開始,每發(fā)生一次分區(qū)leader選舉該值就會(huì)加一,kafka通過引入leader epoch機(jī)制解決低版本依靠依賴水位線表示副本進(jìn)度可能造成的數(shù)據(jù)丟失與數(shù)據(jù)不一致問題,這個(gè)將在后續(xù)文章中深入剖析。
  • isr 分區(qū)的isr集合。
  • version 存儲(chǔ)狀態(tài)分區(qū)狀態(tài)數(shù)據(jù)結(jié)構(gòu)的版本號(hào),這個(gè)字段大家可以忽略

在Zookeeper中有一種同樣的“設(shè)計(jì)模式”,就是可以通過在zookeeper中創(chuàng)建臨時(shí)節(jié)點(diǎn)+事件監(jiān)聽機(jī)制,從而實(shí)現(xiàn)數(shù)據(jù)的實(shí)時(shí)動(dòng)態(tài)感知,以/brokers/ids為例進(jìn)行闡述:

  • Kafka broker進(jìn)程啟動(dòng)時(shí)會(huì)向zookeeper創(chuàng)建一個(gè)臨時(shí)節(jié)點(diǎn)/brokers/ids/{id},其中id為broker的編號(hào)
  • Kafka Broker進(jìn)程停止后,創(chuàng)建的臨時(shí)節(jié)點(diǎn)在broker與zookeeper的會(huì)話超時(shí)后會(huì)被自動(dòng)刪除,產(chǎn)生節(jié)點(diǎn)刪除事件
  • Kafka controller 會(huì)自動(dòng)監(jiān)聽/brokers/ids 目錄的節(jié)點(diǎn)新增與刪除事件,一旦broker下線、上線,controller都會(huì)實(shí)時(shí)感知,從而采取必要處理。

經(jīng)過上面的初步介紹,Kafka對(duì)zookeeper的依賴還是非常大的,特別是Kafka控制器的選舉、broker節(jié)點(diǎn)的存活狀態(tài)等都依賴zookeeper。

Kafka 控制器可以看出是整個(gè)kafka集群的“大腦”,如果它出現(xiàn)異動(dòng),其影響范圍之廣,影響程度之大可想而知,接下來的故障分析會(huì)給出更直觀的展現(xiàn)。

溫馨提示:本文主要是一個(gè)故障分析過程,后續(xù)關(guān)于kafka控制器如何選舉、leader_epoch副本同步機(jī)制等會(huì)在《Kafka原理與實(shí)戰(zhàn)》專欄中一一介紹,敬請(qǐng)關(guān)注。

3、問題分析

一看到消息發(fā)送響應(yīng)時(shí)間長(zhǎng),我的第一反應(yīng)是查看線程棧,是不是有鎖阻塞,但查看線程堆棧發(fā)現(xiàn)Kafka用于處理請(qǐng)求的線程池大部分都阻塞在獲取任務(wù)處,表明“無活可干”狀態(tài):

說明客戶端端消息發(fā)送請(qǐng)求都沒有到達(dá)Kafka的排隊(duì)隊(duì)列,并且專門用于處理網(wǎng)絡(luò)讀寫的線程池也很空閑,那又是為什么呢?

消息發(fā)送端延遲超級(jí)高,但服務(wù)端線程又極度空閑,有點(diǎn)詭異?

繼續(xù)查看服務(wù)端日志,發(fā)現(xiàn)了大量主題(甚至連系統(tǒng)主題__consumer_offsets主題也發(fā)生了Leader選舉),日志如下:

核心日志:start at Leader Epoch 大量分區(qū)在進(jìn)行Leader選舉。

Kafka中中只有Leader分區(qū)能處理讀、寫請(qǐng)求,follower分區(qū)只是從leader分區(qū)復(fù)制數(shù)據(jù),在Leader節(jié)點(diǎn)宕機(jī)后參與leader選舉,故分區(qū)在進(jìn)行Leader選舉時(shí)無法處理客戶端的寫入請(qǐng)求,而發(fā)送端又有重試機(jī)制,故消息發(fā)送延遲很大。

那到底在什么情況下會(huì)觸發(fā)大量主題進(jìn)行重新選舉呢?

我們找到當(dāng)前集群的Controler節(jié)點(diǎn),查看state-change.log中,發(fā)現(xiàn)如下日志:

出現(xiàn)了大量分區(qū)的狀態(tài)從OnlinePartition變更為OfflinePartition。

溫馨提示:根據(jù)日志我們可以去查看源碼,找到輸出這些方法的調(diào)用鏈,就可以順藤摸瓜去找針對(duì)性的日志。

繼續(xù)查看Controler節(jié)點(diǎn)下的controller.log中發(fā)現(xiàn)關(guān)鍵日志:

核心日志解讀:

  • [Controller id=1] Broker failure callback for 8 (kafka.controller.KafkaController) 控制器將節(jié)點(diǎn)8從集群的在線中移除,控制器為什么會(huì)將節(jié)點(diǎn)8移除呢?

接下來順藤摸瓜,去看一下節(jié)點(diǎn)8上的日志如下圖所示:

核心日志解讀:原來broker與zookeeper的會(huì)話超時(shí),導(dǎo)致臨時(shí)節(jié)點(diǎn)被移除。

先不探究會(huì)話為什么會(huì)超時(shí),我們先來看一下會(huì)話超時(shí),會(huì)給Kafka集群帶來什么嚴(yán)重影響。

/brokers/ids下任意一個(gè)節(jié)點(diǎn)被刪除,Kafka控制器都能及時(shí)得到,并執(zhí)行對(duì)應(yīng)的處理。

這里需要分兩種情況考慮。

3.1 普通Broker節(jié)點(diǎn)被移除

處理入口為:KafkaController的onBrokerFailure方法,代碼詳情如下圖所示:

一個(gè)普通的broker在zk中被移除,Kafka控制器會(huì)將該節(jié)點(diǎn)上分配的所有分區(qū)的狀態(tài)從OnlinePartition變更為OfflinePartition,從而觸發(fā)分區(qū)的重新選舉。

擴(kuò)展知識(shí)點(diǎn):__consumer_offsets分區(qū)如果進(jìn)行Leader重新選舉,大面積的消費(fèi)組會(huì)觸發(fā)重平衡,背后的機(jī)制:

消費(fèi)組需要在Broker端進(jìn)行組協(xié)調(diào)器選舉,選舉算法如下:消費(fèi)組的名稱的hashcode與主題 __ consumer_offsets的隊(duì)列總數(shù)取模,取余數(shù),映射成 __consumer_offsets 分區(qū),該分區(qū)的leader在哪個(gè)broker節(jié)點(diǎn),該節(jié)點(diǎn)則會(huì)充當(dāng)消費(fèi)組的組協(xié)調(diào)器。

一旦該分區(qū)的Leader發(fā)生變化,對(duì)應(yīng)的消費(fèi)組必須重新選舉新的組協(xié)調(diào)器,從而觸發(fā)消費(fèi)組的重平衡。

3.2 Controller節(jié)點(diǎn)被移除

如果zookeeper中移除的broker id 為 Kafka controller,其影響會(huì)更大,主要的入口如下圖所示:

如果是controller節(jié)點(diǎn)會(huì)話超時(shí),臨時(shí)節(jié)點(diǎn)/controller節(jié)點(diǎn)會(huì)被刪除,從而會(huì)觸發(fā)Kafka controller選舉,最終所有的broker節(jié)點(diǎn)都會(huì)收到節(jié)點(diǎn)/controller的刪除、新增或節(jié)點(diǎn)數(shù)據(jù)變化的通知,KafkaController的onControllerFailover方法會(huì)被執(zhí)行,與會(huì)將于zookeeper相關(guān)的事件監(jiān)聽器重新注冊(cè)、分區(qū)狀態(tài)機(jī)、副本狀態(tài)機(jī)都會(huì)停止并重新啟動(dòng),各個(gè)分區(qū)會(huì)觸發(fā)自動(dòng)leader分區(qū)選舉。

可以這樣形容:一朝天子一朝臣,全部重新來過。

3.3 zookeeper會(huì)話超時(shí)根因排查

查看服務(wù)端日志,可以看到如下日志:

核心日志解讀:Closed socket connection for client ... 表示連接被客戶端主動(dòng)關(guān)閉。

那為什么客戶端會(huì)主動(dòng)關(guān)閉心跳呢?心跳處理的套路就是客戶端需要定時(shí)向服務(wù)端發(fā)送心跳包,服務(wù)端在指定時(shí)間內(nèi)沒有收到或處理心跳包,則會(huì)超時(shí)。

要想一探究竟,唯一的辦法:閱讀源碼 ,通過研讀Zookeeper客戶端源碼,發(fā)現(xiàn)存在這樣一個(gè)設(shè)計(jì):客戶端會(huì)把所有的請(qǐng)求先放入一個(gè)隊(duì)列中,然后通過一個(gè)發(fā)送線程(SendThread)從隊(duì)列中獲取請(qǐng)求,發(fā)送到服務(wù)端,關(guān)鍵代碼如下:

如果存在大量的zk更新操作,心跳包可能會(huì)處理不及時(shí),而在出現(xiàn)zookeeper session會(huì)話超時(shí)之前,集群在大面積ISR擴(kuò)張與收縮,頻繁更新zk,從而觸發(fā)了客戶端端心跳超時(shí),這個(gè)問題也可以通過如下代碼進(jìn)行復(fù)現(xiàn):

 

經(jīng)過這波分析,由于zookeeper會(huì)話超時(shí),導(dǎo)致大量分區(qū)重新選舉,最終導(dǎo)致消息發(fā)送延遲很大,并且消費(fèi)組大面積重平衡的根本原因就排查清楚了,本期分享就到此為止,我們下期見。

 

責(zé)任編輯:武曉燕 來源: 中間件興趣圈
相關(guān)推薦

2020-10-19 06:49:18

內(nèi)存String

2015-11-23 10:29:48

app隱藏通信安卓耗電

2019-06-04 14:19:53

AWS谷歌巖機(jī)

2020-08-18 08:20:49

應(yīng)用程序

2009-03-20 16:10:15

2019-05-27 10:22:26

Oracle日志數(shù)據(jù)庫

2018-09-10 09:43:26

2011-04-21 16:34:56

打印亂碼接口

2009-06-03 08:48:26

2021-12-12 21:51:54

人工智能銀行內(nèi)卷

2015-10-14 11:32:55

機(jī)房空調(diào)制冷

2009-12-03 10:25:32

微軟補(bǔ)丁黑屏故障

2009-10-12 19:44:40

Windows 7閃屏解決辦法

2011-08-12 10:04:52

數(shù)據(jù)中心宕機(jī)EPO

2023-07-25 13:40:46

AI模型

2015-02-26 13:34:28

2015-10-14 11:04:53

2010-09-01 09:33:15

網(wǎng)絡(luò)故障

2025-03-05 05:00:00

2009-02-25 08:58:30

裁員上網(wǎng)本微軟
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)