Kafka 副本OffsetOutOfRangeException
Kafka 副本OffsetOutOfRangeException
@(KAFKA)[kafka]
- Kafka 副本OffsetOutOfRangeException- 1故障描述
- 2故障詳細原因線程同步鎖使用了寫鎖未使用讀鎖
- 3解決建議- 方法一升級至0901
- 方法二修改kafka代碼自己編譯一個版本
- 方法三新集群上線降低問題出現概率
- 方法四檢查拓撲報警時出現若是類似異常直接重啟
- 方法五拓撲均使用opaque
- 建議
 
- 4最終解決方案
 
https://issues.apache.org/jira/browse/KAFKA-2477 
 影響版本0.8&之前,修復版本0.9.0.0
1、故障描述
近期,由于kafka集群負載增大,server.log中經常出現下面的錯誤日志。這是kafka自身的一個bug。
簡單說就是由于副本去leader請求同步數據時,發現請求的offset超出了leader的offset范圍(原因見下面代碼解釋),從而認為副本出錯了,于是刪除副本數據,從leader重新同步一份數據過來。由于每個分區的數據較大(約60G),同步時間較長,在此期間,leader及replication均處于高磁盤、網絡IO的狀態,導致storm讀取數據時超時無響應。
對于opaque拓撲,當發現某個分區不可用時,會讀取其它分區。而transactional拓撲必須等這個分區恢復。因此最后的結果是SA的拓撲恢復了,而US/SDC的拓撲掛掉。
[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、故障詳細原因:線程同步鎖使用了寫鎖,未使用讀鎖
(1)某個Wrtier(W1)開始寫數據,它對日志只有寫鎖,未鎖定讀。若線程W1將日志已經append到log中,但未更新nextOffset,此時被其它線程取得運行權。假設此時offset為100,nextOffset為101. 
 (2)此時副本的一個Reader(R1)過來讀數據,它之前已經讀到100了,所以請求nextOffset為101, leader發現有offset為101的數據,所以正確返回數據。 
 (3)然后副本的下一個Reader(R2)來繼續讀數據,它已經讀取到101了,所以請求102,但在leader中,由于nextOffset未更新,它認為102已經超出它當前的100的offset了,所以出現OffsetOutOfRange異常。kafka認為副本已經損壞,刪除副本數據,從leader重傳 
 (4)W1線程繼續執行,更新nextOffset到102,但已經太遲了,異常已經出現。 
 相關代碼:
3、解決建議
方法一:升級至0.9.0.1
目前版本0.8.2,這個bug在0.9.0.0修復。這是一勞永逸的辦法,也是最終的解決的辦法。 
 問題:storm-kafka0.9還處在開發階段,暫時beta版不建議使用。 
 結論:最終解決方法,但暫時不可用。
方法二:修改kafka代碼,自己編譯一個版本
問題:kafka使用gradle編譯的scala代碼,重新編譯有風險
方法三:新集群上線,降低問題出現概率
加快新集群上線的速度,當負載降低時,問題出現概率會相應降低。 
 問題:治標不治本。
方法四:檢查拓撲報警時,出現若是類似異常,直接重啟
通過storm REST API獲取拓撲異常信息,符合一定條件時,重啟拓撲。 
 暫時可行的方法。
方法五:拓撲均使用opaque
問題:拓撲實現opaque的MapState會較為復雜。
建議:
(1)先使用方法四暫時度過。 
 (2)我們先嘗試編譯并維護自己的一個版本,同時加快新集群上線。哪個先達成就使用哪個。 
 (3)最終使用方法一解決問題。
4、最終解決方案
(1)調整以下2個參數,減低replica從leader同步數據的速度:
message.max.bytes=10000000 replica.fetch.max.bytes=10737418 num.replica.fetchers=2(2)升級kafka至0.10.0.1
至此,問題已基本解決,除了GC時間偶爾過長導致zk認為kafka掛掉以外,如果這種情況出現較多的話,則考慮增大zk的timeout時間。
補充: 
 storm fix了一個小bug: 
 https://issues.apache.org/jira/browse/STORM-2440
總結
以上是生活随笔為你收集整理的Kafka 副本OffsetOutOfRangeException的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: REST、SOAP、protocolbu
- 下一篇: storm的消息格式分析
