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. ubuntu and centos各种上网代理设置

    1.Ubuntu 一. apt-get 代理设置 由于公司通过代理上网,firefox的代理设置很容易就搞定了,但是通过apt-get安装软件还是不行,于是,查阅了很多资料,最多的方法就是网上流传的三 ...

  2. Nginx的使用(反向代理,负载均衡)

    在我目前的工作内容中,接触到Nginx的用处无外乎两点: 1. 反向代理,解决前端跨域的问题 工作内容有门户的概念,就是将各个子系统集成到门户里,在门户里面访问,这样就很容易造成跨域的问题 那么解决的 ...

  3. Spring boot 出现的时间

    Spring 4.0 ~ 4.3 不管商业操作如何,Spring还是继续发展, 2013年12月, Spring4.0 发布,这个版本开始支持JDK8 , 甚至比JDK8 的GA版本还要早3个月! 2 ...

  4. RESTful Web API 实践

    REST 概念来源 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备...). 因此,必须有一种统一的机制,方便不同的前端设备与后端进行通 ...

  5. IntellJ IDEA javax.servlet.ServletException 找不到javax.servlet.ServletException的类 java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory

    误状态:错误显示 解决: (1)说明缺少包---->添加如下包配置 <dependency> <groupId>javax.servlet.jsp</groupId ...

  6. java.lang.String cannot be cast to java.util.Date

    我这个是个新建的功能,然后在保存的时候出现了这个错误.然后就找到了新建的action,发现其上的list方法出了问题. 这样是正确的.之前list<Constract>写成这样了.

  7. SPSS-多重响应-频率和交叉表案例分析(问卷调查分析)

    在10.1休假前,希望跟大家讨论一下SPSS-多重响应--频率和交叉表分析,希望大家能够多提点提点 在云南电信网上营业厅做了一个关于“客户不使用电信3g业务的原因有哪些的问卷调查,问题所示: 这份问卷 ...

  8. Andfix热修复原理

    一.前言 最近腾讯弄出一个Tinker热修复框架,那么本文先不介绍这个框架,先来介绍一下阿里的一个热修复框架AndFix,这个框架出来已经很长时间了,但是看网上没有太多非常详细的讲解,这里就来做一次分 ...

  9. hdu 1058

    这道题有很多种做法,但是思路大都是一样的,代码有点类似于poj2591这道题. 题意:问因子只含有2,3,5,7的第k个数是什么? #include<stdio.h> int f[5843 ...

  10. hdu 5012 模拟+bfs

    http://acm.hdu.edu.cn/showproblem.php?pid=5012 模拟出骰子四种反转方式,bfs,最多不会走超过6步 #include <cstdio> #in ...