我有几个运行 RHEL 的裸机服务器,之前它们出现过一些 java/JVM 崩溃问题,偶尔还会出现一些内核级内存错误消息。由于工作负载被转移到其他地方,这些服务器现在大多处于闲置状态,等待更换内存。
在阅读了 Aleksey Shipilёv 的帖子《请测试你的内存》后,我想在主机上运行memtester,看看它是否能在不重启的情况下发现这些问题。通常我们在重启时只会使用“普通”的 memtest86+,但有其他选择可能会很有趣。
在具有 3 TB 内存的 2016 年服务器上完成 memtester 运行需要多长时间?
在这样的一个主机 (v6.10) 上,memtest86+ 运行大约需要 3 天。正如 Shipolev 的文章所提到的,memtest 是多线程的,这可能有所帮助。
在同一台服务器上,运行
memtester 2700g 3
(版本 4.5.1)在运行了 21 天后,仍然处于 3 次循环中的第一次循环。它持续使用 100% 的一个核心。这是一台 R930,配备英特尔 CPU E7-8880 v4(176 核)和 96x32 GB DDR4 RAM(2400 MHz)。
总之,重启机器并运行常规的 memtest86+ 仍然是最好的选择。需要停止或将工作负载移到其他地方才能进行此类调查。
这种方式无法预先测试内存,因此只有在内核检测到某些错误或 JVM 崩溃次数过多以至于必须停止或将工作负载移至其他地方后,才值得进行内存测试。在某些情况下,使用 memtester 可能仍然有用,因为要测试的内存量有限,并且物理访问或重新启动的成本过高。
示例日志
没有普遍的答案:这取决于 RAM 和 CPU 的内存控制器,并且从当前可用的服务器硬件来看,可以预期存在几个数量级的差异。
一般来说,通过从用户空间测试虚拟内存来测试物理内存是……嗯,从设计上来说,这是一个坏主意。与实际与物理 RAM 交互相比,您将花费更多时间来强调内核中的分页逻辑、CPU 的 MMU、多核机器上的多层缓存一致性(3 TB 机器很可能如此),并且如果您没有以优化 CPU 访问内存的方式(在 x86_64/AVX2 及更高版本的机器上,与
mm256_stream_*
经典加载/存储相比……)进行此操作,您将得到另一个因素,通常是 5 倍的性能损失。因此,您选择
memtest86+
改为(这确实使这个问答偏离了本网站的主题,您不觉得吗?)是一种正确的举动,某种程度上(我认为它实际上不知道您机器的缓存和一致性拓扑,因此它无法很好地进行并行测试)。但老实说:为什么?即使是那个假设使用小得多的机器(128 GB RAM 对他们来说似乎很大)的博客也说,好的,您从 ECC RAM 开始。绝对不可能有一个节点连接到 3 TB 的非 ECC RAM。如果您有 ECC RAM,那么您将有一个计数器来显示需要纠正的错误数。RAM 上的位翻转是可以预料的,在 3TB 的 RAM 中,您可以相当肯定至少发生了一次 - 但 ECC 的工作是将物理错误转换回正确的数据,以便您获得可靠的内存。当然,虽然 ECC 可以纠正大多数错误,但也可能会发生(运气不好)错误非常严重,以至于结果看起来像有效数据(或者更容易“纠正”为错误的有效数据而不是正确数据)。因此,如果您知道您的机器使用哪一代 RAM,以及使用哪种 ECC,您可以从可纠正ECC 错误计数器推断出错误纠正的错误数量。这在实际使用中比运行合成内存检查要好得多——合成内存检查可能会也可能不会看到诸如邻近效应之类的东西(想想 Rowhammer 之类的东西),而 ECC 计数器实际上会观察使用过程中出现的问题。可纠正 ECC 错误的激增将导致调查。
从另一个角度来看:如果您有 ECC 内存,您应该有已更正和未更正的错误计数器。在 RHEL8 和 RHEL9 上,安装软件包
rasdaemon
,然后ras-mc-ctl --error-count
列出本次启动时硬件记录的错误计数:此外,您可以
rasdaemon
在启动时启动该服务,它会将检测到的错误放入您可以使用的数据库中ras-mc-ctl --errors
。这样您就可以将已知内存错误的时间戳与崩溃和内核错误的时间戳进行比较。最后,
rasdaemon
中的配置/etc/sysconfig/rasdaemon
允许您将其设置为告诉内核在一段时间内内存中有太多已更正的错误时将其脱机;如果您设置了该配置,并且看到太多页面脱机,则说明内存有问题。通过减少内存容量以移除有故障的 RAM,您还可以让系统在内存故障的情况下继续运行。