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] view plain copy

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

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

[java] view plain copy

  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之前拷贝到对应的数据目录下。

时间: 2024-10-03 23:00:21

ZooKeeper学习之文件系统的布局和格式的相关文章

zz``文件系统磁盘布局与I/O映射

sysnote.org/2015/08/06/fs-io-map/ 这个大牛博客不错,可以收藏并扩散学习下 本文主要对文件系统的磁盘布局进行概要的梳理,并在此基础上分析文件系统I/O到块I/O的映射机制. 1.文件系统磁盘布局 首先文件系统层面来阐述文件与块设备的关系. 1.1文件描述符与inode 应用程序在访问文件时都会先打开文件,在内核中,对应每个进程,都会有一个文件描述符表表示这个进程打开的文件,但是用户程序不能直接访问内核中的文件描述符表,而只能使用文件描述符表的索引(一个整数),这些

[转帖]Zookeeper学习系列【一】 教会你Zookeeper的一些基础概念

Zookeeper学习系列[一] 教会你Zookeeper的一些基础概念 https://segmentfault.com/a/1190000018927058 前言 最近加入了部门的技术兴趣小组,被分配了Zookeeper的研究任务.在研究过程当中,发现Zookeeper由于其开源的特性和其卓越的性能特点,在业界使用广泛,有很多的应用场景,而这些不同的应用场景实际上底层的原理都是差不多的,只要你真正理解了Zookeeper的一些基础概念和机制,就能够触类旁通. 于是乎,在第一次和项目小组内成员

php学习基础-文件系统(一) 文件处理,文件权限

一.PHP系统文件处理 /* PHP文件系统处理 * 所有文件处理都是使用系统函数完成的. * 是基于Linux/Unix系统为模型 * * 文件系统处理的作用: * 1. 所有的项目离不开文件处理 * 2. 可以用文件长时间保存数据 * 3. 建立缓存, 服务器中文件操作 * * 文件处理 * 1. 文件类型 * 以Linux为模型的, 在Windows只能获取file, dir或unknow 三种类型 * 在Linux/Unix下, block, char, dir, fifo, file,

php学习基础-文件系统(二) 文件读写操作、文件资源处理

一.文件的打开与关闭 /* *读取文件中的内容 * file_get_contents(); //php5以上 * file() * readfile(); * * 不足:全部读取, 不能读取部分,也不能指定的区域 * * fopen() * fread() * fgetc() * fgets() * * * * * 写入文件 * file_put_contents("URL", "内容字符串"); //php5以上 * 如果文件不存在,则创建,并写入内容 * 如果

EasyUI学习总结(六)——EasyUI布局

EasyUI学习总结(六)--EasyUI布局 一.EasyUI布局介绍 easyUI布局容器包括东.西.南.北.中五个区域,其中中心面板是必须的,而东.西.南.北这四个面板是可选的,如果布局里面不需要东.西.南.北这四个面板,那么可以把相应的div删掉,另外,如果需要创建复杂的easyUI布局,那么可以通过嵌套东.西.南.北.中五个面板来实现.下面简单演示一下EasyUI布局. 1.1.通过div创建easyUI布局 easyUI的layout可以通过div来创建,使用div来创建easyUI

根文件系统移植(2)——根文件系统的两种格式

一:镜像格式的根文件系统 (1)镜像文件的根文件系统的主要作用是用来以后烧录到块设备上面的,块设备上的内核启动后去挂载它. (2)镜像形式的根文件系统是由文件夹格式的根文件系统通过特定的工具(mke2fs)制作得到的 (3)镜像文件系统具有一定的格式,格式是内化的,跟文件名后缀是无关,而是在制作时决定的. 二:文件夹格式的根文件系统 (1)简单来说,文件夹格式的根文件系统其实就是我们开发主机下的一个文件夹而已,不同之处在于这个文件夹里面包含了我们根文件系统所需的内容(包括etc目录下的运行时配置

Away3D 学习笔记(一): 加载3DS格式的模型文件

加载外部的3DS文件分为两种: 1: 模型与贴图独立于程序的,也就是从外部的文件夹中读取 1 private function load3DSFile():Loader3D 2 { 3 loader = new Loader3D(); 4 loader.addEventListener(LoaderEvent.RESOURCE_COMPLETE,onLoadComplete); 5 loader.addEventListener(AssetEvent.ASSET_COMPLETE,onAsset

CSS3学习笔记:flexbox布局

这篇文章里我们将学习CSS 里flexbox布局的几个最重要的概念,通过学习flexbox布局,你会发现以往遇到的所有的关于布局的问题,现在都可以轻松解决了. 我们将只关注几个核心概念,等这些核心知识掌握之后,你可以再慢慢的学习那些不重要的相关知识. 1. 容器和容器里的元素 flexbox布局的两个最重要的概念是 容器 (蓝色)和容器里的 子元素 (红色).在本文的例子中, 容器 和它的 子元素 都是 div . 横向布局 为了实现flex布局,我们需要在 容器 的CSS里添加如下代码: .c

如何将根文件系统制作成yaffs格式,并设置从yaffs启动

1.利用mkyaffs2image 工具,将根文件系统打包成yaffs镜像包 mkyaffs2image-128M root_qtopia root_qtopia.img 2.设置uboot参数bootarg setenv bootargs noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0 如何将根文件系统制作成yaffs格式,并设置从yaffs启动