ZKDatabase在内存中维护了zookeeper的sessions, datatree和commit logs集合。 当zookeeper server启动的时候会将txnlogs和snapshots从磁盘读取到内存中。核心逻辑主要在方法ZkDatabase.loadDataBase()中实现,其代码如下:

    /**
* 将数据从磁盘加载到内存中,并将事物添加到内存中的提交日志中
* @return 磁盘上最后一个有效的zxid
* @throws IOException
*/
public long loadDataBase() throws IOException {
PlayBackListener listener=new PlayBackListener(){
public void onTxnLoaded(TxnHeader hdr,Record txn){
Request r = new Request(null, 0, hdr.getCxid(),hdr.getType(),
null, null);
r.txn = txn;
r.hdr = hdr;
r.zxid = hdr.getZxid();
addCommittedProposal(r);
}
}; long zxid = snapLog.restore(dataTree,sessionsWithTimeouts,listener);
initialized = true;
return zxid;
}

loadDataBase的流程如下:

  • 构建一个PlayBackListener对象
  • snapshot的反序列,倒叙排目录下的snapshot文件,遍历查找出最新的那个有效snapshot文件进行反序列化到内存。snapshot的反序列后我们会知道snapshot最新的zxid叫做lastProcessedZxid, 这个lastProcessedZxid之前的事务操作,都成功执行并序列到snapshot中可恢复到内存,lastProcessedZxid之后的操作只有事务日志,不能直接通过snapshot恢复。

snapLog.restore实现如下:

    public long restore(DataTree dt, Map<Long, Integer> sessions,
PlayBackListener listener) throws IOException {
//从最近的快照中对数据树进行反序列化
snapLog.deserialize(dt, sessions);
//lastProcessedZxid+1从事务日志文件txnLog读取事务操作
FileTxnLog txnLog = new FileTxnLog(dataDir);
TxnIterator itr = txnLog.read(dt.lastProcessedZxid+1);
long highestZxid = dt.lastProcessedZxid;
TxnHeader hdr;
try {
while (true) {
//遍历TxnIterator,执行processTransaction方法,就是把事务操作在内存中在执行一遍把丢失的操作补回来
hdr = itr.getHeader();
if (hdr == null) {
//empty logs
return dt.lastProcessedZxid;
}
if (hdr.getZxid() < highestZxid && highestZxid != 0) {
LOG.error("{}(higestZxid) > {}(next log) for type {}",
new Object[] { highestZxid, hdr.getZxid(),
hdr.getType() });
} else {
highestZxid = hdr.getZxid();
}
try {
processTransaction(hdr,dt,sessions, itr.getTxn());
} catch(KeeperException.NoNodeException e) {
throw new IOException("Failed to process transaction type: " +
hdr.getType() + " error: " + e.getMessage(), e);
}
// 同时将事务操作通过PlayBackListener添加到commitedLog集合,commitedLog的事务操作在服务恢复的时候会同步到其他leaner server, 因为很有可能其他leaner server也没有及时的takesnapshot
listener.onTxnLoaded(hdr, itr.getTxn());
if (!itr.next())
break;
}
} finally {
if (itr != null) {
itr.close();
}
}
//返回最后的事务日志zxid给database,作为ZKDatabase的最新事物id
return highestZxid;
}

在zookeeperServer成功loadDatabase后,会及时主动的做一次takesnapshot操作来得到一份最新的内存影像。snapshot是内存数据的某个点一份影像,takeSnapshot操作还是很耗时,为了性能根据一下算法操作:

  • 创建在同步处理器SyncRequestProcessor
  • 100000/2 + random.nextInt(100000/2),这个十万是一个默认值可配置)计算出一个值,如果logCount大于这个值,就进行takeSnapshot操作

上面的算法存在一个问题, 那就是在非正常关机情况下,最新有效的那个snapshot并不是内存中最新的数据,所以需要利用txnLogs来把没有生成snapshot的操作在内存重新执行一边来恢复到非正常关闭服务那一刻内存情况。

Zookeeper原理分析之存储结构ZkDatabase的更多相关文章

  1. Zookeeper原理分析之存储结构Snapshot

    Zookeeper内存结构 Zookeeper数据在内存中的结构类似于linux的目录结构,DataTree代表这个目录结构, DataNode代表一个节点.DataTree默认初始化三个目录:&qu ...

  2. Zookeeper原理分析之存储结构TxnLog

    Zookeeper事物日志文件用于记录事物操作,如添加,删除节点等等,都会在事务日志中记录一条记录.下面我们就详细分析一下txnLog事务日志文件. txnLog事务日志文件文件由三部分组成: 日志文 ...

  3. 1.zookeeper原理解析-数据存储之Zookeeper内存结构

    Zookeeper是怎么存储数据的,什么机制保证集群中数据是一致性,在网络异常,当机以及停电等异常情况下恢复数据的,我们知道数据库给我们提供了这些功能,其实zookeeper也实现了类似数据库的功能. ...

  4. zookeeper原理解析-数据存储

    Zookeeper内存结构 Zookeeper是怎么存储数据的,什么机制保证集群中数据是一致性,在网络异常,当机以及停电等异常情况下恢复数据的,我们知道数据库给我们提供了这些功能,其实zookeepe ...

  5. Hadoop生态圈-Zookeeper的工作原理分析

    Hadoop生态圈-Zookeeper的工作原理分析 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   无论是是Kafka集群,还是producer和consumer都依赖于Zoo ...

  6. Hashtable数据存储结构-遍历规则,Hash类型的复杂度为啥都是O(1)-源码分析

    Hashtable 是一个很常见的数据结构类型,前段时间阿里的面试官说只要搞懂了HashTable,hashMap,HashSet,treeMap,treeSet这几个数据结构,阿里的数据结构面试没问 ...

  7. 牛客网Java刷题知识点之HashMap的实现原理、HashMap的存储结构、HashMap在JDK1.6、JDK1.7、JDK1.8之间的差异以及带来的性能影响

    不多说,直接上干货! 福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号:   大数据躺过的坑      Java从入门到架构师      人工智能躺过的坑          ...

  8. Zookeeper的基本原理(zk架构、zk存储结构、watch机制、独立安装zk、集群间同步复制)

    1.Hbase集群的高可用性与伸缩性 HBase可以实现对Regionserver的监控,当个别Regionserver不可访问时,将其负责的分区分给其他Regionsever,其转移过程较快,因为只 ...

  9. Atitit.数据索引 的种类以及原理实现机制 索引常用的存储结构

    Atitit.数据索引 的种类以及原理实现机制 索引常用的存储结构 1. 索引的分类1 1.1. 按照存储结构划分btree,hash,bitmap,fulltext1 1.2. 索引的类型  按查找 ...

随机推荐

  1. 什么是RNA-Seq (RNA Sequencing)

    什么是RNA-Seq (RNA Sequencing) 2011-07-14 ~ ADMIN 随着ome为词尾的各种组学的出现,转录组学已经成为了人们了解生物信息的一个重要组成部分.人们使用了许多办法 ...

  2. MySQL 开启远程访问权限

    1.登陆mysql数据库    mysql -u root -p 查看user表 mysql> use mysql;Database changedmysql> select host,u ...

  3. nfs文件系统在linux下挂载不上的解决办法

      标签: mount nfs export 2014年08月07日 18:46:247472人阅读 评论(0) 收藏 举报  分类: 文件系统(10)  版权声明:本文为博主原创文章,未经博主允许 ...

  4. 第十届Mockplus ▪ UXPA用户体验西南赛区决赛成功举行

    九月的重庆,秋意渐浓. 伴随着凉爽的秋风,第十届Mockplus·UXPA国际用户体验创新大赛(UXD Award2018)西南赛区决赛于9月16日下午在四川美术学院-虎溪校区成功举办.来自西南区域各 ...

  5. 动词的时态(Les temps du verbe )

    在开始讲解直陈式现在时的主要用法之前,我们有必要先搞清楚两个基本概念:▶语式(mode):语式是动词表达动作的方式.一个动作,可以作为实在的事表达出来,也可以作为希望或单纯设想的事表达出来,法语动词共 ...

  6. Linux学习--2

    字符串 字符串可以用单引号,也可以用双引号,也可以不用引号.单双引号的区别跟PHP类似 单引号字符串的限制:单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的:单引号字串中不能出现单引号(对 ...

  7. 5) mvn archetype:generate

    获取帮助 mvn -h 命令格式 usage: mvn [options] [<goal(s)>] [<phase(s)>] -D,--define <arg> D ...

  8. WPF MediaKit的一点问题

    原版WPF MediaKit在捕获摄像头视频时,如果不使用640*480分分辨率输出,会出现NewVideoSample事件不被触发的问题. 经数日摸索,终于明白SetVideoCapturePara ...

  9. android插件化简述

    2015年是Android插件化技术突飞猛进的一年,随着业务的发展各大厂商都碰到了Android Native平台的瓶颈: 从技术上讲,业务逻辑的复杂导致代码量急剧膨胀,各大厂商陆续出到65535方法 ...

  10. Informatica bulk和normal模式

    转载:http://bestxiaok.iteye.com/blog/1107612 Bulk 方式进行目标数据的Load,是Informatica提供的一种高性能的Load数据方式.它利用数据库底层 ...