Kafka 副本OffsetOutOfRangeException
Kafka 副本OffsetOutOfRangeException
@(KAFKA)[kafka]
- Kafka 副本OffsetOutOfRangeException
- 1故障描述
- 2故障詳細(xì)原因線程同步鎖使用了寫鎖未使用讀鎖
- 3解決建議
- 方法一升級(jí)至0901
- 方法二修改kafka代碼自己編譯一個(gè)版本
- 方法三新集群上線降低問題出現(xiàn)概率
- 方法四檢查拓?fù)鋱?bào)警時(shí)出現(xiàn)若是類似異常直接重啟
- 方法五拓?fù)渚褂胦paque
- 建議
- 4最終解決方案
https://issues.apache.org/jira/browse/KAFKA-2477
影響版本0.8&之前,修復(fù)版本0.9.0.0
1、故障描述
近期,由于kafka集群負(fù)載增大,server.log中經(jīng)常出現(xiàn)下面的錯(cuò)誤日志。這是kafka自身的一個(gè)bug。
簡(jiǎn)單說就是由于副本去leader請(qǐng)求同步數(shù)據(jù)時(shí),發(fā)現(xiàn)請(qǐng)求的offset超出了leader的offset范圍(原因見下面代碼解釋),從而認(rèn)為副本出錯(cuò)了,于是刪除副本數(shù)據(jù),從leader重新同步一份數(shù)據(jù)過來。由于每個(gè)分區(qū)的數(shù)據(jù)較大(約60G),同步時(shí)間較長(zhǎng),在此期間,leader及replication均處于高磁盤、網(wǎng)絡(luò)IO的狀態(tài),導(dǎo)致storm讀取數(shù)據(jù)時(shí)超時(shí)無響應(yīng)。
對(duì)于opaque拓?fù)?#xff0c;當(dāng)發(fā)現(xiàn)某個(gè)分區(qū)不可用時(shí),會(huì)讀取其它分區(qū)。而transactional拓?fù)浔仨毜冗@個(gè)分區(qū)恢復(fù)。因此最后的結(jié)果是SA的拓?fù)浠謴?fù)了,而US/SDC的拓?fù)鋻斓簟?/p> [2016-03-29 18:24:59,403] WARN [ReplicaFetcherThread-3-4], Replica 2 for partition [g17,4] reset its fetch offset from 3501121050 to current leader 4's start offset 3501121050 (kafka.server.ReplicaFetcherThread) [2016-03-29 18:24:59,403] ERROR [ReplicaFetcherThread-3-4], Current offset 3781428103 for partition [g17,4] out of range; reset offset to 3501121050 (kafka.server.ReplicaFetcherThread)
2、故障詳細(xì)原因:線程同步鎖使用了寫鎖,未使用讀鎖
(1)某個(gè)Wrtier(W1)開始寫數(shù)據(jù),它對(duì)日志只有寫鎖,未鎖定讀。若線程W1將日志已經(jīng)append到log中,但未更新nextOffset,此時(shí)被其它線程取得運(yùn)行權(quán)。假設(shè)此時(shí)offset為100,nextOffset為101.
(2)此時(shí)副本的一個(gè)Reader(R1)過來讀數(shù)據(jù),它之前已經(jīng)讀到100了,所以請(qǐng)求nextOffset為101, leader發(fā)現(xiàn)有offset為101的數(shù)據(jù),所以正確返回?cái)?shù)據(jù)。
(3)然后副本的下一個(gè)Reader(R2)來繼續(xù)讀數(shù)據(jù),它已經(jīng)讀取到101了,所以請(qǐng)求102,但在leader中,由于nextOffset未更新,它認(rèn)為102已經(jīng)超出它當(dāng)前的100的offset了,所以出現(xiàn)OffsetOutOfRange異常。kafka認(rèn)為副本已經(jīng)損壞,刪除副本數(shù)據(jù),從leader重傳
(4)W1線程繼續(xù)執(zhí)行,更新nextOffset到102,但已經(jīng)太遲了,異常已經(jīng)出現(xiàn)。
相關(guān)代碼:
3、解決建議
方法一:升級(jí)至0.9.0.1
目前版本0.8.2,這個(gè)bug在0.9.0.0修復(fù)。這是一勞永逸的辦法,也是最終的解決的辦法。
問題:storm-kafka0.9還處在開發(fā)階段,暫時(shí)beta版不建議使用。
結(jié)論:最終解決方法,但暫時(shí)不可用。
方法二:修改kafka代碼,自己編譯一個(gè)版本
問題:kafka使用gradle編譯的scala代碼,重新編譯有風(fēng)險(xiǎn)
方法三:新集群上線,降低問題出現(xiàn)概率
加快新集群上線的速度,當(dāng)負(fù)載降低時(shí),問題出現(xiàn)概率會(huì)相應(yīng)降低。
問題:治標(biāo)不治本。
方法四:檢查拓?fù)鋱?bào)警時(shí),出現(xiàn)若是類似異常,直接重啟
通過storm REST API獲取拓?fù)洚惓P畔?#xff0c;符合一定條件時(shí),重啟拓?fù)洹?
暫時(shí)可行的方法。
方法五:拓?fù)渚褂胦paque
問題:拓?fù)鋵?shí)現(xiàn)opaque的MapState會(huì)較為復(fù)雜。
建議:
(1)先使用方法四暫時(shí)度過。
(2)我們先嘗試編譯并維護(hù)自己的一個(gè)版本,同時(shí)加快新集群上線。哪個(gè)先達(dá)成就使用哪個(gè)。
(3)最終使用方法一解決問題。
4、最終解決方案
(1)調(diào)整以下2個(gè)參數(shù),減低replica從leader同步數(shù)據(jù)的速度:
message.max.bytes=10000000 replica.fetch.max.bytes=10737418 num.replica.fetchers=2(2)升級(jí)kafka至0.10.0.1
至此,問題已基本解決,除了GC時(shí)間偶爾過長(zhǎng)導(dǎo)致zk認(rèn)為kafka掛掉以外,如果這種情況出現(xiàn)較多的話,則考慮增大zk的timeout時(shí)間。
補(bǔ)充:
storm fix了一個(gè)小bug:
https://issues.apache.org/jira/browse/STORM-2440
總結(jié)
以上是生活随笔為你收集整理的Kafka 副本OffsetOutOfRangeException的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: REST、SOAP、protocolbu
- 下一篇: storm的消息格式分析