0826-5.16.2-如何讀取和分析Zookeeper Transaction Log 和Snapshots

作者:周鵬輝

1.文檔編寫目的



在進行故障排除時,我們可能希望深入瞭解二進制形式的Zookeeper事務日誌和快照,以便從中獲取更多可讀信息。本文描述瞭如何通過讀取Zookeeper事務日誌和快照來排查zookeeper相關問題。

  • 文檔概述

1.Zookeeper事務日誌和快照介紹

2.Zookeeper 事務日誌和快照讀取方法

3.總結

  • 測試環境

1.CDH and CM version:CDH5.16.2 and CM5.16.2

2.集羣啓用:Kerbeos+OpenLDAP+Sentry


2.Zookeeper事務日誌和快照介紹



Zookeeper 的數據先寫入數據目錄(CDH中默認/var/lib/zookeeper/version-2)的transaction log,當總量達到 10 萬條記錄的時候會自動做快照(snapshot)【1】。而且數據文件不是根據時間來保存的,沒法設置數據保存日期。CDH 默認設置是每天清理這個目錄, 並且只保留 5 個快照. 如果想需要保留更多的數據, 可以在CM -> Zookeeper -> Configuration -> Auto Purge Snapshots Retain Count【2】中設置保存更多的快照,不過這對於定位 Zookeeper 導致的問題可能幫助也不是很大, 因爲快照生成的時間不一定是發生問題的時候. 所以如果想排查一些因爲zookeeper引起的問題, 建議直接把當時的整個數據目錄打包來分析。

【1】


【2】


3.Zookeeper 事務日誌和快照讀取方法



3.1 Zookeeper Transaction Log

1.把集羣的/var/lib/zookeepr/vaersion-2目錄拷貝到/tmp/zookeeper下進行分析


2.把解析Transaction Log 和Snapshots的jar包拷貝到/tmp/zookeepr,以下是在CDH5.16.2環境相關包的存放路徑:


cp /opt/cloudera/parcels/CDH-5.16.2-1.cdh5.16.2.p0.8/jars/zookeeper-3.4.5-cdh5.16.2.jar  /tmp/zookeeper/
cp /opt/cloudera/parcels/CDH-5.16.2-1.cdh5.16.2.p0.8/lib/zookeeper/lib/log4j-1.2.16.jar /tmp/zookeeper/
cp  /opt/cloudera/parcels/CDH-5.16.2-1.cdh5.16.2.p0.8/lib/zookeeper/lib/slf4j-log4j12.jar /tmp/zookeeper/
cp /opt/cloudera/parcels/CDH-5.16.2-1.cdh5.16.2.p0.8/lib/zookeeper/lib/slf4j-log4j12-1.7.5.jar   /tmp/zookeeper/
cp  /opt/cloudera/parcels/CDH-5.16.2-1.cdh5.16.2.p0.8/lib/zookeeper/lib/slf4j-api-1.7.5.jar    /tmp/zookeeper/


3.解析Zookeeper Transaction Log,比如我們想獲取log.740003f499文件下面的更多信息,通過如下命令,我們可以看到此文件下面包含很多 session id號和對應的連接信息:

java -cp /tmp/zookeeper/zookeeper-3.4.5-cdh5.16.2.jar:/tmp/zookeeper/log4j-1.2.16.jar:/tmp/zookeeper/slf4j-log4j12-1.7.5.jar:/tmp/zookeeper/slf4j-api-1.7.5.jar org.apache.zookeeper.server.LogFormatter  /tmp/zookeeper/version-2/log.740003f499


4. 如下命令輸出此Zookeeper事務日誌(log.740003f499)中記錄了多少個事務,一共是39510個事務:

java -cp /tmp/zookeeper/zookeeper-3.4.5-cdh5.16.2.jar:/tmp/zookeeper/log4j-1.2.16.jar:/tmp/zookeeper/slf4j-log4j12-1.7.5.jar:/tmp/zookeeper/slf4j-api-1.7.5.jar org.apache.zookeeper.server.LogFormatter  /tmp/zookeeper/version-2/log.740003f499  |grep session|wc -l


5. 如果想知道整個集羣中哪個服務對Zookeeper的調用最多,其中一種方法是檢查“ SetData”調用,比如:

java -cp /tmp/zookeeper/zookeeper-3.4.5-cdh5.16.2.jar:/tmp/zookeeper/log4j-1.2.16.jar:/tmp/zookeeper/slf4j-log4j12-1.7.5.jar:/tmp/zookeeper/slf4j-api-1.7.5.jar org.apache.zookeeper.server.LogFormatter  /tmp/zookeeper/version-2/log.740003f499 |grep session|grep setData|awk '{print $12}'|awk -F/ '{print $3}'|sort|uniq -c|sort -n


3.2 Snapshots

1.獲取snapshot.740003f497文件中的更多信息,使用如下命令:

java -cp /tmp/zookeeper/zookeeper-3.4.5-cdh5.16.2.jar:/tmp/zookeeper/log4j-1.2.16.jar:/tmp/zookeeper/slf4j-log4j12-1.7.5.jar:/tmp/zookeeper/slf4j-api-1.7.5.jar org.apache.zookeeper.server.SnapshotFormatter /tmp/zookeeper/version-2/snapshot.740003f497


在返回的信息中,我們可以看到各個seesion id對應的詳細信息,比如cZxid、dataLength等。


2.想輸出znodes列表,只需添加“ grep'/'”即可

java -cp /tmp/zookeeper/zookeeper-3.4.5-cdh5.16.2.jar:/tmp/zookeeper/log4j-1.2.16.jar:/tmp/zookeeper/slf4j-log4j12-1.7.5.jar:/tmp/zookeeper/slf4j-api-1.7.5.jar org.apache.zookeeper.server.SnapshotFormatter /tmp/zookeeper/version-2/snapshot.740003f497  |  grep '/'


3.3 結合session ID和transaction Log查看數據長度

1.我們用zookeeper-client 產生一個znode /my_test爲例進行說明。用zookeeper-client 產生一個znode如下:

zookeeper-client  -server 192.168.0.181:2181
create /my_test my_data


把對應znode的數據目錄/var/lib/zookeeper/version-2/  拷貝到/tmp/zookeeper下進行分析,看到對應的transaction和snapshots文件

cp -r /var/lib/zookeeper/version-2/ .


2.使用如下命令讀取最新的事務日誌log.1c00000001,可以看到, 這個znode -- my_test被產生了,session id 爲 0x3757f69404c0002, 並且它的數據“my_data" 緊隨其後 -- “#6d795f64617461”

java -cp /tmp/zookeeper/zookeeper-3.4.5-cdh5.16.2.jar:/tmp/zookeeper/log4j-1.2.16.jar:/tmp/zookeeper/slf4j-log4j12-1.7.5.jar:/tmp/zookeeper/slf4j-api-1.7.5.jar org.apache.zookeeper.server.LogFormatter  /tmp/zookeeper/version-2/log.1c00000001 > log.1c00000001.log
grep 'my_test' log.1c00000001.log


11/1/20 12:09:50 AM CST session 0x3757f69404c0002 cxid 0x1 zxid 0x1c00000022 create '/my_test,#6d795f64617461,v{s{31,s{'world,'anyone}}},F,395672


3.通過session id也可以查看到對應的znode信息

grep ' 0x3757f69404c0002' log.1c00000001.log


11/1/20 12:09:29 AM CST session 0x3757f69404c0002 cxid 0x0 zxid 0x1c00000011 createSession 30000
11/1/20 12:09:50 AM CST session 0x3757f69404c0002 cxid 0x1 zxid 0x1c00000022 create '/my_test,#6d795f64617461,v{s{31,s{'world,'anyone}}},F,395672


3.4 結合session ID和Snapshots查看數據長度

1.由於snapshot只是znode tree的一個快照, 所以我必須重啓zookeeper 節點以便能產生一個新的snapshot文件來進行測試(因爲snapshot文件只是一個當時znode tree的一個快照,如果當時沒有執行快照 ,我們目前並沒有手動觸發產生一個snapshot的命令或者操作,所以未必能在transaction log中找到對應的id)。重啓後產生了最新的snapshot文件snapshot.1d00000000。


2.執行如下命令讀取最新snapshot.1d00000000

java -cp /tmp/zookeeper/zookeeper-3.4.5-cdh5.16.2.jar:/tmp/zookeeper/log4j-1.2.16.jar:/tmp/zookeeper/slf4j-log4j12-1.7.5.jar:/tmp/zookeeper/slf4j-api-1.7.5.jar org.apache.zookeeper.server.SnapshotFormatter /var/lib/zookeeper/version-2/snapshot.1d00000000 >snapshot.1d00000000.log


3.查看這個結果文件snapshot.1d00000000.log可以看到Create zxid = 0x00000700000032 與之前transaction log解析後的id一致, 數據字節長度是7, 也就是 ”my_data"的字節長度#6d795f64617461。

/my_test
  cZxid = 0x00001c00000022
  ctime = Sun Nov 01 00:09:50 CST 2020
  mZxid = 0x00001c00000022
  mtime = Sun Nov 01 00:09:50 CST 2020
  pZxid = 0x00001c00000022
  cversion = 0
  dataVersion = 0
  aclVersion = 0
ephemeralOwner = 0x00000000000000
dataLength = 7


3.5 結合zookeeper日誌和數據長度排查負載高的應用

上面我們已經通過transaction和snapshot文件查看到了對應的seesion id和數據長度,我們想進一步確定是哪些應用在哪些節點發起的導致zookeeper負載高。我們可以結合transaction和snapshot和zookeeper 日誌來分析問題(CDH中zookeeper 日誌默認在/varlog/zookeeper下)。


1.先通過seesion id在zookeeper中找到對應的連接信息

grep '0x3757f69404c0002' /var/log/zookeeper/zookeeper-cmf-zookeeper-SERVER-cdh01.hadoop.com.log



2.看到此連接是從192.168.0.181:39352發起,我們就可以到對應的主機和端口查找到對應的連接信息。

lsof -i:39536
ps -aux | grep 18744


確實我們此時沒有關閉剛剛創建znode /my_test的連接,已經對應上。


我們close剛剛創建znode /my_test的連接,


發現通過ip和端口已經查找不到對應的zookeeper連接


3.前面我們看到znode /my_test數據片段裏面的dataLength =7表示此連接信息的數據長度爲7byte,如果此數據長度特別大,容易導致zookeeper的負載,我們可以通過對應的seesion id到對應節點、端口查此鏈接對應的應用。當dataLengtg的值大於zookeeper的 jute.maxbuffer裏面配置的數值,就會在zookeeper中出現Len error異常。從而容易導致需要使用到zookeeper的服務(比如YARN、Kafka、HBase等)出現故障。


4.問題總結



1.當在zookeeper中看到比如Len error 14307055的異常時候,我們可以通過結合zookeeper 日誌(/var/log/zookeeper)和zookeeper的數據目錄下的Transaction和Snapshots文件(/var/lib/zookeeper/version-2)。確定IP和端口確定是哪些應用導致zookeeper 負載高從而出現Len error異常;


2. zookeeper的數據長度dataLength如果大於zookeeper的jute.maxbuffer裏面配置的數值,就會出現Len error異常。可以在Zookeeper日誌中找到Len error最大的值, 如果小於 32MB, 那麼統一建議把 jute.maxbuffer配置爲32MB。如果此數據長度特別大,容易導致zookeeper的負載,我們可以通過對應的seesion id的IP和端口查此鏈接對應的應用。zookeeper中出現Len error異常,容易導致需要使用到zookeeper的服務(比如YARN、Kafka、HBase等)和zookeeper連接中斷,從而出現異常。

本文分享自微信公衆號 - Hadoop實操(gh_c4c535955d0f)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章