首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

zookeeper原理解析-数据存储(2)

zookeeper原理解析-数据存储(2)

我们看下datatree的序列化方法


4)Snapshot序列化



5)Snapshot反序列化

5)TxnLog事务日志
事务日志文件用来记录事物操作,每一个事务操作如添加,删除节点等等,都会在事务日志中记录一条记录,用来在zookeeper异常情况下,通过txnlog和snapshot文件来恢复数据,下面我们来看下txnLog事务日志文件的格式
打开一个事务日志文件看看



一个日志文件LogFile: FileHeader TxnList ZeroPad三部分组成
1)   日志文件头FileHeader: {
magic   4bytes (ZKLG) //常量代表
version 4bytes        //常量2
dbid     8bytes        //这个没啥用,就是默认值0
}
头文件是固定长度 16  = 4 + 4 + 8数据,它的值也固定
2)   TxnList代表记录记录集合,txn代表一条记录
Txn:checksum Txnlen TxnHeaderRecord 0x42由顺序的五部分组成
           //序列化TxnHeader Record记录到byte[]

byte[] buf = Util.marshallTxnEntry(hdr, txn);

        Checksum crc = makeChecksumAlgorithm();

        //根据指定数组更新校验值

crc.update(buf, 0, buf.length);

        //将校验吗写入输出流

oa.writeLong(crc.getValue(), "txnEntryCRC");

        //将TxnHeader Record数据写入到输出流

                   //1.先计算buf数据长度写入

                   //2.写入buf数组数据

                   //3.记录尾部以’B’字符结尾,写入0x42

Util.writeTxnBytes(oa, buf);           

2.1) checksum校验位计算,是由Adler32校验 计算TxnHeader Record序列化后的字节码(跟文档说明有出入,文档说是由Txnlen TxnHeaderRecord 0x42计算出来的, 可是看代码不是,难道我理解错了????????)
2.2) TxnLen:记录数据长度包括记录头TxnHeader和记录Record

2.3)TxnHeader: {

                    sessionid 8bytes

                    cxid 4bytes  // 与客户端交互的xid

                    zxid 8bytes  // 服务器端生成的事务id

                    time 8bytes  // 时间

                    type 4bytes  // 事务操作的类型

             }

2.4)Record:事务记录的内容,由jute规范定义了序列化反序列化流程,各个事务操作都实现了Record接口,下面看下创建的事务操作记录

                   public class CreateTxn implements Record {

                         privateString path;  //创建路径

                         privatebyte[] data;  //节点数据内容

                         privatejava.util.List<org.apache.zookeeper.data.ACL> acl; //节点权限

                         privateboolean ephemeral; //是否临时节点

                         privateint parentCVersion; //父节点的版本号

                            //下面过程就是序列化过程,反序列化类似

                        publicvoid serialize(OutputArchive a_, String tag) throws  .io.IOException {

                                a_.startRecord(this,tag);

                                 a_.writeString(path,"path");

                                a_.writeBuffer(data,"data");

                                 {

                                       a_.startVector(acl,"acl");

                                       if(acl!= null) {          int len1 =acl.size();

                                          for(int vidx1 = 0; vidx1<len1;vidx1++) {

                                                 org.apache.zookeeper.data.ACL e1 = (org.apache.zookeeper.data.ACL)acl.get(vidx1);

                                              a_.writeRecord(e1,"e1");

                                          }

                                      }

                                      a_.endVector(acl,"acl");

                                }

                                a_.writeBool(ephemeral,"ephemeral");

                                a_.writeInt(parentCVersion,"parentCVersion");

                                a_.endRecord(this,tag);

                         }

2.5)0x42:每条事务记录尾部以’B’字符结尾就是0x42

3) 每个文件尾部都用一个字符 0 填充, 工具Util.padLogFile扩充文件的时候在尾部填写上
返回列表