PBS 存储技术概述

数据存储

数据存储区是存储备份快照及其数据块的逻辑位置。快照由清单、blob、动态和固定索引(请参阅术语)组成,并存储在以下目录结构中:

<datastore-root>/<type>/<id>/<time>/

数据存储的重复数据删除基于重用块,这些块由备份快照中的索引引用。这意味着多个索引可以引用相同的块,从而减少包含数据所需的空间量(甚至跨备份快照)。

Chunks(块)

块是一些(可能是加密的)数据,末尾是 CRC-32 校验和,开头是类型标记。它由其内容的 SHA-256 校验和标识。

为了生成这样的块,备份数据被分成固定大小或动态大小的块。相同的内容将被散列到相同的校验和。

数据存储的块位于:

<datastore-root>/.chunks/

这个chunk目录被chunks校验和的前四个字节进一步细分,所以带有校验和的chunk:

a342e8151cbf439ce65f3df696b54c67a114982cc0aa751f2852c2f7acc19a8b

驻留在:

<datastore-root>/.chunks/a342/

这样做是为了减少每个目录的文件数量,因为每个目录有很多文件可能对文件系统性能不利。

创建数据存储时,将预先分配这些块目录 ('0000'-'ffff')。

固定大小的块

对于基于块的备份(如 VM),使用固定大小的块。内容(磁盘映像)被分成相同长度的块(通常为 4 MiB)。

这对于 VM 映像非常有效,因为来宾上的文件系统最常尝试将文件分配为连续的块,因此新文件会获得新块,而更改现有文件只会更改它们自己的块。

作为一种优化,Proxmox VE 中的VM可以使用“脏位图”,它可以跟踪镜像的更改块。由于这些位图也是分割成块的镜像的表示,镜像的脏块和需要上传的块之间存在直接关系,因此只需上传磁盘的修改块以进行备份。

由于镜像总是被分成相同大小的块,未更改的块将导致这些块的校验和相同,因此不需要再次备份这些块。这样就不需要存储快照来查找更改的块。

为了一致性,Proxmox VE使用 QEMU 内部快照机制,该机制也不依赖于存储快照。

动态大小的块

如果不想备份基于块的系统而是基于文件的系统,则使用固定大小的块不是一个好主意,因为每次文件大小更改时,剩余的数据都会移动,这将导致许多块发生变化,减少了重复数据删除的数量。

为了改善这一点,Proxmox Backup Server 使用动态大小的块代替。它不是将镜像拆分为固定大小,而是首先生成一致的文件存档 ( pxar ) 并在此动态生成的存档上使用滚动散列来计算块边界。

我们使用 Buzash 的变体,它是一种循环多项式算法。它的工作原理是在迭代数据时不断计算校验和,并在某些条件下触发哈希边界。

假设要备份的系统的大部分文件没有改变,最终算法会在与之前备份相同的数据上触发边界,从而产生可以重复使用的块。

加密块

加密块是一个特例。固定大小和动态大小的块都可以加密,它们的处理方式与普通块略有不同。

加密块的哈希不是用实际的(加密的)块内容计算的,而是用与加密密钥连接的纯文本内容计算的。这样,使用不同密钥加密的两个相同数据块会生成两个不同的校验和,并且多个加密密钥不会发生冲突。

这样做是为了加速备份的客户端部分,因为它只需要加密实际上传的块。先前备份中已经存在的块不需要加密和上传。

注意事项和限制

哈希冲突注意事项

每个散列算法都有机会产生冲突,这意味着两个(或更多)输入生成相同的校验和。对于 SHA-256,这种机会可以忽略不计。要计算这样的碰撞,可以使用概率论中“生日问题”的思想。对于大数字,用普通计算机计算这实际上是不可行的,但有一个很好的近似值:

其中n是尝试的次数,d是可能性的数量。举一个具体的例子,假设有一个 1 PiB 的大型数据存储,以及 4 MiB 的平均块大小。这意味着n=268435456 尝试,和 d=2256可能性。将这些值插入之前的公式中,您将看到在该场景中发生碰撞的概率为:

就上下文而言,在猜 45 个中的 6 个的彩票游戏中,正确猜出所有 6 个数字的机会仅为 1.2277∗10−7,碰撞这意味着概率大约是一样的殊荣13个这样的乐透游戏在一排。

总之,在正常的数据存储中意外发生这种冲突的可能性极小。

此外,SHA-256 容易受到长度扩展攻击,但由于块的大小有上限,所以这不是问题,因为潜在的攻击者不能随意向数据添加超出该限制的内容。

基于文件的备份

由于动态大小的块(用于基于文件的备份)是在自定义存档格式 (pxar) 上创建的,而不是直接覆盖文件,因此文件和块之间没有关系。这意味着 Proxmox 备份客户端必须为每次备份再次读取所有文件,否则将无法生成一致的独立 pxar 存档,其中可以重用原始块。请注意,仍然只会上传新的或更改的块。

加密块的验证

对于加密块,只有原始(明文)数据的校验和可用,因此服务器(没有加密密钥)无法根据它验证其内容。而是只检查 CRC-32 校验和。

posted @ 2021-09-10 16:35  Varden  阅读(457)  评论(0编辑  收藏  举报