- 切换事务日志文件的时机,实际是生成快照文件的时机
ZK 的数据与存储中,有几个特别关注点:
内存数据
与磁盘数据
间的关系:- 内存数据,是真正提供服务的数据
- 磁盘数据,作用:
- 恢复内存数据,恢复现场
- 数据同步:集群内,不同节点间的数据同步(另,内存中的提议缓存队列 proposals)
- 磁盘数据,为什么同时包含:快照、事务日志?出于数据粒度的考虑
- 如果只包含快照,那恢复现场的时候,会有数据丢失,
- 因为生成快照的时间间隔太大,即,快照的粒度太粗了
- 事务日志,针对每条提交的事务都会 flush 到磁盘,
- 因此粒度很细,恢复现场时,能够恢复到事务粒度上
- 如果只包含快照,那恢复现场的时候,会有数据丢失,
- 快照生成的时机:基于阈值,引入随机因素
- 解决的关键问题:避免所有节点同时 dump snapshot,
- 因为 dump snapshot 耗费大量的 磁盘 IO、CPU,
- 所有节点同时 dump 会严重影响集群的对外服务能力
countLog > snapCount/2 + randRoll
,其中:- countLog 为累计执行事务个数
- snapCount 为配置的阈值
- randRoll 为随机因素(取值:0~snapCount/2)
- 解决的关键问题:避免所有节点同时 dump snapshot,
- ZK 的 快照文件是 Fuzzy 快照,不是精确到某一时刻的快照,而是某一时间段内的快照
- ZK 使用「异步线程」生成快照:
- 线程之间共享内存空间,导致 Fuzzy 快照
- 这就要求 ZK 的所有事务操作是幂等的,否则产生数据不一致的问题
- 实际上 ZK 的所有操作都是幂等的
- 类比:Redis 中使用「异步进程」生成快照 RDB(Redis Dump Binary)
- RDB 文件是精确的快照,原因:进程之间内存空间隔离
- 系统内核使用「写时复制」(Copy-On-Write)技术,节省大量内存空间
- ZK 使用「异步线程」生成快照: