本文来谈谈快照文件,事务日志文件在文件系统中是如何存放的。

写事务日志是事务处理的关键步骤,所以高度建议在一个独立的磁盘上存储。快照不需要在独立的磁盘存储,因为它们是由一个后台线程以懒汉式的(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删除了。

我们可以用下面的命令查看第二个日志文件:

  1. 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的。快照数据只有在对应的事务日志重放后才是正确的。为了恢复数据,必须重放一个快照文件后缀之后的事务日志。

快照文件是使用二进制的形式存储,这儿有另一个工具来解析快照文件:

  1. 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学习之文件系统的布局和格式的更多相关文章

  1. [转]ZooKeeper学习第一期---Zookeeper简单介绍

    ZooKeeper学习第一期---Zookeeper简单介绍 http://www.cnblogs.com/sunddenly/p/4033574.html 一.分布式协调技术 在给大家介绍ZooKe ...

  2. ZooKeeper 学习笔记

    ZooKeeper学习笔记 1.   zookeeper基本概念 zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是hadoop和Habase的重要组件,是为分布式应用提供一致性服 ...

  3. 【分布式】ZooKeeper学习之一:安装及命令行使用

    ZooKeeper学习之一:安装及命令行使用 一直都想着好好学一学分布式系统,但是这拖延症晚期也是没得治了,所以干脆强迫自己来写一个系列博客,从zk的安装使用.客户端调用.涉及到的分布式原理.选举过程 ...

  4. ZooKeeper学习笔记(一)——概述

    zookeeper学习笔记(一)--概述 1. 概述 Zookeeper是一个开源的分布式的,为分布式应用提供协调服务的Apache项目.zookeeper从设计模式的角度来理解:是一个基于观察者设计 ...

  5. Zookeeper学习笔记(中)

    Zookeeper学习笔记(中) Zookeeper的基本原理和基本实现 深入了解ZK的基本原理 ZK的一致性: ZAB 协议: Zookeeper 原子消息广播协议 ZK通过选举保证 leader ...

  6. zookeeper学习(上)

    zookeeper学习(上) 在前面的文章里我多次提到zookeeper对于分布式系统开发的重要性,因此对zookeeper的学习是非常必要的.本篇博文主要是讲解zookeeper的安装和zookee ...

  7. Flutter学习指南:UI布局和控件

    Flutter学习指南:UI布局和控件 - IT程序猿  https://www.itcodemonkey.com/article/11041.html

  8. zookeeper 学习资料

    zookeeper 学习资料 学习资料 网址 Zookeeper 教程(菜鸟教程) https://www.w3cschool.cn/zookeeper/

  9. Spring MVC 学习笔记11 —— 后端返回json格式数据

    Spring MVC 学习笔记11 -- 后端返回json格式数据 我们常常听说json数据,首先,什么是json数据,总结起来,有以下几点: 1. JSON的全称是"JavaScript ...

随机推荐

  1. android开发学习---开发一个简易的短信发送器

    一.需求: 开发一个简易的短信发送器,输入:对方手机号码,短信内容,点击发送按钮,短信发送成功,对方手机成功收到短信. 其中要求短信内容过长时可以自动拆分,长度英文是160个英文,中文是70个,中英混 ...

  2. angularJS实现无刷新文件下载

    $scope.getExcel = function () { $http.post("/production/statistics/export", { storeId: $sc ...

  3. nginx 实现valid_referer全面解析

    先来补充点知识,然后在进行讲解. 先看下两种HTTP head 一个是直接输入网址打开的head,另一个是通过搜索引擎打开的网址head 一:直接输入网址打开的 (Request-Line)  GET ...

  4. XSS安全处理

    Security.class.php文件 <?php class Security { public $filename_bad_chars = array( '../', '<!--', ...

  5. c# 4.0 - how to i SMTP with c# 4/.NET 4 to port 465/SSL (...

    first, i've discovered through trial and error that c# 4/.NET 4 has some serious limitations which a ...

  6. Android Viewpager加Fragment做界面切换时数据消失的解决方式

    今天遇到多个Fragment切换,回来后页面空白的情况,找到这个博客方法设置了一下,就可以了 vpAdapter = new VpAdapter(getSupportFragmentManager() ...

  7. linux中chkconfig 启动程序顺序介绍

    1)redhat的启动方式和执行次序是: 加载内核 执行init程序 /etc/rc.d/rc.sysinit          # 由init执行的第一个脚本 /etc/rc.d/rc $RUNLE ...

  8. Android通讯录管理(获取联系人、通话记录、短信消息)

    前言:前阵子主要是记录了如何对联系人的一些操作,比如搜索,全选.反选和删除等在实际开发中可能需要实现的功能,本篇博客是小巫从一个别人开源的一个项目抽取出来的部分内容,把它给简化出来,可以让需要的朋友清 ...

  9. Django form入门详解--2

    调整form的输出格式: 默认情况下form的格式化输出是基本table的样式的.但是django中还是为form提供发别的输出样式 1.默认的table样式输出 <html> <h ...

  10. laravel路由不生效,404,除了/ 都不行,关于nginx环境下laravel除了默认路由都出现404报错的处理方法

    其实出现这个问题只会出现在laravel被部署在二级目录中,其原因是,除了请求根目录/ (http://www.xxx.com/public/),会请求public/index.php 你在浏览器输入 ...