ZooKeeper系列(5):ZooKeeper的日志和快照


ZooKeeper系列文章:https://www.cnblogs.com/f-ck-need-u/p/7576137.html#zk

 


ZooKeeper有兩種日志、一種快照。日志分為事務日志和ZooKeeper運行時的系統日志。

1.事務日志和快照

ZooKeeper集群中的每個服務器節點每次接收到寫操作請求時,都會先將這次請求發送給leader,leader將這次寫操作轉換為帶有狀態的事務,然后leader會對這次寫操作廣播出去以便進行協調。當協調通過(大多數節點允許這次寫)后,leader通知所有的服務器節點,讓它們將這次寫操作應用到內存數據庫中,並將其記錄到事務日志中。

當事務日志記錄的次數達到一定數量后(默認10W次),就會將內存數據庫序列化一次,使其持久化保存到磁盤上,序列化后的文件稱為"快照文件"。每次拍快照都會生成新的事務日志。

有了事務日志和快照,就可以讓任意節點恢復到任意時間點(只要沒有清理事務日志和快照)。

1.1 事務日志和快照相關的配置項

  • dataDir
    ZooKeeper的數據目錄,主要目的是存儲內存數據庫序列化后的快照路徑。如果沒有配置事務日志(即dataLogDir配置項)的路徑,那么ZooKeeper的事務日志也存放在數據目錄中。

  • 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個快照對應的事務日志。其它的所有快照和日志都清理。

  • autopurge.purgeInterval
    指定觸發自動清理功能的時間間隔,單位為小時,值為大於或等於1的整數,默認值為0,表示不開啟自動清理功能。

1.2 事務日志和快照的命名規則

在ZooKeeper集群啟動后,當第一個客戶端連接到某個服務器節點時,會創建一個會話,這個會話也是事務,於是創建第一個事務日志,一般名為log.100000001,這里的100000001是這次會話的事務id(zxid)。之后的事務都將寫入到這個文件中,直到拍下一個快照。

如果是事務ZXID5觸發的拍快照,那么快照名就是snapshot.ZXID5,拍完后,下一個事務的ID就是ZXID6,於是新的事務日志名為log.ZXID6。

1.3 查看事務日志

事務日志是一個二進制文件,無法直接查看。好在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

以下是一個事務日志的內容示例。

1.4 自動清理功能

從ZooKeeper 3.4.0開始,ZooKeeper提供了自動清理事務日志和快照的功能,見事務日志和快照相關的配置項

此外,還提供了一個腳本zkCleanup.sh,它也用來清理事務日志和快照。但比較少用。

有時也會寫定時任務腳本,來刪除定時、定點的事務日志和快照數據。

2.ZooKeeper系統的系統日志

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中相關的內容都修改掉。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM