環境
Red Hat Enterprise Linux Server release 7.3 (Maipo)
jdk1.7.0_80
zookeeper-3.4.11
一、事務日志和快照日志
1.事務日志和快照日志概述
配置文件:/home/cluster/zookeeper/conf/zoo.cfg
事務日志目錄:dataDir=/home/cluster/zookeeper/zkdata
快照日志目錄:dataLogDir=/home/cluster/zookeeper/logs
事務日志,指zookeeper系統在正常運行過程中,針對所有的更新操作,在返回客戶端“更新成功”的響應前,zookeeper會保證已經將本次更新操作的事務日志已經寫到磁盤上,只有這樣,整個更新操作才會生效,在/home/cluster/zookeeper/zkdata目錄下生成一個version-2目錄,該目錄下面是一堆格式如log.****事務日志,文件大小為64MB,****表示寫入該日志的第一個事務的ID,十六進制表示比如log.8cc70320908b。
快照日志,zookeeper的數據在內存中是以樹形結構進行存儲的,而快照就是每隔一段時間就會把整個DataTree的數據序列化后存儲在磁盤中,這就是zookeeper的快照文件。在/home/cluster/zookeeper/logs目錄下有一個version-2目錄,下面是一對格式snapshot.**的快照文件,比如:snapshot.8cc703247dc2,其中**表示zookeeper觸發快照的那個瞬間,提交的最后一個事務的ID。
2.事務日志可視化:事務日志為二進制文件,不能通過vim等工具直接訪問。其實可以通過zookeeper自帶的jar包讀取事務日志文件。首先將libs中的slf4j-api-1.6.1.jar文件和zookeeper根目錄下的zookeeper-3.4.11.jar文件復制到臨時文件夾tmplibs中,然后執行如下命令:
java -classpath .:slf4j-api-1.6.1.jar:zookeeper-3.4.9.jar org.apache.zookeeper.server.LogFormatter ../Data/datalog/version-2/log.8cc70320908b
[cluster@PCS102 tmplibs]$ java -classpath .:slf4j-api-1.6.1.jar:zookeeper-3.4.11.jar org.apache.zookeeper.server.LogFoatter ../zkdata/version-2/log.8cc705501505 10/23/18 3:38:38 AM CST session 0x20309e8d8bd000f cxid 0x1004dee zxid 0x8cc705509109 create '/controller,#7b2276657273696f6e223a312c2262726f6b65726964223a302c2274696d657374616d70223a2231353430323337313138363837227d,v{s{31,s{'world,'anyone}}},T,21575201 10/23/18 3:38:38 AM CST session 0x20309e8d8bd0010 cxid 0x2876033 zxid 0x8cc70550910a error -110 10/23/18 3:38:38 AM CST session 0x1006a28d0860051 cxid 0x170127f zxid 0x8cc70550910b error -110 10/23/18 3:38:38 AM CST session 0x20309e8d8bd000f cxid 0x1004df3 zxid 0x8cc70550910c setData '/controller_epoch,#3231353735313837,21575186 10/23/18 3:38:38 AM CST session 0x20309e8d8bd000f cxid 0x1004e4c zxid 0x8cc70550910d delete '/controller 10/23/18 3:38:38 AM CST session 0x20309e8d8bd0010 cxid 0x287603c zxid 0x8cc70550910e create '/controller,#7b2276657273696f6e223a312c2262726f6b65726964223a312c2274696d657374616d70223a2231353430323337313138373831227d,v{s{31,s{'world,'anyone}}},T,21575202
3.四種日志清理
3.1 使用定時刪除日志腳本 推薦使用這一種 結合crontab,每天定時清理: 0 0 2 * * ? /home/cluster/zookeeper/bin/cleanuplog.sh
#!/bin/bash #snapshot file dir dataLogDir=/home/cluster/zookeeper/logs/version-2 #transction file dir dataDir=/home/cluster/zookeeper/zkdata/version-2 #zk log dir logDir=/home/cluster/zookeeper/logs #保留最新的60個文件 count=60 count=$[$count+1] ##按照時間正序排列|展示從頭開始第count行開始|傳入執行參數 #事務日志 LOGNUM=`ls -l /home/cluster/zookeeper/zkdata/version-2/log.* |wc -l` if [ $LOGNUM -gt 0 ]; then ls -t $dataDir/log.* | tail -n +$count | xargs rm -f fi #快照日志 SNAPSHOTNUM=`ls -l /home/cluster/zookeeper/logs/version-2/snapshot.* |wc -l` if [ $SNAPSHOTNUM -gt 0 ]; then ls -t $dataLogDir/snapshot.* | tail -n +$count | xargs rm -f fi #zookeeper.log ZKLOGNUM=`ls -l /home/cluster/zookeeper/logs/zookeeper.log.* |wc -l` if [ $ZKLOGNUM -gt 0 ]; then ls -t $logDir/zookeeper.log.* | tail -n +$count |xargs rm -f fi #zookeeper.out if [ -e "$logDir/zookeeper.out" ]; then rm -f /home/cluster/zookeeper/logs/zookeeper.out fi
3.2 使用ZK的工具類PurgeTxnLog,它的實現了一種簡單的歷史文件清理策略,可以在這里看一下他的使用方法:http://zookeeper.apache.org/doc/r3.4.3/api/index.html,可以指定要清理的目錄和需要保留的文件數目,簡單使用如下
java -cp zookeeper.jar:lib/slf4j-api-1.6.1.jar:lib/slf4j-log4j12-1.6.1.jar:lib/log4j-1.2.15.jar:conf org.apache.zookeeper.server.PurgeTxnLog <dataDir><snapDir> -n <count>
3.3對於上面這個Java類的執行,ZK自己已經寫好了腳本,在bin/zkCleanup.sh中,所以直接使用這個腳本也是可以執行清理工作的。
3.4從3.4.0開始,zookeeper提供了自動清理snapshot和事務日志的功能,通過配置zoo.cfg中 autopurge.snapRetainCount 和 autopurge.purgeInterval 這兩個參數能夠實現定時清理了。這兩個參數都是在zoo.cfg中配置的:autopurge.purgeInterval 這個參數指定了清理頻率,單位是小時,需要填寫一個1或更大的整數,默認是0,表示不開啟自己清理功能。autopurge.snapRetainCount 這個參數和上面的參數搭配使用,這個參數指定了需要保留的文件數目。默認是保留3個。
二、zk運行日志 zookeeper.out和zookeeper.log
zkEnv.sh配置日志目錄ZOO_LOG_DIR和log4j日志輸出的配置ZOO_LOG4J_PROP
if [ "x${ZOO_LOG_DIR}" = "x" ] then ZOO_LOG_DIR="/home/cluster/zookeeper/logs" fi #默認日志級別INFO,輸出器是控制台 if [ "x${ZOO_LOG4J_PROP}" = "x" ] then ZOO_LOG4J_PROP="INFO,CONSOLE" fi
zkServer.sh 配置日志文件名稱和啟動參數
if [ ! -w "$ZOO_LOG_DIR" ] ; then mkdir -p "$ZOO_LOG_DIR" fi #nohup日志輸出 _ZOO_DAEMON_OUT="$ZOO_LOG_DIR/zookeeper.out" nohup "$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \ -cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &
通過以上代碼可以知道:zookeeper.out實際上是nohup的輸出。而nohup的輸出實際上是stdout,stderr的輸出,可以使用 /home/cluster/zookeeper/bin/cleanuplog.sh一起清理
看下原來log4j配置,基本上沒實際用處
#聲明屬性 zookeeper.root.logger=INFO, CONSOLE zookeeper.console.threshold=INFO zookeeper.log.dir=. zookeeper.log.file=zookeeper.log zookeeper.log.threshold=INFO zookeeper.tracelog.dir=. zookeeper.tracelog.file=zookeeper_trace.log # # ZooKeeper 日志配置 默認INFO級別 輸出器CONSOLE log4j.rootLogger=${zookeeper.root.logger} #控制台 info日志 log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.Threshold=${zookeeper.console.threshold} log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n #ROLLINGFILE appender log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender log4j.appender.ROLLINGFILE.Threshold=${zookeeper.log.threshold} log4j.appender.ROLLINGFILE.File=${zookeeper.log.dir}/${zookeeper.log.file} #每個日志文件最大多少 log4j.appender.ROLLINGFILE.MaxFileSize=10MB #最多幾個文件 log4j.appender.ROLLINGFILE.MaxBackupIndex=10 log4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout log4j.appender.ROLLINGFILE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n #TRACE日志 log4j.appender.TRACEFILE=org.apache.log4j.FileAppender log4j.appender.TRACEFILE.Threshold=TRACE log4j.appender.TRACEFILE.File=${zookeeper.tracelog.dir}/${zookeeper.tracelog.file} log4j.appender.TRACEFILE.layout=org.apache.log4j.PatternLayout log4j.appender.TRACEFILE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L][%x] - %m%n
現在我們改造一下,使用DailyRollingFileAppender每天生成一個文件
修改zkEnv.sh配置日志目錄ZOO_LOG_DIR和log4j日志輸出的配置ZOO_LOG4J_PROP
這樣可以使用 /home/cluster/zookeeper/bin/cleanuplog.sh 一起清理
[cluster@PCS102 bin]$ vim zkEnv.sh if [ "x${ZOO_LOG4J_PROP}" = "x" ] then ZOO_LOG4J_PROP="INFO,DAYROLLINGAppender" fi
#聲明屬性 zookeeper.root.logger=INFO, DAYROLLINGAppender zookeeper.log.dir=/home/cluster/zookeeper/logs zookeeper.log.file=zookeeper.log # ZooKeeper 日志配置 默認INFO級別 輸出器CONSOLE log4j.rootLogger=${zookeeper.root.logger} #DAYROLLING appender log4j.appender.DAYROLLINGAppender=org.apache.log4j.DailyRollingFileAppender log4j.appender.DAYROLLINGAppender.DatePattern='.'yyyy-MM-dd-HH log4j.appender.DAYROLLINGAppender.File=${zookeeper.log.dir}/${zookeeper.log.file} log4j.appender.DAYROLLINGAppender.Threshold=INFO log4j.appender.DAYROLLINGAppender.layout=org.apache.log4j.PatternLayout log4j.appender.DAYROLLINGAppender.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n
參考:
ZooKeepr日志清理【轉】
ZK自動清理日志
zookeeper運維
修改Zookeeper輸出日志 zookeeper.out輸出路徑