固定大小分块
Beta
固定大小分块是一项 beta 阶段的功能。
整体功能已可使用,但规格和行为在未来版本中仍可能发生变化。
注意 fixed_auto 处于 alpha 阶段,详见下方对应章节
固定大小分块在可预测的字节偏移边界处切分文件,每个数据块的大小恰好等于配置中指定的值 (若文件大小不是块大小的整数倍,则最后一个数据块可能更小)
什么是固定大小分块¶
固定大小分块在概念上非常简单:从文件开头到结尾,按照相等的大小依次切分。 每个数据块单独计算哈希并存储,与 CDC 数据块的存储方式相同
与 CDC 不同,固定大小分块的边界不受文件内容影响。 在文件中间插入或删除数据时,数据块边界不会随之位移, 但被修改的数据块的哈希会完全改变,插入或删除操作还会导致其后所有数据块发生偏移, 可能使大量已存储的数据块失效
因此,对于有任意编辑模式的文件,固定大小分块的表现通常不如 CDC。 只有当文件的写入模式与块大小边界对齐时,固定大小分块才能发挥其优势
以 fixed_4k 作用于 Minecraft region 文件为例:
+------------------------------------------------------------------------+
| 文件(如 r.0.0.mca) |
+------+------+------+------+------+------+------+------+------+-- - --+
| 4KiB | 4KiB | 4KiB | 4KiB | 4KiB | 4KiB | 4KiB | 4KiB | 4KiB | ... |
| c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | |
+------+------+------+------+------+------+------+------+------+-- - --+
每个 4 KiB 的数据块对应 region 文件的一个内部页。 当两次备份之间只有少量游戏区块发生变化时,只有对应的页会被修改, 其余数据块与已存储的内容完全一致,可直接复用
可用算法¶
| 算法 | 块大小 | 典型适用场景 |
|---|---|---|
fixed_4k |
4 KiB | Minecraft region 文件(.mca):region 文件以 4 KiB 页为内部组织单位,修改少量游戏区块只会脏化有限的 4 KiB 页 |
fixed_32k |
32 KiB | 一般性的中等粒度场景 |
fixed_128k |
128 KiB | 追加写文件:尾部追加的数据只会产生新的末尾数据块,之前的所有数据块保持不变 |
fixed_1m |
1 MiB | 超大型追加写文件:比 fixed_128k 更低的元数据开销,适用于不需要细粒度去重的场景 |
fixed_auto |
128 KiB / 4 KiB | 根据上一次备份中同路径文件的分块布局自适应,在控制元数据增长的同时保留部分 4 KiB 复用能力 |
fixed_4k¶
4 KiB 的块大小与 Minecraft Anvil 格式 region 文件(.mca)的内部页结构对齐。
理论上,游戏中修改少量区块只会脏化有限数量的 4 KiB 页面,
因此 fixed_4k 在理论上能够对 region 文件实现最细粒度的去重
然而,fixed_4k 存在严重的实际缺陷:
- 元数据开销极大:一个 1 GiB 的文件需要约 262 144 条数据块记录
- I/O 性能很差:备份时每个数据块都需要单独的读写操作
除非文件非常大且每次备份只有极少数页面发生变化,否则 fixed_4k 的代价很可能远大于收益
fixed_32k¶
一种折中选项。元数据开销比 fixed_4k 低 32 倍,但粒度也粗糙得多
fixed_128k¶
128 KiB 的块大小非常适合以尾部追加方式写入的文件。 当新数据被追加到文件末尾时,只有末尾的数据块会发生变化;之前的所有数据块保持相同的哈希,可直接复用
对于纯追加写入的文件,fixed_128k 是 CDC 的一个合理替代选项
fixed_1m¶
1 MiB 的块大小在 fixed_128k 的基础上进一步降低了元数据开销,代价是去重粒度更粗。
适用于超大型追加写文件,且对细粒度去重需求不高的场景
大多数情况下,推荐优先使用 fixed_128k 或 CDC 变体。仅在文件体积极大且写入模式严格为追加写时才考虑 fixed_1m
fixed_auto¶
Alpha
fixed_auto 处于 alpha 阶段,性能相对其他分块算法较低
fixed_auto 会按 128 KiB 窗口遍历文件。 对于每个完整窗口,它会检查上一次备份中同路径文件在相同 offset 的分块布局:
- 如果上一版窗口是 1 个 128 KiB chunk,且当前内容未变化,则继续使用 1 个 128 KiB chunk
- 如果上一版窗口是 1 个 128 KiB chunk,但当前内容已变化,则将当前窗口切成 32 个 4 KiB chunk
- 如果上一版窗口是 32 个 4 KiB chunk,则先比较 4 KiB hash;当变化数量为 0 时,存成 1 个 128 KiB chunk,否则继续使用 32 个 4 KiB chunk
上一版数据缺失、上一版是 direct blob、上一版布局不规则,或当前窗口是不完整尾块时,该窗口会作为单个 chunk 存储
借此,fixed_auto 可达成这样的效果:对于文件持续变化的部分,以 4KiB 为粒度进行分块去重;
对于其他部分则以 128KiB 的粒度进行分块去重
由于 Minecraft 存档中的的 region 文件(.mca)是以 4KiB 为粒度进行修改的,
fixed_auto 预期可在不产生过多元数据开销的前提下,达到接近 fixed_4k 的去重效果
不适用场景¶
固定大小分块在以下情况通常效果不佳:
- 文件频繁在中间或开头被修改(插入/删除会导致后续所有数据块偏移)
- 文件的字节级变化模式完全不可预测
- 文件内部结构与块大小不对齐
无需额外依赖¶
固定大小分块没有额外的 Python 依赖要求。 只要安装了 Prime Backup,该功能即可使用