跳转至

文件分块

将大文件拆分成更小的数据块,以在多次备份之间实现更好的去重效果

什么是文件分块

文件分块是一种存储策略:在存储前,将大文件拆分成若干小块(chunk)。 每个数据块单独计算哈希并去重,因此当大文件在两次备份之间只有局部内容发生变化时, 只需将变化的数据块重新写入,未变化的数据块可直接复用已有存储

在 Prime Backup 中,读取和导出分块文件对用户是透明的。 当需要恢复文件内容时,Prime Backup 会自动按顺序将其重建出来

什么时候会启用

分块存储由 backup 中的两个配置字段控制:

  • chunking_enabled:分块功能的总开关。若为 false,任何文件都不会被分块存储
  • chunking_rules:一个有序的规则列表。Prime Backup 会对每个文件依次遍历此列表,应用第一条匹配的规则

当且仅当以下两个条件同时满足时,一条规则才算匹配:

  • 文件大小达到该规则的 file_size_threshold
  • 相对于 source_root 的文件路径匹配该规则的 patterns

若没有任何规则匹配,文件将以常规直存数据对象(direct blob)的方式存储,不进行分块

默认配置如下:

{
    "chunking_enabled": false,
    "chunking_rules": [
        {
            "algorithm": "fastcdc_32k",
            "file_size_threshold": 104857600,
            "patterns": [
                "**/*.db"
            ]
        }
    ]
}

修改上述配置只会影响后续备份中新写入的文件。 已存储的直存数据对象或分块数据对象不会被自动转换

它是怎么存储的

Prime Backup 仍会为整个文件创建一条数据对象(blob)记录,但该数据对象的存储方法为 chunked(分块),而非 direct(直存)

当前实现的大致流程如下:

  1. 使用所选算法对文件进行切块
  2. 为每个数据块计算哈希值(遵循 backup.hash_method 设置)
  3. 检查这些数据块是否已存在,已存在的直接复用
  4. 仅压缩并写入那些新的数据块
  5. 将数据块按顺序绑定回整个文件对应的数据对象(按偏移量)

元数据优化(数据块组)

从概念上讲,一个分块数据对象只是一个有序的数据块列表。 为每一对数据对象与数据块存储直接的关联记录开销会很大, 因此实现将连续的数据块组织成数据块组(chunk group),并存储两层绑定关系:

  • 数据对象 -> 数据块组(按数据对象偏移量)
  • 数据块组 -> 数据块(按组内偏移量)
+--------------------------------------------------------------------------------+
|                                      blob                                      |
+--------------------------+-----------------------------------------------------+
|       chunk group 1      |  chunk group 2  |          chunk group 3            |
+--------------------------+-----------------+-----------------+-----------------+
| chunk1 | chunk2 | chunk3 | chunk4 | chunk5 | chunk6 | chunk7 | chunk8 | chunk9 |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+

这在不改变逻辑模型的前提下减少了元数据开销

数据块哈希遵循 backup.hash_method 设置,与整个文件对应的数据对象哈希相同。数据块组哈希始终使用 sha256,不受 backup.hash_method 影响

压缩与性能

分块存储不会关闭压缩

对于一个分块数据对象:

  • 数据对象记录本身的 compress 字段记为 plain
  • 每个数据块会根据 backup.compress_methodbackup.compress_threshold 独立压缩
  • 数据对象的 stored_size 表示所有唯一数据块存储大小之和

与直存方式相比,首次备份某个文件时,分块存储的速度会更慢, 因为 Prime Backup 需要额外进行切块、哈希计算和逐块处理。 优势主要体现在后续那些大量数据块可被复用的备份上

可用算法

算法 类型 平均块大小 适合场景
fastcdc_32k CDC 32 KiB 通用;适合任意局部修改的大文件
fastcdc_128k CDC 128 KiB 超大型文件(10 GiB 以上),32 KiB 粒度会产生过多数据块记录
fixed_4k 固定大小 4 KiB MC region 文件(与 4 KiB 页边界对齐);注意:会导致严重的元数据膨胀
fixed_32k 固定大小 32 KiB 中等粒度的固定大小场景
fixed_128k 固定大小 128 KiB 以追加写为主的文件

各方式的详细说明见独立文档:

  • CDC 分块:内容感知的切块边界;对任意类型的局部修改均有效
  • 固定大小分块:基于字节偏移的切块边界;实现更简单,但适应性较弱(alpha 状态)

观察方式

Prime Backup 的维护逻辑已支持分块存储。 你可以通过 !!pb database overview 命令观察效果,该命令会额外显示一组数据块统计信息

如果 Prime Backup 发现某个分块文件在一次备份中产生了大量全新的数据块,它会在日志中发出警告。 这通常说明该文件并不适合作为分块存储的目标;当然,若这是该文件首次被备份,则属于正常现象,可忽略警告