为什么大多数人建议将 swappiness 降低到 10-20?

为什么大多数人建议将 swappiness 降低到 10-20?

我已经在多个网站上看到建议将 swappiness 降低至 10-20 以获得更好的性能。

这是神话吗?这是一般规则吗?我有一台配备 4GB 内存和 128GB SSD 硬盘的笔记本电脑,您建议我的 swappiness 值是多少?

谢谢。

答案1

因为大多数人认为交换 = 坏事,如果不减少交换,系统就会在不需要时进行交换。这两种说法都不正确。人们把交换与系统陷入困境的时候联系在一起——然而,主要是交换因为系统陷入了困境,而不是相反。当系统进行交换时,它已经将性能成本纳入了交换决策中,并决定不这样做会对系统性能或稳定性造成更大的总体损失。

总体而言,默认设置可带来良好的整体性能和稳定性。我建议保留默认设置。Linux 还有其他途径可以改进其内存管理以解决一些极端情况,但总的来说,swappiness 控制并不是一个好的解决方法 - 在一个方向上进行调整可能会解决一个问题并产生其他问题。如果可能的话,只需安装更多物理 RAM(而不使用 swappiness)就可以掩盖所有其他补救措施。

Linux 如何使用 RAM

任何未被应用程序使用的 RAM 都可用作“缓存”。缓存对于快速、平稳运行的系统非常重要,可加快磁盘的读取和写入速度。

如果您的应用程序增加内存使用量,以至于几乎占用了所有 RAM,则缓存将缩小,结果磁盘操作平均速度会变慢。如今,只有几十兆字节或更少的缓存是不够的。

如果应用程序进一步增加内存使用量(假设您没有交换空间),那么您不仅没有缓存空间,而且最终会耗尽内存,系统将不得不终止正在运行的进程。终止进程比减速更糟糕,因为它会让您的系统变得不稳定、不可预测。

Linux 如何使用交换

为了解决这两个问题,您的系统可以将一些很少使用的应用程序内存重新分配给磁盘上的交换空间,从而释放 RAM。额外的 RAM 可以防止进程因内存不足而死亡,并且可以回收少量缓存,使磁盘操作可以更顺畅地运行。

但是,这种重新分配并不是按照明确的截止点进行的。Linux 不会在分配达到一定百分比后开始交换。它有一个“模糊”算法。它考虑了很多因素,可以用“内存分配压力有多大”来最好地描述。如果分配新内存的“压力”很大,那么将增加一些内存被交换以腾出更多空间的机会。如果“压力”较小,那么将减少这些机会。

您的系统有一个“swappiness”设置,可帮助您调整此“压力”的计算方式。它通常被错误地表示为“RAM 百分比”,但事实并非如此,它只是用作公式一部分的值。建议的合理值约为 40 到 60,而 60 现在是默认值。

让系统在必要时进行交换总体来说是一件非常好的事情,即使您有大量 RAM。让系统在必要时进行交换可以让您高枕无忧,因为如果您遇到内存不足的情况,即使是暂时的(在运行使用大量内存的短进程时),您的系统还有第二次机会让一切继续运行。如果您完全禁用交换,那么您将面临进程因无法分配内存而被终止的风险。

当系统陷入停滞并发生大量交换时,会发生什么情况?

交换是一种缓慢而昂贵的操作,因此系统会避免执行该操作,除非它计算出缓存性能的权衡将完全弥补它,或者有必要避免终止进程。

很多时候,人们会发现系统严重损坏磁盘并使用大量交换空间,并把责任归咎于交换。这是错误的做法。如果交换达到这种极端程度,则意味着交换是系统处理内存不足问题的一种尝试,而不是问题的根源,如果不进行交换,正在运行的进程就会随机死亡。

那么桌面系统呢?它们不需要不同的方法吗?

桌面系统的用户确实希望系统能够“灵敏地”响应用户发起的操作(例如打开应用程序),这类操作有时会由于所需内存的增加而触发交换。

一些人尝试调整此问题的一种方法是减少 swappiness 参数,这可以提高系统对应用程序耗尽内存和缓存空间不足的容忍度。

然而,这只是在转移目标。第一个应用程序现在可能无需交换操作即可加载,但对于下一个加载的应用程序来说,这将减少空闲时间。相同的交换可能稍后才会发生,当您下次打开应用程序时。与此同时,由于缓存大小减少,系统性能整体下降。因此,降低交换设置带来的任何好处可能难以衡量,有时会减少交换延迟,但有时会导致其他性能下降。如果您知道自己在做什么,稍微降低交换设置可能是合理的,但将其降低到 10 的低水平可能会使系统能够容忍非常低的缓存大小,并使系统更容易在短时间内进行交换。

应避免完全禁用交换,因为您会失去针对内存不足情况的附加保护,而这可能会导致进程崩溃或被终止。

目前最有效的补救措施是(如果您经济条件允许的话)安装更多 RAM。

无论如何,可以在具有大量 RAM 的系统上禁用交换吗?

如果您拥有的 RAM 远远超过应用程序所需的 RAM,那么您很少需要交换。因此,在所有常见情况下,禁用交换可能不会产生任何影响。但是,如果您拥有足够的 RAM,则启用交换也不会有任何影响,因为系统在不需要时不会进行交换。

只有在最不寻常的情况是,系统会发现自己内存不足,因此缓存系统会受到阻碍,在这种情况下,你会交换最多。因此,您可以放心地将交换保留在其正常设置上,这样当您有足够的内存时,它就不会产生负面影响。

但是交换如何能加速我的系统呢?交换不会减慢系统速度吗?

将数据从 RAM 传输到交换区的操作很慢,但只有当内核确信保持合理的缓存大小所带来的总体收益将超过此收益时才会执行此操作。如果您的系统由于磁盘抖动而变得非常慢,则交换区并不是导致此问题的原因,而只是试图缓解此问题。

一旦数据被交换,什么时候会再次出来?

任何给定的内存部分一旦被使用(读取或写入)就会从交换中返回。但是,通常交换的内存是长时间未访问且预计不会很快需要的内存。

将数据从交换中移出与将数据放入交换中一样耗时。如果不需要,内核不会从交换中删除数据。当数据在交换中且未被使用时,它会为其他事情留出更多内存正在使用,并且有更多的系统缓存。

有哪些情况适合减少 swappiness?

是的。如果您运行的服务器专用于某个特定的服务器应用程序,而该应用程序无法从系统缓存中获益。某些数据库服务器(如 Oracle 服务器、MySQL/MariaDB)建议在某些情况下将 swappiness 降低到 1 到 10,因为这些数据库引擎使用自己的缓存。

请注意,仅当您的系统专用于该一项任务时,这才是正确的,并且对于 MySQL/MariaDB,仅当您仅使用纯 InnoDB 或 XtraDB,而不是 MyISAM 或 Aria 等时,才是正确的。如果您的系统的专用目的围绕执行自己的缓存且不受益于系统缓存的应用程序,降低 swappiness 可能是一个好主意。

答案2

在普通桌面上,您有 4-5 个活动任务,这些任务会占用 50-60% 的内存。如果您将 swappiness 设置为 60,则大约 1/4-1/3 的活动任务页面将被交换出去。这意味着,对于每个任务更改、对于您打开的每个新选项卡、对于每个 JS 执行,都会有一个交换过程。

解决方案是将 swappiness 设置为 10。根据实际观察,这会导致系统放弃磁盘 io 缓存(这在桌面上几乎没有作用,因为读/写缓存实际上根本没有使用。除非您不断复制大型文件)而不是将任何东西推入交换。实际上,这意味着系统将拒绝交换页面,而是切断 io 缓存,除非它达到 90% 的内存使用率。而这反过来意味着流畅、无交换、快速的桌面体验。

然而,在文件服务器上,我会将 swappiness 设置为 60 甚至更高,因为服务器没有必须整体保存在内存中的大量活动前台任务,而是有很多较小的进程,这些进程要么在工作,要么在休眠,并且不会立即改变其状态。相反,服务器通常向客户端提供(原谅)完全相同的数据,这使得磁盘 io 缓存更有价值。因此,在服务器上,最好换出休眠进程,释放内存空间以用于磁盘缓存请求。

然而,在桌面上,这种精确的设置会导致交换真实应用程序的内存块,这些应用程序几乎不断地修改或访问这些数据。

奇怪的是,浏览器通常会保留大量内存,并不断修改这些内存。当这些内存块被换出时,如果请求回来则需要一段时间 - 与此同时,浏览器会继续更新其缓存。这会导致巨大的延迟。实际上,您将需要等待 2 分钟才能在新选项卡中加载单个网页。

桌面并不真正关心磁盘 io,因为桌面很少读取和写入可缓存的重复大量数据。减少磁盘 io 以尽可能防止交换对桌面来说要比保留 30% 的内存用于磁盘缓存而交换出 30% 的 RAM(充满属于活跃使用的应用程序的块)更有利。

只需启动 htop,打开浏览器、GIMP、LibreOffice - 在那里加载一些文档,然后浏览几个小时。真的就这么简单。

答案3

如果您在 Linux 系统上运行 Java 服务器,您确实应该考虑将 swappiness 从默认值 60 大幅降低。因此 20 确实是一个不错的开始。交换对于垃圾收集过程来说是一个杀手,因为每次收集都需要触及进程内存的大部分。操作系统没有办法检测此类进程并为其做正确的事情。对于高效的应用服务器,最佳做法是尽可能避免交换。

答案4

我想从大数据性能工程师的角度添加一些观点,以便让其他人更多地了解 2017 年的技术背景。

我个人的经验是,虽然我通常会禁用交换以确保我的系统以最大速度运行,但在我的工作站上,针对特定问题,我发现交换量为 1 和 10 会导致冻结(永久)和长时间暂停。对于此特定应用程序,交换量为 80 可带来比默认值 (60) 更好的性能和更短的暂停。请注意,我有 8GB RAM 和 4x 256GB 交换,由 1 个 HDD 支持。我通常会说明基准测试和完整硬件规格中看到的精确统计数据,但我还没有做任何说明,而且这是一台最近的低端台式机,在这里并不重要。

在我以前的公司,我们没有在具有 [500GB 到 4TB] x [10-100] 个节点的 Spark 服务器上启用 swappiness,原因是我们认为性能不佳是重新设计数据管道和数据结构以更高效的方式的标志。我们也不想对 HDD/SSD 进行基准测试。此外,交换这么多 RAM 需要每个节点 10-30 个磁盘并进行并行写入以最大限度地缩短磁盘访问时间。

今天、20 年前和 20 年后,情况仍然会是有些问题对于 RAM 来说太大了。有了无限的时间和金钱,我们可以购买/租赁更多硬件或重新设计任何流程,以使性能达到理想的水平。交换只是一种让我们忽略真正问题(我们没有足够的 RAM,我们不想花更多的钱)的黑客手段。

对于那些认为提高交换能力不是一个好建议的人,这里有一个小观点。过去,硬盘驱动器只有几 KB 的缓存(如果有的话)。接口是 IDE/并行 ATA。CPU 总线以及 RAM 和许多其他东西也慢得多。简而言之,系统在各个方面都非常慢(相对于今天而言)。几年前,硬盘驱动器使用 SATA3。今天,他们使用 NVMe 协议,这显著改善了延迟。硬盘驱动器有许多 MB 的缓存。最有趣的部分是当您使用现代 SSD(更稳定的读/写耐久性和性能)与 NVMe 或 PCIe 作为交换存储时。这是成本和性能之间的最佳折衷。请不要在便宜或旧的 SSD 上尝试此操作。

交换+SSD!对于高性能易失性存储,我强烈建议尝试使用高交换值。它主要取决于内存访问模式(随机访问所有内存与很少访问大多数内存)、内存使用情况、磁盘带宽是否已饱和以及抖动的实际成本。

相关内容