Zookeeper原理分析之存储结构ZkDatabase
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的更多相关文章
- Zookeeper原理分析之存储结构Snapshot
Zookeeper内存结构 Zookeeper数据在内存中的结构类似于linux的目录结构,DataTree代表这个目录结构, DataNode代表一个节点.DataTree默认初始化三个目录:&qu ...
- Zookeeper原理分析之存储结构TxnLog
Zookeeper事物日志文件用于记录事物操作,如添加,删除节点等等,都会在事务日志中记录一条记录.下面我们就详细分析一下txnLog事务日志文件. txnLog事务日志文件文件由三部分组成: 日志文 ...
- 1.zookeeper原理解析-数据存储之Zookeeper内存结构
Zookeeper是怎么存储数据的,什么机制保证集群中数据是一致性,在网络异常,当机以及停电等异常情况下恢复数据的,我们知道数据库给我们提供了这些功能,其实zookeeper也实现了类似数据库的功能. ...
- zookeeper原理解析-数据存储
Zookeeper内存结构 Zookeeper是怎么存储数据的,什么机制保证集群中数据是一致性,在网络异常,当机以及停电等异常情况下恢复数据的,我们知道数据库给我们提供了这些功能,其实zookeepe ...
- Hadoop生态圈-Zookeeper的工作原理分析
Hadoop生态圈-Zookeeper的工作原理分析 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 无论是是Kafka集群,还是producer和consumer都依赖于Zoo ...
- Hashtable数据存储结构-遍历规则,Hash类型的复杂度为啥都是O(1)-源码分析
Hashtable 是一个很常见的数据结构类型,前段时间阿里的面试官说只要搞懂了HashTable,hashMap,HashSet,treeMap,treeSet这几个数据结构,阿里的数据结构面试没问 ...
- 牛客网Java刷题知识点之HashMap的实现原理、HashMap的存储结构、HashMap在JDK1.6、JDK1.7、JDK1.8之间的差异以及带来的性能影响
不多说,直接上干货! 福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号: 大数据躺过的坑 Java从入门到架构师 人工智能躺过的坑 ...
- Zookeeper的基本原理(zk架构、zk存储结构、watch机制、独立安装zk、集群间同步复制)
1.Hbase集群的高可用性与伸缩性 HBase可以实现对Regionserver的监控,当个别Regionserver不可访问时,将其负责的分区分给其他Regionsever,其转移过程较快,因为只 ...
- Atitit.数据索引 的种类以及原理实现机制 索引常用的存储结构
Atitit.数据索引 的种类以及原理实现机制 索引常用的存储结构 1. 索引的分类1 1.1. 按照存储结构划分btree,hash,bitmap,fulltext1 1.2. 索引的类型 按查找 ...
随机推荐
- 教你如何制作饼干icon教程
Hello,不露又和大家见面了,今天给大家带来的是一个可爱Q弹的icon~ 看起来像块饼干是吧~ 做起来非常简单哦,快打开PS一起躁起来吧. 先来看看效果图: 步骤1:打开PS,新建一个800*600 ...
- 关闭文件描述符-close
头文件:#include<unistd.h> 原型:int close(int fd); 返回值:成功返回0,失败返回-1.
- spring-data-jpa+hibernate 各种缓存的配置演示
本文所有测试用代码在https://github.com/wwlleo0730/restjplat 的分支addDB上 目前在使用spring-data-jpa和hibernate4的时候,对于缓存关 ...
- 2018.10.20 NOIP模拟 蛋糕(线段树+贪心/lis)
传送门 听说是最长反链衍生出的对偶定理就能秒了. 本蒟蒻直接用线段树模拟维护的. 对于第一维排序. 维护第二维的偏序关系可以借助线段树/树状数组维护逆序对的思想建立权值线段树贪心求解. 代码
- 2018.08.10 atcoder Median Sum(01背包)
传送门 题意简述:输入一个数组an" role="presentation" style="position: relative;">anan. ...
- hdu-1124(数学问题,求n!的尾零的个数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1124 思路:每五个数1个0,5个5就2个0(不用管2,一定充足) #include<iostre ...
- 关于EmitMapper,映射配置
public static T Snapshoot<T>(this XtraForm form, T obj) { var config = new DefaultMapConfig(); ...
- day3之文件操作
一,文件操作基本流程. # 1.打开文件,产生文件句柄 # 2.操作文件句柄 # 3.关闭文件句柄 # f1 = open('11.txt',encoding='utf-8', mode='r') # ...
- 使用process_monitor.sh监控hadoop进程的crontab配置
可以从下列链接找到process_monitor.sh:https://github.com/eyjian/libmooon/blob/master/shell/process_monitor.sh ...
- 常见的it软件默认端口
tomcat:8080 nginx:80 mysql:3306 oracle:1521 nexus:8081 浏览器:80 redis:6379 solr:tomcat部署默认8080 jetty部署 ...