如何回收旧版本数据

2021-04-22  本文已影响0人  一生逍遥一生

Compat接口首先会更新当前server已压缩的版本号,并将耗时昂贵的压缩任务保存到FIFO队列中异步执行,压缩任务执行时,首先会压缩treeIndex模块中的keyIndex
索引,其次会遍历boltdb中的key,删除已废弃的key。

压缩的本质是回收历史版本,目标对象仅是历史版本,不包括一个key-value数据的最新版本。

精细化的控制本质:

  • 1.使用etcd server的自带自动压缩机制(按时间周期性压缩和保留版本号的压缩)。
  • 2.自定义压缩:定时任务中主动触发压缩。

周期性压缩

参数 参数值 解释
auto-compaction-mode periodic 启用时间周期性压缩
auto-compaction-retention 1h 保留的时间周期
auto-compaction-mode revision 启动版本号压缩模式
auto-compaction-retention 10000 保留的历史版本号

auto-compaction-retention 为0时,将关闭自动压缩策略。

周期性压缩模式的原理:
etcd server启动后,根据配置的模式periodic,会创建periodic Compactor,它会异步的获取、记录过去一段时间的版本号。periodic Compact组件
获取你设置的压缩间隔参数为1h,并将其划分成10个区间,也就是每个区间6分钟,每隔6分钟,它会通过etcd MVCC模块的地址获取当前的server版本号,
追加到rev数组中。如果只保留过去1小时的历史版本,periodic Compactor组件会通过当前时间减去上一次成功执行Compact操作的时间,如果大于一个
小时,它会取出rev数组的首元素,通过etcd server的compact接口,发起压缩操作。

版本号压缩

etcd server启动后会根据你的压缩模式,创建revision Compactor。revision Compactor会根据你设置的保留版本号数,每隔5分钟定时获取当前server
的最大版本号,减去想要保留的历史版本数,然后通过etcd server的compact接口发起如下的压缩操作即可。

压缩原理

etcd server 收到Compact请求后,它是如何执行的,核心原理是什么?
Compact请求经过Raft日志同步给多数节点后,etcd会从Raft日志取出Compact请求,应用此请求到状态机执行。
MVCC模块的Compact接口首先会检查Compact请求的版本号rev是否被压缩过,若是则返回ErrCompacted错误给client。其次会检查rev是否大于当前etcd
server的最大版本号,若是则返回ErrFutureRev给client。
Compact接口会通过boltdb的API在meta bucket中更新当前已调度的压缩版本号,然后将压缩任务追加到FIFO Scheduled中,异步调度执行。

为什么Compact接口需要持久化存储当前已调度的压缩版本号到boltdb中?
etcd通过持久化存储scheduledCompactedRev,节点crash重启后,会重新向FIFO Scheduled中添加压缩任务,已保证各个节点数据的一致。

异步的执行压缩任务会做那些工作?

  • 压缩treeIndex中的各key历史索引,清理已删除key,并将有效的版本号保存到map数据结构中。
  • 删除boltdb中废弃的历史版本数据。基本原理是根据版本号遍历boltdb已压缩区间范围内的key,遍历keyIndex返回的有效索引map数据结构判断key是否有效,
    无效则通过boltdb API删除它。

为什么压缩后db大小不减少

boltdb删除大量的key,在事务提交后B+Tree经过分裂、平衡,会释放出若干branch/leaf page页面,然而boltdb并不会将其释放给磁盘,调整db大小操作是昂贵的,
会对性能有较大的损害。boltdb是通过freelist page记录这些空闲页的分布位置,当收到新的写请求时,优先从空闲页数组中申请若干连续页使用,实现高性能的读写。

boltdb大小不变的原因是存放key-value数据的branch和leaf页,它们释放后变成空闲页,并不会将空闲释放给磁盘。boltdb通过freelist page来管理一系列
空闲页,后续新增的写请求优先从freelist中申请空闲页使用,以提高性能。

上一篇下一篇

猜你喜欢

热点阅读