ZooKeeper系列文章:https://www.cnblogs.com/f-ck-need-u/p/7576137.html#zkhtml
ZooKeeper有兩種日誌、一種快照。日誌分爲事務日誌和ZooKeeper運行時的系統日誌。java
ZooKeeper集羣中的每一個服務器節點每次接收到寫操做請求時,都會先將此次請求發送給leader,leader將此次寫操做轉換爲帶有狀態的事務,而後leader會對此次寫操做廣播出去以便進行協調。當協調經過(大多數節點容許此次寫)後,leader通知全部的服務器節點,讓它們將此次寫操做應用到內存數據庫中,並將其記錄到事務日誌中。數據庫
當事務日誌記錄的次數達到必定數量後(默認10W次),就會將內存數據庫序列化一次,使其持久化保存到磁盤上,序列化後的文件稱爲"快照文件"。每次拍快照都會生成新的事務日誌。apache
有了事務日誌和快照,就可讓任意節點恢復到任意時間點(只要沒有清理事務日誌和快照)。api
dataDir
:
ZooKeeper的數據目錄,主要目的是存儲內存數據庫序列化後的快照路徑。若是沒有配置事務日誌(即dataLogDir配置項)的路徑,那麼ZooKeeper的事務日誌也存放在數據目錄中。bash
dataLogDir
:
指定事務日誌的存放目錄。事務日誌對ZooKeeper的影響很是大,強烈建議事務日誌目錄和數據目錄分開,不要將事務日誌記錄在數據目錄(主要用來存放內存數據庫快照)下。服務器
preAllocSize
:
爲事務日誌預先開闢磁盤空間。默認是64M,意味着每一個事務日誌大小就是64M(能夠去事務日誌目錄中看一下,每一個事務日誌只要被建立出來,就是64M)。若是ZooKeeper產生快照頻率較大,能夠考慮減少這個參數,由於每次快照後都會切換到新的事務日誌,但前面的64M根本就沒寫完。(見snapCount配置項)工具
snapCount
:
ZooKeeper使用事務日誌和快照來持久化每一個事務(注意是日誌先寫)。該配置項指定ZooKeeper在將內存數據庫序列化爲快照以前,須要先寫多少次事務日誌。也就是說,每寫幾回事務日誌,就快照一次。默認值爲100000。爲了防止全部的ZooKeeper服務器節點同時生成快照(通常狀況下,全部實例的配置文件是徹底相同的),當某節點的先寫事務數量在(snapCount/2+1,snapCount)範圍內時(挑選一個隨機值),這個值就是該節點拍快照的時機。日誌
autopurge.snapRetainCount
:
該配置項指定開啓了ZooKeeper的自動清理功能後(見下一個配置項),每次自動清理時要保留的版本數量。默認值爲3,最小值也爲3。它表示在自動清理時,會保留最近3個快照以及這3個快照對應的事務日誌。其它的全部快照和日誌都清理。code
autopurge.purgeInterval
:
指定觸發自動清理功能的時間間隔,單位爲小時,值爲大於或等於1的整數,默認值爲0,表示不開啓自動清理功能。
在ZooKeeper集羣啓動後,當第一個客戶端鏈接到某個服務器節點時,會建立一個會話,這個會話也是事務,因而建立第一個事務日誌,通常名爲log.100000001
,這裏的100000001是此次會話的事務id(zxid)。以後的事務都將寫入到這個文件中,直到拍下一個快照。
若是是事務ZXID5觸發的拍快照,那麼快照名就是snapshot.ZXID5,拍完後,下一個事務的ID就是ZXID6,因而新的事務日誌名爲log.ZXID6。
事務日誌是一個二進制文件,沒法直接查看。好在ZooKeeper提供了一個LogFormatter工具類。
假設ZooKeeper安裝目錄爲/usr/local/zookeeper,那麼能夠經過下面的方法來查看事務日誌log.100000001中的內容。
java -cp /usr/local/zookeeper/zookeeper-3.4.12.jar:/usr/local/zookeeper/lib/slf4j-api-1.7.25.jar org.apache.zookeeper.server.LogFormatter /usr/local/zookeeper/data/version-2/log.100000001
如下是一個事務日誌的內容示例。
從ZooKeeper 3.4.0開始,ZooKeeper提供了自動清理事務日誌和快照的功能,見事務日誌和快照相關的配置項。
此外,還提供了一個腳本zkCleanup.sh,它也用來清理事務日誌和快照。但比較少用。
有時也會寫定時任務腳本,來刪除定時、定點的事務日誌和快照數據。
ZooKeeper使用log4j(log for java)來記錄系統日誌。默認狀況下,系統日誌文件爲ZooKeeper安裝目錄下的zookeeper.out,這是由log4j的配置文件決定的。(實際上,zkEnv.sh和zkServer.sh中也設置了日誌的路徑,見下文)。
ZooKeeper使用的log4j的配置文件爲$ZOOKEEPER_HOME/conf/log4j.properties
。
[root@s1 zk]# cat conf/log4j.properties # Define some default values that can be overridden by system properties zookeeper.root.logger=INFO, CONSOLE zookeeper.console.threshold=INFO zookeeper.log.dir=. # 日誌目錄 zookeeper.log.file=zookeeper.log # 日誌文件名稱 zookeeper.log.threshold=DEBUG zookeeper.tracelog.dir=. zookeeper.tracelog.file=zookeeper_trace.log .....省略.......
log4j.properties中沒有指定zookeeper.out啊?但爲何會輸出到zookeeper.out中呢?這是由於zkServer.sh中指定了這個文件。如下是zkServer.sh中和zookeeper.out相關的內容:
.........省略............. _ZOO_DAEMON_OUT="$ZOO_LOG_DIR/zookeeper.out" case $1 in start) echo -n "Starting zookeeper ... " .........省略............. 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 & .........省略.............
能夠看到,在zkServer.sh的start選項中,使用nohup啓動ZooKeeper,並將日誌輸出到"$ZOO_LOG_DIR/zookeeper.out"中。
通常來講,沒有特殊需求,不必去改log4j日誌配置。要改的話,記得把log4j.properties和zkEnv.sh和zkServer.sh中相關的內容都修改掉。