Linux 交换的静默磁盘错误和可靠性

Linux 交换的静默磁盘错误和可靠性

我的理解是,硬盘驱动器和 SSD 在驱动器内部实现了一些基本的错误纠正,大多数 RAID 配置(例如 mdadm)将依赖于此来决定驱动器何时无法纠正错误并需要离线。然而,这取决于存储的错误诊断是否 100% 准确。事实并非如此,像两驱动器 RAID-1 镜像这样的常见配置将很容易受到攻击:假设一个驱动器上的某些位已悄然损坏,并且该驱动器不报告读取错误。因此,btrfs 和 ZFS 等文件系统会实现自己的校验和,以免信任有缺陷的驱动器固件、有故障的 SATA 电缆等。

同样,RAM也会存在可靠性问题,因此我们有ECC RAM来解决这个问题。

我的问题是这样的:保护 Linux 交换文件免受两磁盘配置上的驱动器固件未捕获的静默损坏/位腐烂的规范方法是什么(即使用主线内核驱动程序)?在我看来,缺乏端到端保护的配置(例如 btrfs 提供的配置)在某种程度上抵消了 ECC RAM 带来的安心感。但我想不出什么好办法:

  • btrfs 根本不支持交换文件。您可以从 btrfs 文件设置循环设备并对其进行交换。但这有问题:
  • Linux 上的 ZFS 允许使用 ZVOL 作为交换区,我想这可以工作:http://zfsonlinux.org/faq.html#CanIUseaZVOLforSwap- 然而,根据我的阅读,ZFS 通常对内存要求很高,并且让它在仅交换应用程序中工作听起来像是需要做一些工作来解决这个问题。我想这不是我的第一选择。为什么你必须使用一些树外内核模块才能获得可靠的交换,这超出了我的理解范围——在当今时代,肯定有一种方法可以通过大多数现代 Linux 发行版/内核来实现这一目标?
  • 实际上,Linux 内核邮件列表上有一个线程,其中包含用于在内存管理器本身内启用校验和的补丁,这正是我在这个问题中讨论的原因: http://thread.gmane.org/gmane.linux.kernel/989246- 不幸的是,据我所知,该补丁已经死亡,并且由于我未知的原因从未到达上游。太糟糕了,这听起来是一个不错的功能。另一方面,如果您将交换放在 RAID-1 上 - 如果损坏超出了校验和修复的能力,您会希望内存管理器在出现恐慌或其他情况之前尝试从另一个驱动器读取数据,这就是可能超出了内存管理器应该做的范围。

总之:

  • RAM 有 ECC 来纠正错误
  • 永久存储上的文件具有 btrfs 来纠正错误
  • 交换有??​​? <---这是我的问题

答案1

我们相信从交换中检索的数据的完整性,因为存储硬件有校验和、CRC 等。

在上面的评论之一中,您说:

是的,但它不能防止磁盘本身之外的位翻转

“它”在这里指的是磁盘的校验和。

确实如此,但是SATA 使用 32 位 CRC用于命令和数据。因此,您有 40 亿分之一的机会在磁盘和 SATA 控制器之间损坏数据而无法检测到。这意味着连续错误源可能每传输 125 MiB 就会引入一个错误,但像宇宙射线这样罕见的随机错误源会以极低的速率导致无法检测到的错误。

还要认识到,如果您的源以接近每 125 MiB 传输 1 个错误的速度导致未检测到的错误,那么性能将会下降糟糕的由于数量众多检测到需要重新传输的错误。监视和日志记录可能会及时提醒您问题,以避免未检测到的损坏。

至于存储介质的校验和,每个 SATA(以及之前的 PATA)磁盘都使用某种按扇区校验和。 “企业”硬盘的特征之一是受保护的较大扇区额外的数据完整性功能,大大减少了未检测到的错误的机会。

如果没有这些措施,就没有任何意义备用扇区池在每个硬盘驱动器中:驱动器本身无法检测到坏扇区,因此它永远无法交换新扇区。

在另一条评论中,你问:

如果 SATA 如此值得信赖,为什么还有 ZFS、btrfs、ReFS 等校验和文件系统?

一般来说,我们并不要求交换长期存储数据。交换存储的限制是系统的正常运行时间,并且交换中的大多数数据不会持续那么长时间,因为通过系统虚拟内存系统的大多数数据都属于寿命较短的进程。

最重要的是,这些年来,随着内核和内核运行频率的增加,正常运行时间普遍缩短了。libc更新、虚拟化、云架构等。

此外,交换中的大多数数据在管理良好的系统中本质上是不使用的,因为它本身不会耗尽主 RAM。在这样的系统中,唯一最终进入交换的东西是页面该程序不经常使用(如果有的话)。这比您想象的更常见。您的程序链接的大多数动态库都包含您的程序不使用的例程,但它们必须由动态链接器。当操作系统发现您没有使用库中的所有程序文本时,它会将其交换出来,为您的程序的代码和数据腾出空间使用。如果这些换出的内存页面被损坏,谁会知道呢?

与 ZFS 相比,我们希望数据能够持久且持久地存储,这样数据的持续时间不仅会超出系统当前的正常运行时间,而且会超出组成存储系统的各个存储设备的使用寿命。 ZFS 等解决的问题的时间尺度比交换解决的问题大约长两个数量级。因此,与 Linux 交换区相比,我们对 ZFS 的损坏检测要求要高得多。

ZFS 等与交换在另一个关键方面有所不同:我们不将交换文件系统一起进行 RAID。什么时候多个交换设备在一台机器上使用,它是JBOD方案,不像 RAID-0 或更高版本。 (例如 macOS 的链式交换文件方案, Linux 的swapon等)由于交换设备是独立的,而不是像 RAID 那样相互依赖,因此我们不需要大量的校验和,因为更换交换设备不需要查看其他相互依赖的交换设备以获取应在替换设备上运行的数据。在 ZFS 术语中,我们不会从其他存储设备上的冗余副本重新同步交换设备。

所有这些确实意味着您必须使用可靠的交换设备。我曾经使用价值 20 美元的外部 USB HDD 硬盘盒来挽救出现故障的 ZFS 池,却发现该硬盘盒本身并不可靠,在该过程中引入了自身的错误。 ZFS 强大的校验和拯救了我。您无法通过交换文件对存储介质进行如此粗暴的处理。如果交换设备快要死了,并且正在接近最坏的情况,即每传输 125 MiB 就会注入一个无法检测到的错误,您只需尽快更换它。

这个问题的整体偏执感转移到一个例子拜占庭将军问题。仔细阅读,思考向计算机科学界描述该问题的学术论文的 1982 年日期,然后决定您是否在 2019 年对这个问题有新的想法。如果没有,那么也许你会使用该技术由三十位计算机专业毕业生设计,他们都了解拜占庭将军问题。

这是老生常谈的事情。你可能无法想出一个在计算机科学期刊上没有被讨论过的想法、反对意见或解决方案。

SATA 当然不是完全可靠,但除非您打算加入学术界或内核开发团队之一,否则您将无法对现有技术做出实质性贡献。这些问题已经很好地解决了,正如您已经注意到的:ZFS、btrfs、ReFS...作为操作系统用户,您只需相信操作系统的创建者正在为您解决这些问题,因为他们也知道关于拜占庭将军。

这是目前不实用将交换文件放在 ZFS 或 Btrfs 之上,但如果上述内容不能让您放心,您至少可以将其放在 xfs 或 ext4 之上。这比使用专用交换分区更好。

答案2

DM-完整性

看:文档/device-mapper/dm-integrity.txt

dm-integrity通常在日志模式下使用。在交换的情况下,您可以安排不记录日志。这可以显着降低性能开销。我不确定您是否需要在每次启动时重新格式化交换完整性分区,以避免在不干净的关闭后捕获错误。

在里面初步公告dm-integrity,作者表示更倾向于“更高级别的数据完整性保护”。在交换的情况下,这将开启将校验和存储在 RAM 中的可能性。但是,该选项既需要对当前交换代码进行重大修改,又会增加内存使用量。 (当前代码使用范围而不是单个页面/扇区有效地跟踪交换)。


DIF/DIX?

Oracle 在 Linux 2.6.27 中添加了 DIX 支持(2008)。

使用 DIX 是否提供端到端完整性?

你可以咨询你的供应商。我不知道你怎么知道他们是否在撒谎。

需要 DIX 来保护数据在 OS(操作系统)和羟基苯甲酸

DIF 本身增强了数据保护在 HBA 和存储设备之间飞行。 (也可以看看:用一些数字展示错误率的差异)。

正是因为保护字段中的校验和是标准化的,所以技术上可以在不提供任何保护静态数据。只需让 HBA(或存储设备)在读取时重新生成校验和即可。最初的 DIX 项目已经非常明确地表达了这一前景。

  • DIF/DIX 是正交逻辑块校验和
    • 我们仍然爱你,btrfs!
    • 逻辑块校验和错误用于检测损坏的数据
    • 检测发生在读取时间
    • ...可能几个月后,原始缓冲区就会丢失
    • 如果原始缓冲区出现乱码,任何冗余副本也可能是坏的
  • DIF/DIX 大约是积极预防腐败
    • 首先防止不良数据存储在磁盘上
    • ...并在原始缓冲区从内存中删除之前找出问题

--来自 oss.oracle.com 的 lpc08-data-integrity.pdf

他们关于 DIX 的早期帖子之一提到即使驱动器不支持 DIF,也可以在操作系统和 HBA 之间使用 DIX。

在目前使用 DIX 的“企业”环境中,完全撒谎相对不太可能;人们会注意到它。此外,DIF 基于现有硬件,可以使用 520 字节扇区进行格式化。据称,使用 DIF 的协议要求您首先重新格式化驱动器,请参阅sg_format命令等。

更有可能的是,实施不遵循真实的情况端到端原则。举一个例子,提到一家供应商支持 DIX 的较弱校验和选项以节省 CPU 周期,然后该选项被堆栈中更下方的更强校验和所取代。这很有用,但并不是完整的端到端保护。

或者,操作系统可以生成自己的校验和并将其存储在应用程序标记空间中。然而当前的 Linux (v4.20) 不支持此功能。该评论于 2014 年撰写,表明这可能是因为“很少有存储设备实际上允许使用应用程序标签空间”。 (我不确定这是否指存储设备本身、HBA,或两者)。

哪些类型的 DIX 设备可与 Linux 配合使用?

数据和完整性元数据缓冲区的分离以及校验和的选择被称为数据完整性扩展[DIX]。由于这些扩展超出了协议机构(T10、T13)的范围,Oracle 及其合作伙伴正尝试在存储网络行业协会内对它们进行标准化。

--v4.20/文档/块/data-integrity.txt

维基百科告诉我 DIF 在 NVMe 1.2.1 中已标准化。对于 SCSI HBA,如果我们没有一个标准可供参考,那么似乎很难确定这一点。目前,谈论“Linux DIX”支持可能是最准确的:-)。有可用的设备:

Red Hat Enterprise Linux 7.4 完全支持 SCSI T10 DIF/DIX [原文如此],前提是硬件供应商已对其进行认证并为特定 HBA 和存储阵列配置提供全面支持。其他配置不支持 DIF/DIX,不支持在引导设备上使用它,并且虚拟化来宾也不支持它。

目前,已知以下供应商提供此支持......

--RHEL 7.5 发行说明,第 16 章. 存储

RHEL 7.5 发行说明中提到的所有硬件都是光纤通道。

我不了解这个市场。听起来 DIX 将来可能会在服务器中得到更广泛的应用。我不知道为什么它可以用于消费级 SATA 磁盘 - 据我所知,甚至没有命令格式的事实上的标准。我很想知道它是否能在 NVMe 上得到更广泛的应用。

答案3

交换有??​​? <---这是我的问题

交换依然不受保护在 Linux 中(但请参阅 UPD)。

当然,Linux 上的 ZFS 可以用作交换存储但仍然有一个锁定在某些情况下 - 从而有效地撤销该选项。

Btrfs 仍然无法处理交换文件。他们提到了可能使用环回,尽管它的性能很差。有迹象表明 Linux 5 最终可能会拥有它(?)……

保护传统交换的补丁带有校验和的本身并没有成为主流。

所以,总而言之:不。 Linux 在这方面仍然存在差距。

UPD。: 作为 @来源绝地 指出有一个工具,如 dm-integrity。 Linux 内核自 4.12 版本以来已经获得了设备映射器的目标,可以用于为任何通用块设备提供校验和,而那些用于交换的块设备也不例外。该工具并未广泛纳入主要发行版,并且大多数发行版在 udev 子系统中没有任何支持,但最终这种情况应该会改变。当与冗余提供程序配对时,例如放在 MD 又名 Linux 软件 RAID 的顶部,不仅可以检测位腐烂,还可以将 I/O 请求重新路由到健康数据,因为 dm-integrity 会指示存在一个问题和 MD 应该处理它。

答案4

我不认为存在“规范”的方式,因此以下是我个人的看法。

从潜在用户的角度监控了 btrfs 的进展后,我不得不说它对我来说仍然有些模糊。有些功能已经成熟并可供生产使用,而有些功能看似不成熟且使用起来很危险。

就我个人而言,我没有时间决定使用哪些功能,不使用哪些功能,因此我需要花时间来弄清楚如何关闭或打开这些功能。

相比之下,ZFS 坚如磐石且成熟(恕我直言)。因此,为了回答您的问题,我将使用 ZFS(顺便说一句,它不会消耗太多内存 - 见下文)。

但对你来说,btrfs 可能是正确的选择,因为你已经在使用它了(如果我没猜错的话),上面的评论之一展示了如何使用它进行交换。

纯粹出于偶然,我在过去几天将一些 Linux 服务器放在 ZFS 上,每次都包括根文件系统和交换区。在我这样做之前,我已经做了一些非常彻底的研究,这花了我几天的时间。我所学到的内容的简短总结:

ZFS的内存消耗

关于 ZFS 的内存消耗存在一个常见的误解。 ZFS一般是这样的不是消耗大量内存;事实上,它可以在具有 2 GB RAM 的机器上以 TB 的存储空间运行。仅当您使用重复数据删除(默认关闭),那么它需要大量的RAM。

硬件错误检测/纠正

SATA、PATA、RAID 或其他错误检测/纠正机制是否足以保证数据完整性是一个在网络上各个地方引起无休止讨论甚至激烈争论的话题。从理论上讲,硬件存储设备应该报告(并可能纠正)它遇到的任何错误,并且各级数据传输硬件(芯片组、内存等)也应该这样做。

好吧,它们并非在所有情况下都如此,或者它们对错误的反应令人惊讶。我们以典型的 RAID5 配置为例。通常情况下,如果一个磁盘出现问题,它会将其报告给 RAID,而 RAID 又会构建要从其他磁盘读取的数据并将其传递出去,但也会将其写回故障磁盘(这可能会重新映射该磁盘)写入数据之前的扇区);如果同一磁盘报告太多错误,RAID 会将其脱机并通知管理员(如果配置正确)。

到目前为止,一切都很好,但在某些情况下,错误的数据会从磁盘中取出,而磁盘却不会报告错误(请参阅下一节)。大多数 RAID 可以使用奇偶校验信息检测到这种情况,但它们的反应很愚蠢:它们不会报告错误并停止数据传递,而是只会根据错误数据重新计算奇偶校验并将新的奇偶校验写入相应的磁盘,从而将错误数据标记为永远正确。

这是合理的行为吗?据我所知,大多数硬件RAID5控制器甚至Linux的md RAID都是这样操作的。

我不知道 btrfs 的错误更正,但你最终应该再仔细阅读一次文档,特别是如果你使用 btrfs 的 RAID。

沉默的位腐烂

尽管存在所有激烈的争论和(伪)科学讨论:现实大多与理论不同,尽管理论可能陈述相反,但静默位腐烂肯定会发生(静默机器人腐烂通常意味着硬件存储上的数据被损坏,而存储设备没有报告读取此数据时出错,但我将在传输路径中的任何位置添加翻转位到此定义)。

发生这种情况并不是我个人的观点:至少谷歌、亚马逊和欧洲核子研究中心已经发布了涵盖该主题的详细白皮书。这些论文可供公众免费下载。他们对数百万个硬盘和数十万个服务器/存储设备进行了系统实验,要么是因为他们遇到了未检测到的数据损坏问题,要么是因为他们想知道如何在其发生之前阻止它。

总之,他们的服务器场中的数据被损坏的速度明显高于 MTBF 统计数据或其他理论所预期的速度。我所说的显着更高是指数量级。

因此,静默位损坏(即传输路径中任何一点都未被检测到的数据损坏)是现实生活中的一个问题。

数据寿命

Warren Young 说交换数据的生命周期很短,这是正确的。但我想补充以下考虑:不仅数据(在文档的意义上)进入交换,但是(也许更有可能)操作系统或其他部分的部分运行软件。如果我有一个 MP3 交换,我可以忍受翻转位。如果(由于极端情况)我的生产 httpd 服务器软件的一部分处于交换状态,我绝对无法忍受翻转位,如果未检测到,翻转位随后会导致执行损坏的代码。

结语

对我来说,ZFS 解决了这些问题,或者更准确地说,它将它们从磁盘移至内存,从而降低了出现问题的可能性沉默的位衰减了几个数量级。此外,如果配置正确(即镜像而不是 RAID),它会提供干净且合理的错误纠正,其工作方式与预期一致,并且毕竟可以轻松理解。

话虽如此,请注意,你永远不会获得绝对的安全。就我个人而言,我比磁盘更信任我的 ECC RAM,并且我相信 ZFS 及其端到端校验和可以将问题概率降低几个数量级。我会绝不不过,建议使用不带 ECC RAM 的 ZFS。

免责声明:我与任何 ZFS 供应商或开发人员没有任何关系。对于 ZFS 的所有变体(分叉)都是如此。我最近几天才成为它的粉丝......

相关内容