跳转至

固定大小分块

Alpha 状态

固定大小分块目前是概念验证性质的实现,处于 alpha 阶段。 不建议在生产环境中使用。 除非你有特定需求,否则请使用 CDC 分块

固定大小分块在可预测的字节偏移边界处切分文件,每个数据块的大小恰好等于配置中指定的值 (若文件大小不是块大小的整数倍,则最后一个数据块可能更小)

什么是固定大小分块

固定大小分块在概念上非常简单:从文件开头到结尾,按照相等的大小依次切分。 每个数据块单独计算哈希并存储,与 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_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 的一个合理替代选项

不适用场景

固定大小分块在以下情况通常效果不佳:

  • 文件频繁在中间或开头被修改(插入/删除会导致后续所有数据块偏移)
  • 文件的字节级变化模式完全不可预测
  • 文件内部结构与块大小不对齐

无需额外依赖

固定大小分块没有额外的 Python 依赖要求。 只要安装了 Prime Backup,该功能即可使用