ZooKeeper学习之文件系统的布局和格式
本文来谈谈快照文件,事务日志文件在文件系统中是如何存放的。
写事务日志是事务处理的关键步骤,所以高度建议在一个独立的磁盘上存储。快照不需要在独立的磁盘存储,因为它们是由一个后台线程以懒汉式的(lazily)方式产生的。
存储快照的路径是由DataDir参数指定的,事务日志的路径则是由DataLogDir参数指定的。首先来看看事务日志的目录。如果你查看目录的内容,你会看到一个名为version-2的文件夹。对于日志和快照现在只有一种格式,如果有别的版本的格式,像这样按照格式的版本把数据隔离开来,对于日后不同版本的数据迁移会比较方便。
事务日志
在执行一些测试之后,看一下目录的情况,只有两个事务日志文件:
-rw-r--r-- 1 breed 67108880 Jun 5 22:12 log.100000001
-rw-r--r-- 1 breed 67108880 Jul 15 21:37 log.200000001
来观察一下,首先,它们有些大,每个文件大约有6M,执行的测试其实挺少。第二,文件名的后缀的那个数字很大。
ZK为文件预分配了相当大的块(chunk)来避免每次写文件带来的元数据的管理开销。如果你用16进制dump这些文件的话,会看到都是一些null字符(\0字符),除了文件开头的一些数据二进制数据之外。当server跑了一段时间后,这些null字符会被实际的日志数据取代。
文件名后缀的那个数字是zxid,可以很容易的进行recovery并能快速查找,这个zxid是日志文件的第一个zxid,并且是16进制的。之所以用16进制是因为可以容易的看到epoch和counter。所以第一个文件属于epoch 1,第二个属于epoch 2。
如果能看到文件内部的数据当然更好了,这在需要定位问题的时候很有必要的。开发人员需要花很多时间去调查为何ZK丢失了znode的数据,只有通过查看事务日志,才能知道是不是被client删除了。
我们可以用下面的命令查看第二个日志文件:
- java -cp $ZK_LIBS org.apache.zookeeper.server.LogFormatter version-2 log.200000001
输出如下:
7/15/13... session 0x13...00 cxid 0x0 zxid 0x200000001 createSession 30000
7/15/13... session 0x13...00 cxid 0x2 zxid 0x200000002 create
'/test,#22746573746 ...
7/15/13... session 0x13...00 cxid 0x3 zxid 0x200000003 create
'/test/c1,#6368696c ...
7/15/13... session 0x13...00 cxid 0x4 zxid 0x200000004 create
'/test/c2,#6368696c ...
7/15/13... session 0x13...00 cxid 0x5 zxid 0x200000005 create
'/test/c3,#6368696c ...
7/15/13... session 0x13...00 cxid 0x0 zxid 0x200000006 closeSession null
每一个事务都以人类可读的方式打印出来。因为在事务中只有change操作,所以你不会看到read操作。
快照
快照的命名模式跟事务日志的模式类似。这是配合事务日志的一个例子:
-rw-r--r-- 1 br33d 296 Jun 5 07:49 snapshot.0
-rw-r--r-- 1 br33d 415 Jul 15 21:33 snapshot.100000009
快照文件没有进行预分配,所以size正确的反映了实际的数据量。使用的后缀反映了当快照开始时当前的zxid。前面的文章说过,快照文件实际上是fuzzy的。快照数据只有在对应的事务日志重放后才是正确的。为了恢复数据,必须重放一个快照文件后缀之后的事务日志。
快照文件是使用二进制的形式存储,这儿有另一个工具来解析快照文件:
- java -cp ZK_LIBS org.apache.zookeeper.server.SnapshotFormatter version-2 snapshot.100000009
输出如下:
----
/
cZxid = 0x00000000000000
ctime = Wed Dec 31 16:00:00 PST 1969
mZxid = 0x00000000000000
mtime = Wed Dec 31 16:00:00 PST 1969
pZxid = 0x00000100000002
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x00000000000000
dataLength = 0
----
/sasd
cZxid = 0x00000100000002
ctime = Wed Jun 05 07:50:56 PDT 2013
mZxid = 0x00000100000002
mtime = Wed Jun 05 07:50:56 PDT 2013
pZxid = 0x00000100000002
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x00000000000000
dataLength = 3
----
只dump出每个znode的元数据。这可以让管理员找出那些znode的数据被改变过,那些znode占用了大量内存。不幸的是,znode的数据和ACL不会打印。还要记得定位问题时,一定要使用快照和它对应的日志文件的合并后的数据。
Epoch文件
此外还有2个小文件来构成ZK状态的持久化。有2个epoch文件,分别是acceptedEpoch和currentEpoch。这两个文件分别反映了指定的server进程已经看到的和参与的epoch number。尽管这些文件不包含任何应用级别的数据,但他们对于数据一致性来说很重要,所以在你对数据文件进行备份时,不要漏掉这2个文件。
使用ZK的数据
无论是standalone模式还是集群模式,都是用同样的方式来存储数据的。我们刚才只提到如果通过合并快照和日志来得到正确的数据。你可以拷贝日志文件和快照文件到另外一个机器上,比如你的笔记本电脑,把它们放到一个standalone模式下的干净的数据目录,并启动server,数据就会在这个server上重现。这可以让你看到近似于生产环境的服务上的数据。这也意味着你可以简单的拷贝文件来轻松的备份。如果你选择这种做法需要注意一些事情。首先,ZK得分布式部署,这样数据就会有冗余。做备份的时候,只需要备份其中一个server的数据即可。
一定要记住当一个ZK server ack一个事务时,之后它会承诺记住当时的状态。所以如果你使用一份老的备份数据恢复一台server时,你就使得这个server违反了它的承诺。如果你刚遭受了一个全局性的数据丢失的话这并不是大问题,但如果你在正常工作的集群中一台server放入老的数据,这可能会导致其他的server丢失状态。
如果你想对所有server或者大多数server做数据恢复,最好的做法就是获取最新的状态(从存活的机器中取得的最新(up-to-date)的数据),在启动每个server之前拷贝到对应的数据目录下。
ZooKeeper学习之文件系统的布局和格式的更多相关文章
- [转]ZooKeeper学习第一期---Zookeeper简单介绍
ZooKeeper学习第一期---Zookeeper简单介绍 http://www.cnblogs.com/sunddenly/p/4033574.html 一.分布式协调技术 在给大家介绍ZooKe ...
- ZooKeeper 学习笔记
ZooKeeper学习笔记 1. zookeeper基本概念 zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是hadoop和Habase的重要组件,是为分布式应用提供一致性服 ...
- 【分布式】ZooKeeper学习之一:安装及命令行使用
ZooKeeper学习之一:安装及命令行使用 一直都想着好好学一学分布式系统,但是这拖延症晚期也是没得治了,所以干脆强迫自己来写一个系列博客,从zk的安装使用.客户端调用.涉及到的分布式原理.选举过程 ...
- ZooKeeper学习笔记(一)——概述
zookeeper学习笔记(一)--概述 1. 概述 Zookeeper是一个开源的分布式的,为分布式应用提供协调服务的Apache项目.zookeeper从设计模式的角度来理解:是一个基于观察者设计 ...
- Zookeeper学习笔记(中)
Zookeeper学习笔记(中) Zookeeper的基本原理和基本实现 深入了解ZK的基本原理 ZK的一致性: ZAB 协议: Zookeeper 原子消息广播协议 ZK通过选举保证 leader ...
- zookeeper学习(上)
zookeeper学习(上) 在前面的文章里我多次提到zookeeper对于分布式系统开发的重要性,因此对zookeeper的学习是非常必要的.本篇博文主要是讲解zookeeper的安装和zookee ...
- Flutter学习指南:UI布局和控件
Flutter学习指南:UI布局和控件 - IT程序猿 https://www.itcodemonkey.com/article/11041.html
- zookeeper 学习资料
zookeeper 学习资料 学习资料 网址 Zookeeper 教程(菜鸟教程) https://www.w3cschool.cn/zookeeper/
- Spring MVC 学习笔记11 —— 后端返回json格式数据
Spring MVC 学习笔记11 -- 后端返回json格式数据 我们常常听说json数据,首先,什么是json数据,总结起来,有以下几点: 1. JSON的全称是"JavaScript ...
随机推荐
- java struts2入门学习实例--使用struts2快速实现上传
一.文件上传快速入门 1).关于上传表单三要素 >>尽量以POST请求方式上传,因为GET支持文件大小是有限制的. >>必须要加上enctype="multipart ...
- Lua初学
Lua很火啊,而且跟C,c++可以无缝结合,表示很给力,算是我的第三门语言吧,哈哈! 在官网上下载了源码了,和windows版的,表示编译器也很给力,直接可以用SciTE就可以写代码了. a = 1; ...
- SaltStack 入门到精通第三篇:Salt-Minion配置文件详解
SaltStack 入门到精通第三篇:Salt-Minion配置文件详解 作者:ArlenJ 发布日期:2014-06-09 17:52:16 ##### 主要配置设置 ##### 配置 默认值 ...
- c运行库、c标准库、windows API的区别和联系
C运行时库函数C运行时库函数是指C语言本身支持的一些基本函数,通常是汇编直接实现的. API函数API函数是操作系统为方便用户设计应用程序而提供的实现特定功能的函数,API函数也是C语言的函数实现的 ...
- Docker K8s基本概念入门
原文地址:https://blog.csdn.net/TM6zNf87MDG7Bo/article/details/79621510 k8s是一个编排容器的工具,其实也是管理应用的全生命周期的一个工具 ...
- redis常用性能分析命令
一.连接 src/redis-cli -h 10.20.137.141 -p 6379 >auth 123456789 src/redis-cli -h 10.20.137.141 -p 637 ...
- Spring MVC @PathVariable被截断
一.问题描述 一个控制器提供RESTful访问信息: @RequestMapping(method = RequestMethod.GET, value = Routes.BLAH_GET + &qu ...
- html5 ajax 文件上传
http://html5demos.com/dnd-upload 看这个例子看了一会儿...这个是支持拖拽的上传. 下面代码是一个简单的ajax的文件上传: function match(url,rs ...
- mysql使用GROUP BY分组实现取前N条记录的方法
MySQL中GROUP BY分组取前N条记录实现 mysql分组,取记录 GROUP BY之后如何取每组的前两位下面我来讲述mysql中GROUP BY分组取前N条记录实现方法. 这是测试表(也不知道 ...
- Oracle 12C -- Plug in a Non-CDB as a PDB
1.备份non-CDB数据库2.关闭non-CDB数据库 SQL> shutdown immediate; 3.将non-CDB至于只读状态 SQL> startup open read ...