作者:周鵬輝
在進行故障排除時,我們可能希望深入瞭解二進制形式的Zookeeper事務日誌和快照,以便從中獲取更多可讀信息。本文描述瞭如何通過讀取Zookeeper事務日誌和快照來排查zookeeper相關問題。
文檔概述
1.Zookeeper事務日誌和快照介紹
2.Zookeeper 事務日誌和快照讀取方法
3.總結
測試環境
1.CDH and CM version:CDH5.16.2 and CM5.16.2
2.集羣啓用:Kerbeos+OpenLDAP+Sentry
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.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等)出現故障。
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源創計劃”,歡迎正在閱讀的你也加入,一起分享。