spell 发表于 2015-11-21 15:27:30

2.zookeeper原理解析-数据存储之Snapshot

  =====================================斩秋|http://blog.iyunv.com/quhongwei_zhanqiu=======================================
  
  Snapshot是datatree在内存中某一时刻的影像,zookeeper有一定的机制会定时生成datatree的snapshot。FileSnap实现了SnapShot接口负责将数据写入文件中,下面我们来看看snap相关内容。
  2.1 snapshot文件格式
   Snapshot是以二进制形式存在在文件的,我们用ue打开一个新的snapshot文件


  
  Snapshot文件的中数据大体可以分为两部分header和body。

  
  Header数据格式:
FileHeader{
   int    magic//魔数   常量ZKSN代表zookeeper snapshot文件
   int    version//版本常量 2
   long   dbid   //dbid常量 -1
}
这里很奇怪 version和dbid都是常量,那还有什么意思,也许是保留字段为后续版本使用。
  由头部字段可以计算出头部信息占用 4 + 4 + 8 =16bit的固定长度
  5A 4B 53 4E 就是魔术ZKSN
  00 00 00 02 就是dbid号2
FF FF FF FF FF FF FF FF就是十六进制的-1
  

  
  Body数据格式:
  Snapshot文件中头部信息之后,紧接着就是body部分的信息,body数据大小是动态不是固定。
  1) Map<Long, Integer> sessionWithTimeoutbody信息前面部分存储的是内存中活着的session以及session的超时时间
oa.writeInt(sessSnap.size(),&quot;count&quot;);
      for (Entry<Long, Integer> entry :sessSnap.entrySet()) {
         oa.writeLong(entry.getKey().longValue(), &quot;id&quot;);
            oa.writeInt(entry.getValue().intValue(),&quot;timeout&quot;);
      }
  由上面序列到文件代码可以看出先写入一个int类型字段用来存储sessionWithTimeout的个数,然后在遍历集合以一个long一个int的形式写入
  2) 紧接着就是对datatree序列化到文件了
  我们看下datatree的序列化方法
public voidserialize(OutputArchive oa, String tag) throws IOException {
      scount = 0;
      serializeList(longKeyMap, oa);
      serializeNode(oa, newStringBuilder(&quot;&quot;));
      if (root != null) {
            oa.writeString(&quot;/&quot;,&quot;path&quot;);
      }
    }
2.1)序列化longKeyMap是存储在datatree中的acl权限集合
  readInt(&quot;map&quot;) //acl的映射个数?
  while (map > 0) {
  readLong(&quot;long&quot;) //这个long值longKeyMap的key,作用?是这一组acl的key
  readInt(&quot;acls&quot;)
  while (acls) {
  readInt(&quot;perms&quot;)
  readString(&quot;scheme&quot;)
  readString(&quot;id&quot;)
  }
  }

2.2)存储datatree中数据节点
      readString(&quot;path&quot;)//第一个datanode &quot;&quot;
    while(!path.equals(&quot;/&quot;)) {   //&quot;/&quot;代表路径结束      
         readRecord(node, &quot;node&quot;)包括:
         readBuffer(&quot;data&quot;)
         readLong(&quot;acl&quot;)
         deserialize(archive,&quot;statpersisted&quot;) 状态存储包括:
                        readLong(&quot;czxid&quot;)//createNode时事务号
                            readLong(&quot;mzxid&quot;)//createNode时与Czxid同,setData时的事务号
                            readLong(&quot;ctime&quot;)// 创建节点时间
                            readLong(&quot;mtime&quot;)//createNode时与ctime相同,setData时间
                            readInt(&quot;version&quot;)//createNode版本为0,setData的数据版本号
                            readInt(&quot;cversion&quot;) //createNode版本为0,增加/删除子节点时父节点&#43;1
                            readInt(&quot;aversion&quot;) //createNode版本为0,setACL时节点的版本号
                            readLong(&quot;ephemeralOwner&quot;) // 临时节点表示sessionid,非临时节点这个值为0
                            readLong(&quot;pzxid&quot;)//createNode时与Czxid同,增加/删除子节点时为子节点事务号

      readString(&quot;path&quot;) //读取下一个路径
}
3)文件尾部校验数据
00 00 00 01 2Fsnapshot文件结尾5位数据用来校验snapshot文件是否有效
   00 00 00 01一个int的数值就是数字1,代表后面1一个字符数据
   2F 就是snapshot的结束符/

4)Snapshot序列化

  

  5)Snapshot反序列化
  

  

  =====================================斩秋|http://blog.iyunv.com/quhongwei_zhanqiu=======================================
页: [1]
查看完整版本: 2.zookeeper原理解析-数据存储之Snapshot