在了解 RAIDZ 的优势的过程中,我遇到了以下概念写洞。
作为这一页解释称,写入漏洞是指在写入过程中断电时阵列磁盘之间产生的不一致。该页面还解释称,它会影响 RAID-5/6(如果在写入数据之后但在计算奇偶校验之前断电)和 RAID-1(数据写入一个磁盘,但不写入其他磁盘),并且这是一个隐蔽的问题,只能在重新同步/清理期间或(灾难性地)重建其中一个磁盘期间检测到...但是,最多 的 这 其他 来源谈论它,因为它只影响基于奇偶校验的 RAID 级别。
据我所知,我认为这也可能是 RAID-1 的问题,因为从包含漏洞的磁盘读取会返回垃圾,所以......这对每一个RAID 级别还是不是?它是否依赖于实现?它是否只影响软件 RAID,还是也影响硬件控制器?(补充:mdadm
在这方面表现如何?)
答案1
期限写洞用于描述处理无电池保护的 RAID 阵列时出现的两个类似但不同的问题:
有时是不当定义为任何由于突然断电导致 RAID 阵列损坏。根据这个(错误的)定义,RAID1 容易受到写入漏洞的影响,因为您无法自动写入两个不同的磁盘;
的正确定义写洞,这是整条条纹由于条带更新期间突然断电而导致的数据冗余,仅适用于基于奇偶校验的 RAID。
第二个正确的写入漏洞定义需要进一步解释:假设一个 3 磁盘 RAID5,其块大小为 64K,条带大小为 128K(每个条带 +64K 奇偶校验大小)。如果在将 4K 写入磁盘 #1 后断电,但期间磁盘 #3 上的奇偶校验更新,我们可能会遇到伪造的(即损坏的)奇偶校验块和未检测到的数据一致性问题。如果稍后磁盘 #2 坏了,并且使用奇偶校验通过对磁盘 #1 和磁盘 #3 进行异或来恢复原始数据,则重建的 64K(最初驻留在磁盘 #2 上)和不是最近写入的,仍然会被损坏。
这是一个人为的例子,但它应该揭示与 写洞:与最新中断写入共享同一条带的未触及、静止、无关数据丢失。换句话说,如果文件 A 是几年前写入的,但与刚刚写入的文件 B 共享同一条带,并且系统在文件 B 更新期间断电,则文件 A 将面临风险。
另一件需要考虑的事情是阵列的写入策略:使用读/重建/写入(即:当发生部分写入时重写整个条带)与读/修改/写入(即:仅更新受影响的块+奇偶校验)暴露于不同类型的写入漏洞。
从上面可以看出,RAID0 和 RAID1 不存在适当的写入漏洞:它们没有奇偶校验,奇偶校验可能会“不同步”,导致整个条带无效。请注意,RAID1 镜像支路能非正常关机后可能会不同步,但唯一损坏的是最新写入的数据。之前写入的数据(即静止数据)不会遇到任何问题。
定义并确定了适当的写入漏洞范围后,如何避免?
HW RAID 使用非易失性写入缓存(即:BBU+DRAM 或电容支持闪存模块)来持久存储要写入的更新。如果断电,HW RAID 卡将在恢复供电并启动系统时重新发出任何待处理的操作,将其缓存刷新到磁盘盘片。这不仅可以防止正确的写入漏洞,还可以防止上次写入的数据损坏;
Linux MD RAID 使用写入位图来记录要写入的条带前更新它们。如果断电,脏位图将用于重新计算受影响条带的任何奇偶校验数据。这只能防止真正的写入漏洞;最新写入的数据可能会被破坏(除非由 fsync()+写入屏障支持)。使用相同的方法重新同步 RAID1 阵列的不同步部分(以确保两个镜像支路同步,尽管镜像不存在写入漏洞);
较新的 Linux MD RAID5/6 应该可以选择使用记录/日志设备,部分模拟适当的硬件 RAID 卡的非易失性写回缓存(并且,根据特定的补丁/实施,保护免受写洞和最后写入的数据损坏或仅防止写洞);
最后,避免RAIDZ两个都使用最“优雅”但影响性能的方法来写入漏洞和最后数据损坏:仅写入全尺寸条带(并在 ZIL/SLOG 中记录任何同步写入)。
有用的链接:
https://neil.brown.name/blog/20110614101708
https://www.kernel.org/doc/Documentation/md/raid5-ppl.txt
https://www.kernel.org/doc/Documentation/md/raid5-cache.txt
https://lwn.net/Articles/665299/
答案2
这就是为什么 RAID 需要缓存电池或其他某种缓存一致性验证方法的原因。所有 RAID 卡都应具有电池支持的缓存,并且所有存储控制器都应具有镜像缓存。对于软件 RAID,我认为没有好的答案。我认为即使是 RAID Z 也可能因断电而失败。
答案3
写入漏洞可能会影响每一个RAID 级别但 RAID-0;条带化(RAID-4/5/6)和镜像(RAID-1)配置都可能存在漏洞,这仅仅是因为在 2 个或更多磁盘中不可能进行原子写入。
我说“可能”是因为这个问题与实现有关。除了 RAID-Z 等下一代文件系统解决方案之外,经典的软件 RAID 实现也找到了解决这个问题的方法mdadm
:相对较近引入了使用专用缓存磁盘来避免这种情况的日志功能,即使您选择不使用此功能,它也会在每个不正常关机后强制重新同步,从而在发生写入漏洞时立即捕获并解决它。
感谢#zfs irc 频道的帮助!
答案4
我认为2RAID 阵列“写入洞”的可能定义。
您提到的页面将“写入漏洞”理解为 RAID 阵列不一致。要理解这一点,您应该考虑 RAID 阵列的工作原理。写入操作被发送到阵列的不同磁盘。但由于磁盘是独立的,因此无法保证写入操作(由磁盘)真正提交到物理介质的顺序。换句话说,当您将块写入 RAID 阵列时,写入操作不是原子的。这不是阵列正常运行中的问题。但在断电事件或任何其他严重故障等情况下可能会出现问题。
RAID 阵列的内部不一致可能发生在具有某种数据冗余的每个 RAID 级别中:RAID 1、4、5、6 等。RAID 0 不会出现不一致问题,因为阵列的不同磁盘之间不需要同步冗余数据。
有几种可能的策略来处理 RAID 阵列不一致问题:
Linux MD 软件 RAID 在组装标记为“脏”的 RAID 阵列时默认使用“同步”策略。即,对于 RAID 1 阵列,其中一个磁盘将作为主磁盘,其数据将复制到其他磁盘。对于 RAID 4/5/6,将读取数据块。然后重新生成奇偶校验块并将其写入磁盘。同步过程可能非常漫长。为了使其更快,有一个称为写入意图“位图”的功能,它可以跟踪阵列中的热块。此位图功能将显著减少同步过程的持续时间,但写入操作期间会有一些性能损失。
带有电池供电内存的硬件 RAID 阵列采用两步策略。首先,要写入的数据块被提交到充当日志的内存中。完成此步骤后,数据块被发送到磁盘。如果发生断电事件或任何其他故障,RAID 控制器将检查内存中的所有数据块是否确实已提交到磁盘。
还有一种 CoW(写时复制)策略,稍后我会进一步解释。
“写入漏洞”的另一种可能定义是指 RAID 4/5/6 在某些情况下出现的数据丢失问题(RAID 级别 1 和 10 不受此类“写入漏洞”的影响)。我引用Neel Brown 定义所讨论的问题:
“写入漏洞是一个简单的概念,适用于任何条带+奇偶校验 RAID 布局,如 RAID4、RAID5、RAID6 等。当阵列从非正常关机启动时,就会出现问题所有设备都可用, 或者如果在非正常关机后恢复奇偶校验之前发现读取错误。“
也就是说,您有一个 RAID 5 阵列,并且发生了断电事件。RAID 将尝试使阵列恢复到一致状态。但是其中一个磁盘不再工作,或者无法读取其某些扇区。因此,无法从数据块中重新生成奇偶校验,因为其中一些数据块丢失了。您可能会说:是的,但是阵列中有冗余。所以我们可以使用奇偶校验来重新生成丢失的数据块,不是吗?答案是否定的。如果这样做,您可能会在某些数据块中得到垃圾数据。这是一个非常严重的问题。问题不在于某些数据块是否被写入(现代日志文件系统对此没有任何实际问题)。而是阵列的某些数据块丢失了或者(如果重新生成)它们是垃圾。无论如何,这里都存在一个严重的问题。
如果我们采用“写入漏洞”的更严格定义,我们会发现这是一个特殊的极端情况,只会在某些情况下发生。必须发生严重故障,例如断电事件。此外,某些磁盘必须发生故障(完全或部分故障)。但对于 RAID 4/5/6(具有奇偶校验块的级别),风险是存在的。
可以使用 2 步写入策略(或之前解释过的使用日志技术写入)来防止这种风险。借助日志,即使在这些极端情况下,所有数据块都可以安全地写入磁盘。如果实施得当,带有电池备份的硬件 RAID 不会出现任何“写入漏洞”问题。Linux MD 软件 RAID 也得到了使用日记功能书写几年前,这有效地防止了“写入漏洞”问题。
我对 ZFS 不太熟悉,但我认为它在 RAID-Z 阵列中使用了 CoW(写时复制)技术来避免任何“写漏洞”问题。它会将所有数据和奇偶校验写入一些未使用的空间,然后它会更新对这些物理块的虚拟引用。通过使用这个两步过程,可以保证写入操作是原子的。这样就可以有效地防止写漏洞问题。