ZooKeeper运维——数据备份与恢复(事务日志+快照日志,万字总结,你想要的都有)
Posted 徐同学呀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZooKeeper运维——数据备份与恢复(事务日志+快照日志,万字总结,你想要的都有)相关的知识,希望对你有一定的参考价值。
首发CSDN:徐同学呀,原创不易,转载请注明源链接。我是徐同学,用心输出高质量文章,希望对你有所帮助。
文章目录
一、前言
ZooKeeper
存储数据的底层数据结构是LSM
(Log Structured Merge-tree
)。基于LSM
实现的存储引擎有两个显著特点:MVCC
(Multi-Version Concurrency Control
)和存储KV
,即所有的更新操作,都是先追加事务日志,然后把key-value
存储到内存数据库,注意不是replace
,而是保存对一个key-value
的多个版本。
ZooKeeper
的数据备份与恢复,就用到了其事务日志文件和快照日志文件。快照日志文件是什么概念?为什么要有快照日志文件?
如何做数据备份?如何恢复数据?解开这些疑惑,需要深入了解ZooKeeper
底层是如何保证数据一致性和集群启动时如何做初始化数据加载和同步。
二、ZooKeeper顺序一致性
ZooKeeper
专门设计了 Zab
(Zookeeper Atomic Broadcast
)协议作为其数据一致性协议。所有写操作和客户端会话管理都以事务方式由 Leader
统一协调,使用两阶段提交的方式,保证数据一致性。
1、ZooKeeper如何处理请求
客户端和 ZooKeeper
集群中的任一服务建立连接,即可发送请求,请求主要包括两类,只读请求和事务请求。
(1)只读请求本机处理
只读请求包括 getData
、getChildren
、exists
等,zk服务器接收到只读请求无需转发给 Leader
,可直接本机处理响应。
(2)事务请求转发给Leader协调
事务请求包括 create
、delete
、setData
以及客户端会话的创建和销毁(createSession
、closeSession
)。
Leader
收到事务请求可以直接协调处理,并发给Follower
做数据一致性同步;Follower
收到事务请求就需要先转发给 Leader
,由Leader
统一生成事务提议。
事务请求是原子性和幂等的。
2、两阶段提交+过半数机制
(1)第一阶段提交事务请求
第一阶段是投票阶段,主要是让集群中半数以上的服务持久化事务请求到事务日志文件。所有事务请求由 Leader
统一生成事务提议广播给 Follower
,具体流程如下:
Leader
首先将事务请求持久化到事务日志文件中。Leader
生成事务提议,将其广播给所有Follower
。Follower
收到事务提议,也将事务持久化到事务日志文件,并给Leader
回应一个ACK
消息,表示已做完事务持久化工作。
(2)第二阶段执行事务提交
第二阶段,Leader
收到半数以上的ACK
后,认为半数以上的服务都完成了事务日志持久化操作,可以继续将事务请求同步到内存数据库中,此为事务提交阶段。具体流程如下:
Leader
收到一半以上的ACK
信息后,进入事务commit
阶段,Leader
先将事务请求同步到内存数据库。- 如果是
Leader
自己收到的事务请求,此时就可以响应客户端了。 - Leader 向所有
Follower
广播 COMMIT 消息。 Follower
收到 COMMIT 后,将事务请求同步到内存数据库。- 如果是
Follower
收到的事务请求又转发给Leader,此时Follower
就可以响应客户端了。
如下图分别为 Leader
接收到事务请求和 Follower
接收事务请求的处理过程:
需要注意,假设集群有3个服务节点,Leader
先将事务写入日志文件,相当于已经有一个服务节点完成了第一阶段(就是 Leader
自己),然后广播事务提议给 Follower
,只要有一个 Follower
响应了ACK
,Leader
就可以进入第二阶段 COMMIT
,此时Leader
将事务同步到内存数据库,就可以响应客户端了。
其实在集群中可能还会存在一种运行模式,即Observer
,和 Follower
一样统称为Learner
,也可以参与到数据同步的两阶段过程中,但是没有任何投票权利,Observer
无需回应ACK
给Leader
,Observer
不计入集群过半机制。
3、ZXID
从两阶段流程可以看出,ZooKeeper
保证的是最终一致性,即 Leader
向客户端返回写入成功后,可能有部分 Follower
还没有写入最新的数据。
ZooKeeper
的最终一致性是严格的顺序一致性,所有事务请求统一由Leader
发起提议,严格按ZXID
顺序执行,当前事务请求没有处理完,再来新的事务请求就会阻塞。
ZXID
是由 Leader
生成的事务ID,是一个16进制的递增数字,共64位(二进制),由两部分组成:高32位代表当前Leader
任期编号,递增;低32位是事务计数器,递增,整体上是递增的。
三、事务日志
ZooKeeper
适合读多写少的场景,读操作几乎是内存级别的,这得益于ZooKeeper
将数据保存在内存中。数据在内存中,就有一个问题,ZooKeeper
重启了数据还会在吗?
当然在了,ZooKeeper
将数据以事务日志形式持久化到文件中。每个更新请求,必须先将事务日志写到文件中,然后才把数据同步到内存数据库。
1、事务日志存放目录
事务日志文件默认存储在dataDir
目录下,因为每次事务请求都是一次磁盘IO操作,事务日志的写入性能直接影响了ZooKeeper
对事务请求的吞吐,为了更高的吞吐和低延迟,建议单独为事务日志配置一个目录dataLogDir
,以免受其他操作影响。
dataLogDir
下会先生成一个子目录version2
,2表示ZooKeeper
日志格式的版本号,同一版本的日志可以互相迁移恢复数据。version2
下才是事务日志文件。
2、文件大小和后缀名
事务日志的文件有两个特点:
- 文件大小出奇一致:都是
67108880KB
,即64MB
。 - 文件名后缀是一串看似有些规律的数字,而且随着修改时间推移呈递增状态。
(1)磁盘空间预分配
文件大小都是64MB
,是因为日志文件的磁盘空间预分配。
事务日志不断追加写入文件的操作会触发底层磁盘IO为文件开辟新的磁盘块,即磁盘Seek,为了避免频繁的文件大小增长带来的磁盘Seek开销,ZooKeeper
在创建事务日志文件时就向操作系统预分配了一块比较大的磁盘块,保证了单一事务日志文件所占用的磁盘块是连续的,以此提升事务的写入性能。默认是64MB
,空闲部分用空字符(\\0
)填充。
如果后续检测到文件空间不足4KB
,将扩容再次预分配64MB
,直到创建新的事务日志文件。
(2)ZXID作为后缀名
文件名后面的一串数字是事务ID:ZXID
,并且是写入事务日志文件的第一条事务ZXID
。前面讲了,ZXID
高32位是当前Leader
任期编号,低32位是事务计数器,比如 log.1400000001
、log.1400000003
,都是Leader
任期编号为20时产生的事务日志文件。
3、事务日志可视化
事务日志文件中存放的是二进制格式的数据,不能用vim、cat等工具直接打开,需要用apache-zookeeper-3.7.0
提供的脚本bin/zkTxnLogToolkit.sh
打开:
bin/zkTxnLogToolkit.sh logs/zoo-1/version-2/log.1400000003
一行就是一个事务记录,每行从左到右依次是操作时间、客户端session
ID、CXID
(客户端操作序列号)、ZXID
、操作类型(做了什么),如果操作类型是 createSession
,后面的30000就是session
的超时时间。
4、相关配置项
跟事务日志有关的配置除了dataLogDir
外,还有 preAllocSize
。
(1)dataLogDir
zoo.cfg
中默认没有显式配置dataLogDir
,事务日志和快照日志共享dataDir
。但是强烈建议,单独为事务日志指定dataLogDir
。
事务日志记录对磁盘性能要求极高,为了保证数据一致性,ZooKeeper
在返回客户端请求响应前,必须将本次请求对应的事务日志写入到磁盘中。因此,事务日志写入性能直接决定了ZooKeeper
在处理事务请求时的吞吐。
针对同一块磁盘的其他并发读写操作(如ZooKeeper
运行时日志输出和操作系统自身的读写等),尤其是数据快照操作,会极大影响事务日志的写性能。因此尽量给事务日志的输出配置一个单独的磁盘或是挂载点,极大提高ZooKeeper
整体性能。
(2)preAllocSize
java 系统属性: ZooKeeper.preAllocSize
,从字面意思就可以看出,preAllocSize
是用来配置事务日志文件预先分配文件大小的参数。默认65536
,单位KB
,即64MB
。
5、什么时候创建新日志文件
在进行事务日志写入前,ZooKeeper
会判断是否正在关联一个可写的事务日志文件,如果有则继续追加到该文件中,如果没有就需要创建新的日志文件并关联上。
什么时候ZooKeeper
没有关联上一个可写的事务日志文件呢?有两种情况:
ZooKeeper
停止会导致之前关联的事务日志文件断开,重启后第一次事务日志写入,需要创建新的日志文件。- 上一个事务日志文件写满了(达到阈值,触发了快照之后),需要创建新的日志文件。
需要注意ZooKeeper
服务不要频繁重启,否则会产生很多日志文件,并且有些文件还没有写满,非常浪费磁盘空间。
四、快照日志
快照日志是将ZooKeeper
服务器上某个时刻的全量内存数据,写入到指定磁盘文件中。可以这样理解,快照日志文件是存量数据,事务日志文件是增量数据,二者加起来就是最大限度的全量数据。
1、文件存储
和事务日志类似,快照日志存放在dataDir
子目录version2
中,文件名为snapshot.ZXID
,不需要像事务日志文件一样预分配空间。
需要强调快照文件名后缀 ZXID
是触发快照的瞬间,提交的最后一个事务ID。如果是事务ZXID5
触发快照,那么快照文件名就是snapshot.ZXID5
,快照之后的下一个事务的ID是ZXID6
,新的事务日志名就是log.ZXID6
。
在数据恢复阶段,ZooKeeper
可以根据快照文件名后缀ZXID
,确定增量事务日志的起点文件。
2、快照日志可视化
快照日志内容同样也是二进制格式的,需要用 apache-zookeeper-3.7.0
提供的脚本bin/zkSnapShotToolkit.sh
打开:
bin/zkSnapShotToolkit.sh data/zoo-1/version-2/snapshot.1300000000 |less
快照日志记录每个节点的元信息,每个节点从上到下依次为:
cZxid
,创建这个节点时的事务ID。ctime
,创建节点时间。mZxid,
最后修改节点的事务ID。mtime,
最后修改节点时间。pZxid,
,该节点最后更新子节点列表的事务ID。cversion
,该节点子节点列表更新版本号,即子节点列表修改次数(不是子节点的值修改)。dataVersion
,节点数据版本号。aclVersion
,节点访问控制列表版本号。ephemeralOwner
,如果为临时节点,则为节点拥有者的sessionID
,如果不是临时节点则为0。dataLength,
,节点数据长度。
3、相关配置
快照日志相关的配置,除了dataLog
,还有snapCount
、autopurge.snapRetainCount
和autopurge.purgeInterval
。
(1)snapCount
java 系统属性: ZooKeeper.snapCount
,默认100,000,表示每写100,000次事务日志,触发一次快照,并滚动事务日志,即切换新的事务日志文件。
但是,实际情况,快照是一个比较好性能的操作。为了防止集群中的所有机器同时触发快照操作,当事务日志中的事务数量达到运行时[ snapCount/2 + 1,snapCount ]
范围内生成的随机值时,该ZooKeeper
服务器就触发一次快照。
(2)日志清理
每一个快照日志文件都是zk集群某个时刻的全量数据快照,理论上只需要最新的一个快照日志文件及其后面的事务日志即可,所以定时清理一些不需要的日志文件以节省磁盘内存资源。
日志的清理跟autopurge.snapRetainCount
和autopurge.purgeInterval
有关。
autoburge.snapretaincount
表示保留多少个快照日志文件,如果启动日志清理功能,zk会保留autoburge.snapretaincount
个最近的快照日志文件和dataDir
和dataLogDir
中相应的事务日志文件,并删除其余的。autopurge.snapRetainCount
默认为3,最小也是3。autopurge.purgeInterval
,清理任务触发的小时数时间间隔。设置为正整数(1及以上) ,以启用自动清洗。默认为0不启动。
4、什么时候触发数据快照
触发快照即生成新的快照日志文件有两种情况,事务日志写入数量达到阈值snapCount
和新Leader
同步数据。
(1)事务日志写入数量达到阈值snapCount
每进行一次事务日志记录之后,ZooKeeper
都会判断当前是否需要进行数据快照。前面也说过,理论上进行snapCount
次事务操作后就会触发一次数据快照,但是考虑到数据快照对zk集群的整体性能影响,需要尽量避免所有机器同时进行数据快照。
所以采用过半随机策略,某个ZooKeeper
服务器的事务次数在[ snapCount/2 + 1,snapCount ]
范围内生成的随机值时,触发数据快照。
满足快照条件后,ZooKeeper
先进行事务日志文件的切换,即创建新的事务日志文件,然后再异步进行数据快照操作,尽量不影响正常流程。
(2)新Leader同步数据
运行中的ZooKeeper
集群,如果发生Leader重新选举,新Leader所在机器会检查最近一次快照之后是否有事务日志产生,有就对最近的一次事务之前的全量数据做一次数据快照。
五、ZooKeeper启动数据初始化和同步
ZooKeeper
服务器启动期间,需要进行数据初始化工作,就是将磁盘中的日志文件加载到ZooKeeper
服务器内存中,主要包括两个过程:从快照日志文件中加载快照数据和根据事务日志进行数据修正。
1、加载并解析快照日志文件
每一个快照日志文件都保存了某个时刻ZooKeeper
服务器全量数据,所以可以加载解析快照日志,先生成一棵DataTree
。
(1)加载最新快照文件
在 ZooKeeper
服务器运行期间,磁盘上会产生一些快照文件。更新时间最晚的那个文件包含了最新的全量数据,那么是否只需要这个最新的快照文件就可以了呢?
在 ZooKeeper
的实现中,会获取最新的至多100个快照文件(如果磁盘上存在不到100个快照文件,那么就获取所有快照文件)。这至多100个快照文件并不是全部都要加载和解析,而是先逐个进行数据正确性校验,校验通过就解析这个文件了,正常解析成功,就不会再向后加载检查。
这样做的目的就是防止某些快照文件损坏,最大力度恢复数据。
(2)解析快照文件
每个快照文件都是内存数据序列化到磁盘的二进制文件,因此需要对其进行反序列化,生成 DataTree
对象。
(3)获取最新ZXID(zxid_for_snap)
最新的快照文件解析成功后,根据该文件名解析出一个最新的ZXID
(zxid_for_snap
),即发生快照最后一次提交事务的ZXID
,找到这个ZXID
有什么用呢?
可以根据这个ZXID
找到快照之后对应的增量事务日志文件,进行数据修正。
2、事务日志进行数据修正
只通过快照日志无法完全恢复数据,还需要根据事务日志进行增量数据修正。
(1)获取zxid_for_snap之后提交的事务
快照日志文件处理完后,可以得到一个zxid_for_snap
,扫描加载文件名后缀大于zxid_for_snap
的事务日志文件,获取在zxid_for_snap
之后提交的所有事务。
(2)数据修正
逐个对zxid_for_snap
之后的事务进行内存同步,修复DataTree
数据。如果该ZooKeeper
服务器是Leader
,
在数据修正的过程中,每当有一个事务同步到内存数据库,就将这一事务记录转换成提议,保存到事务提议缓存队列中,为后续数据同步做准备。
(3)获取最新ZXID校验epoch
epoch
字面意思是纪元、时代,在ZooKeeper
中,epoch
表示当前Leader
任期。每次选举出一个新Leader
后,epoch
在原来基础上加1。
ZooKeeper
集群在运行期间,服务间相互通信都会带上这个epoch
,以确保彼此在同一个Leader
任期内。
待所有的事务日志对数据修正后,获取一个最大的ZXID
,即上次服务器正常运行时最后提交的事务ID。
从最大ZXID
的高32位解析出该事务处理的Leader任期epoch
,同时从磁盘的dataDir/version2
目录下currentEpoch
和acceptedEpoch
文件中读取出最新的epoch
值,进行校验。
3、数据同步
ZooKeeper
服务器重启后,做完日志文件的加载和数据初始化,整个集群完成Leader
选举或者本身就有Leader
,此时,Learner
服务器(Follower
或者Observer
)需要向Leader
服务器进行注册,注册完成后,就进入数据同步阶段,即Leader
服务器上的事务和Learner
服务器的事务做对比,同步或者回滚。
(1)Learner 向 Leader 发送 ACKEPOCH
在注册Learner
最后阶段,Learner
向 Leader
发送一个 ACKEPOCH
数据包,Leader
从这个数据包中解析出该Learner
的 currentEpoch
和 lastZxid
。
(2)Leader 初始化 peerLastZxid、minCommittedLog、maxCommittedLog
在开始数据同步之前,Leader
服务器首先从内存数据库中提取出事务请求对应的提议缓存队列,并完成以下三个ZXID
的初始化:
peerLastZxid
,将从Learner
获取的lastZxid
赋值给peerLastZxid
。minCommittedLog
,Leader
服务器提议缓存队列committedLog
中的最小ZXID
。maxCommittedLog
,Leader
服务器提议缓存队列committedLog
中的最大ZXID
。
通过 peerLastZxid
和 minCommittedLog
、maxCommittedLog
比较,有四种数据同步的方式:直接差异化同步(DIFF
)、先回滚再差异化同步(TRUNC+DIFF
)、仅回滚同步(TRUNC
)、全量同步(SNAP
)。
(3.1)直接差异化同步(DIFF)
minCommittedLog < peerLastZxid < maxCommittedLog
(peerLastZxid, maxCommittedLog]
范围内的事务是Learner
没有的,所以只需要Leader
把这个范围内的事务提议发送给这个Learner
同步即可。具体流程如下:
Leader
先向这个Learner
发送一个DIFF
指令,用于通知Learner
进入差异化数据同步阶段,Leader
也将把这些差异事务提议同步给自己。- 对于每条差异事务提议,
Leader
会发送两个数据包给Learner
,分别是PROPOSAL
内容数据包和COMMIT
指令数据包。 Leader
发完所有的差异事务提议后,还会发送一个NEWLEADER
指令,用于通知Learner
,已经将所有差异事务提议都同步给自己了。Learner
收到NEWLEADER
指令后,回复一个ACK
消息给Leader
,表明自己已经完成差异化事务的同步。Leader
在接收到来自这个Learner
的ACK
消息后,就认为这个Learner
已经完成了数据同步,同时进入过半等待阶段,即Leader
会和其他Learner
服务器进行上述同样的数据同步流程。- 直到集群中有过半的
Learner
机器响应了Leader
这个ACK
消息,此时Leader
向所有已经完成数据同步的Learner
发送一个UPTODATE
指令,用来通知Learner
已经完成了数据同步,同时集群中已经有过半机器完成了数据同步。此时集群已经具备了对外服务的能力。 Learner
在接收到这个来自Leader
的UPTODATE
指令后,会终止数据同步流程,然后向Leader再次反馈一个ACK
消息。
很明显差异化同步过程和运行时的Leader
与Follower
事务提交一样,都用了两阶段提交。
(3.2)先回滚再差异化同步(TRUNC+DIFF)
minCommittedLog < peerLastZxid < maxCommittedLog
上述直接差异化同步场景存在一种罕见,但是确实存在的特殊场景,peerLastZxid
依然在 minCommittedLog
和 maxCommittedLog
之间,但是peerLastZxid
和minCommittedLog
是同一任期,maxCommittedLog
是另一个任期。
为什么会出现这样的情况?这一定是发生过Leader重选!假设有 A、B、C 三台机器:
- 某一时刻B是Leader服务器,此时的Leader_Epoch为5,同时当前已经被集群中绝大部分机器都提交的
ZXID
包括:0x500000001
和0x500000002
。 - 此时,Leader 正在处理
ZXID: 0x500000003
,并且已经将该事务写入到了 Leader本地事务日志文件,但是还没来得及把该事务提议广播给Follower
,Leader
服务器挂了。所有Follower
上最后一次事务提交还是0x500000002
。 - 还有两台机器,进行
Leader
选举,假设A成为新Leader
,Leader_Epoch+1变更为6。 - A和C继续对外提供服务,又提交了一个事务
0x600000001
,此时,A的事务提议缓存队列中minCommittedLog
为0x500000001
,maxCommittedLog
为0x600000001
。 - 此时,B 重启,开始数据同步,B最后一次提交事务
peerLastZxid
为0x500000003
,peerLastZxid
在minCommittedLog
和maxCommittedLog
之间,却和现在的Leader
不在同一个任期。 - 对于这个特殊场景,现任Leader没有事务
0x500000003
,B 就使用先回滚再差异化同步(TRUNC+DIFF)的方式。 - 当
Leader
服务器发现某个Learner
包含了一条自己没有的事务记录,那么就在数据同步时让该Learner
进行事务回滚,回滚到Leader
服务器上存在的,同时也是最接近于peerLastZxid
的ZXID
。 - B先回滚到
ZXID
为0x500000002
的事务记录,然后再进行差异化同步。
(3.3)仅回滚同步(TRUNC)
peerLastZxid > maxCommittedLog
Leader
要求 Learner
回滚到 ZXID
值为 maxCommitedLog
对应的事务操作。
(3.4)全量同步(SNAP)
发生全量同步主要原因是 Leader
服务器上的提议缓存队列不能直接用于和 Learner
进行数据同步,所以只能进行全量同步。
有两种情况,Leader
服务器上的提议缓存队列不可用:
peerLastZxid
小于minCommittedLog
。Leader
服务器上的提议缓存队列为空。
所谓全量同步就是 Leader
服务器将本机上的全量内存数据都同步给 Learner
。
六、数据备份与恢复流程
1、为什么需要快照日志
通过对事务日志和快照日志基本概念的了解,知道事务日志存的是增量数据,快照日志存的是某个时刻的全量数据,二者合二为一就是最大限度的全量数据。
又通过对ZooKeeper
启动时数据初始化和同步的了解,快照日志可以初步恢复出一个DataTree
,事务日志只是对这棵DataTree
做数据修正。如果没有快照日志都是事务日志,那么数据恢复的过程将非常耗时好性能,每条事务需要重新写入内存数据库,肯定是没有用快照日志反序列化生成一个DataTree
来的快。
2、数据备份策略
理论上,只需要备份最新的一个快照日志文件及其之后产生的事务日志文件即可,但是防止日志文件损坏,可以全量备份,开启了日志清理任务之后,至多保留3个快照文件,也不会很多。
备份数据需要考虑一个时间间隔,一天一备,还是一小时一备,时间间隔越小,数据越新,越能最大限度恢复数据。
备份数据还需要考虑是本机备份还是将数据备份到其他机器,之所以备份到其他机器是为了防止本机故障停机、无法重启、磁盘损坏等。
本机备份其实没有多大必要,因为原始日志文件就是最新的数据,应该把精力放在数据恢复上。
3、数据恢复
恢复数据分为了两种:冷恢复和热恢复
- 冷恢复就是通过备份的日志文件在
ZooKeeper
启动时初始化和同步,适用于当前集群故障,无法通信的场景。 - 热恢复就是动态的将当前集群的数据同步到目的集群上,前提是当前集群是正常运行,可通信的。
如何动态同步,可以利用 Observer
机制。将目的集群中的一个服务设置成当前集群的 Observer
,当前集群的Leader
就会把数据动态同步给 Observer
了,然后再将目的集群配置启动,让这个Observer
成为目的集群的 Leader
即可。也可以将目的集群的所有服务都作为当前集群的Observer
,可能会消耗一些当前集群 Leader
的一些性能,以实际生产情况为准。
使用日志文件恢复数据需要注意,先把目的集群的日志文件清空(删除 dataDir/version2
和 dataLogDir/version2
),将备份日志文件复制到集群中的某个服务即可,目的集群重启后,有备份日志文件的服务将成为 Leader
,然后同步数据给 Follower
。前提:目的集群是一个新集群。
如果目的集群是一个已经在用的集群,就不能用日志文件恢复了,需要遍历原集群的数据,然后一条一条地写入到目的集群,该方式消耗性能较大,可能会影响目的集群的正常使用。该方式还有一个缺点就是原集群的 客户端会话不会同步,而日志文件恢复是可以的。
七、要点总结
ZooKeeper
专门设计了 Zab
(Zookeeper Atomic Broadcast
)协议作为其数据一致性协议,所有写操作和客户端会话管理都以事务方式由 Leader
统一协调,使用两阶段提交的方式,保证数据一致性。但是为了性能,Leader不可能等所有的 Learner 响应完成,而是使用投票过半机制。
ZooKeeper
的两阶段提交是同步阻塞的,事务提议严格按 ZXID
顺序执行,所以事务操作性能低于非事务操作,Follower
越多性能越低。
事务请求包括 create
、delete
、setData
以及客户端会话的创建和销毁(createSession
、closeSession
)。
ZooKeeper
将数据以事务日志形式持久化到文件中。每个事务请求,必须先将事务日志写到文件中,然后才把数据同步到内存数据库。
事务日志是增量数据,快照日志是某个时刻全量数据,合二为一可以最大限度恢复数据。
通过日志文件恢复数据,取最新的快照日志文件反序列化生成一个 DataTree
,然后用事务日志对这棵 DataTree
做数据修正。
数据恢复后还需要做数据同步,即 Leader
为了保证所有的 Learner
和自己的数据一致,需要拿 Learner
最后提交的 ZXID
和 Leader
的 事务提议缓存队列中的ZXID
最对比,Learner
多退少补。
八、参考资料
- 书籍:《ZooKeeper-分布式过程协同技术详解》
- 书籍:《从Paxos到Zookeeper分布式一致性原理与实践》(推荐)
- https://zookeeper.apache.org/doc/current/zookeeperAdmin.html
- https://www.bilibili.com/video/BV1to4y1C7gw
- https://www.bilibili.com/video/BV1XK4y1r7X3
- https://zhuanlan.zhihu.com/p/336779533
- https://www.cnblogs.com/f-ck-need-u/p/9236954.html
- https://time.geekbang.org/column/article/207706
如若文章有错误理解,欢迎批评指正,同时非常期待你的评论、点赞和收藏。
如果想了解更多优质文章,和我更密切的学习交流,请关注如下同名公众号【徐同学呀】,期待你的加入。
注:《ZooKeeper-分布式过程协同技术详解》和 《从Paxos到Zookeeper分布式一致性原理与实践》pdf版本由于版权问题无法在CSDN上传,有需要这两本PDF的请关注公众号:徐同学呀,回复zkpdf获取。
以上是关于ZooKeeper运维——数据备份与恢复(事务日志+快照日志,万字总结,你想要的都有)的主要内容,如果未能解决你的问题,请参考以下文章