• Zookeeper数据存储总结


    Zookeeper快照文件和事物操作文件以文件的形式存储在硬盘上,以快照文件为主,日志文件为辅。因为当对内存数据进行变更的时候,会保证将事务操作记入log日志,而snapshot只是内存某一个时刻影像,为了性能takeSnapshot生成snapshot并不是实时的,而是由后台线程根据一定规则处理的。详细可参考上一篇文章。

    快照文件和事物操作文件在磁盘上如下所示:

    -rw-rw-r-- 1 ysl ysl  67108880 10月 23 17:43 log.1
    -rw-rw-r-- 1 ysl ysl  67108880 11月  7 16:45 log.9b6
    -rw-rw-r-- 1 ysl ysl  67108880 1月  15 17:22 log.c99a
    -rw-rw-r-- 1 ysl ysl  67108880 1月  16 09:10 log.ca33
    -rw-rw-r-- 1 ysl ysl  67108880 1月  17 11:09 log.ca45
    -rw-rw-r-- 1 ysl ysl  67108880 1月  18 12:00 log.ca4c
    -rw-rw-r-- 1 ysl ysl  67108880 1月  24 17:59 log.ca52
    -rw-rw-r-- 1 ysl ysl  67108880 11月  8 16:34 log.ca8
    -rw-rw-r-- 1 ysl ysl  67108880 11月  9 17:32 log.d16
    -rw-rw-r-- 1 ysl ysl  67108880 1月  30 15:44 log.d172
    -rw-rw-r-- 1 ysl ysl  67108880 2月   1 11:52 log.d18d
    -rw-rw-r-- 1 ysl ysl  67108880 2月   2 10:10 log.d1aa
    -rw-rw-r-- 1 ysl ysl  67108880 11月 10 16:20 log.d88
    -rw-rw-r-- 1 ysl ysl       296 10月 23 12:20 snapshot.0
    -rw-rw-r-- 1 ysl ysl      6746 11月 13 09:14 snapshot.104d
    -rw-rw-r-- 1 ysl ysl      6746 11月 14 11:00 snapshot.1461
    -rw-rw-r-- 1 ysl ysl      5059 10月 24 12:11 snapshot.14f
    -rw-rw-r-- 1 ysl ysl      5349 10月 25 10:04 snapshot.20a
    -rw-rw-r-- 1 ysl ysl      5277 10月 25 10:21 snapshot.210
    -rw-rw-r-- 1 ysl ysl      5277 10月 27 14:10 snapshot.21c
    -rw-rw-r-- 1 ysl ysl      5349 10月 30 09:17 snapshot.30d
    -rw-rw-r-- 1 ysl ysl      5277 10月 30 11:21 snapshot.313
    

    以上文件名是以log.或者snapshot.加上一串long的16进制数字组成,这个long值就是zxid服务器端事务id。Snapshot文件名生成逻辑在 FileTxnSnapLog.save方法中,如下:

        public void save(DataTree dataTree,
                ConcurrentHashMap<Long, Integer> sessionsWithTimeouts)
            throws IOException {
            long lastZxid = dataTree.lastProcessedZxid;
            File snapshotFile = new File(snapDir, Util.makeSnapshotName(lastZxid));
    	........
        }
    

    Util.makeSnapshotName用于生成文件名称

        public static String makeSnapshotName(long zxid) {
    	//返回文件名称
            return "snapshot." + Long.toHexString(zxid);
        }
    

    日志Log文件生成,在FileTxnLog.apend方法中,如果被执行了rollLog方法,那么文件输入流会被清空,这里会创建一个新的文件

    if (logStream==null) {
           if(LOG.isInfoEnabled()){
                LOG.info("Creating new log file: log." +  
                        Long.toHexString(hdr.getZxid()));
           }
           
           logFileWrite = new File(logDir, ("log." + 
                   Long.toHexString(hdr.getZxid())));
           fos = new FileOutputStream(logFileWrite);
           logStream=new BufferedOutputStream(fos);
           .........
        }
    

    当客户端请求一个事物操作时,leader的PrepRequestProcessor处理器会对请求进行预处理包括生成zxid设置到请求中去,zxid的生成是通过调用ZookeeperServer.getNextZxid生成:

        long getNextZxid() {
            return hzxid.incrementAndGet();
        }
    

    它是hzxid一个自增的long值,有没有奇怪这个变量取名叫做hzixd多了一个h, h我的理解是high的缩写代表64位long的高32位。Zxid的分为两部分高32位用来存储每次选举的时代epoch,低32位用来存储事务请求的自增序列。所谓选举时代就是一个数值,标记代表一次选举,跟年份一样是自增的。每次服务器启动或者zookeeper异常导致重新选举都会在原来epoch值加一代表一个新的时代,工具类ZxidUtils用来操作前32或者后32位。比如现在epoch=4代表经历了4次选举,如果重新选举后epoch值为5,通过工具类的zxid=hzxid=ZxidUtils.makeZxid(5,0)= 21474836480,此时低32重新开始值为0, 如果这时来了新的请求值为zxid=21474836481=21474836480+ 1 = ZxidUtils.makeZxid(5, 1)。

    public class ZxidUtils {
    	static public long getEpochFromZxid(long zxid) {
    		return zxid >> 32L;
    	}
    	static public long getCounterFromZxid(long zxid) {
    		return zxid & 0xffffffffL;
    	}
    	static public long makeZxid(long epoch, long counter) {
    		return (epoch << 32L) | (counter & 0xffffffffL);
    	}
    	static public String zxidToString(long zxid) {
    		return Long.toHexString(zxid);
    	}
    }
    
  • 相关阅读:
    移动银盘 文件或目录损坏且无法读取 提示格式化
    error: Some data has already been output, can't send PDF file
    php pdf english french duch……应用攻略,ufpdf
    photoshop cs4 多语言
    c++常用知识小结
    简单的排序
    内存对齐
    socket网络编程常用的结构及函数小结
    字符和字符串处理小结
    几个小程序
  • 原文地址:https://www.cnblogs.com/senlinyang/p/8416766.html
Copyright © 2020-2023  润新知