zoukankan      html  css  js  c++  java
  • 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中相关的内容都修改掉。

  • 相关阅读:
    swoole 查看tcp开启进程数
    详解LRU缓存算法
    glib 双向链表
    清华计算机本科 课表
    glib 单向链表
    通信课程
    基数排序
    glib 数组
    glib 散列表
    清华计算机博士 课表
  • 原文地址:https://www.cnblogs.com/f-ck-need-u/p/9236954.html
Copyright © 2011-2022 走看看