vm.swappiness 不适用于 tmpfs、Ubuntu Server 16.04.5

vm.swappiness 不适用于 tmpfs、Ubuntu Server 16.04.5

需要一些专家的建议才让我来到这里。

观察:在 RAM 使用率高、交换使用率极低(可用空间充足)、tmpfs 使用率高的情况下,操作系统会锁定。

我的设置:

  1. Ubuntu Server 16.04.5 带有内核 4.4.0-131-generic。
  2. 1TB NVMe SSD 上有 64GB RAM、200GB 交换分区。
  3. 64GB tmpfs 分区,具有以下 fstab 条目

    tmpfs  /my-tmp  tmpfs  rw,size=64G,noexec,nosuid,nodev,noatime 0 0
    
  4. /etc/sysctl.conf 中的以下条目

    vm.overcommit_memory=2
    vm.overcommit_ratio=100
    vm.swappiness=40
    

^ 我尝试过 swappiness 值 1、20、40 和默认值 60,但没有成功。

这样的设置是为了支持多种高性能服务,这些服务需要高速临时文件系统访问以及大量的 RAM。

一切都运行正常,直到 RAM 使用率和 tmpfs 使用率都接近最大值,并且操作系统在较长的一段时间内(比如 20 分钟)锁定(没有 ssh 响应、无法按 Ctrl+Alt+F2/3/4、Num Lock 无法切换等),如果发生这种情况,我的一个进程就会崩溃。

我已将可用内存和 tmpfs 使用情况记录到一个文件中,并注意到当发生这种情况时,交换使用情况非常低,可能是因为 tmpfs 使用情况不计入 RAM 使用情况,因为“已用”内存显示的值很小。

系统锁定时内存使用情况的图片如下所示

              total        used        free      shared  buff/cache   available
Mem:            62G        1.2G        324M         60G         61G         75M
Swap:          186G        4.0G        182G

Filesystem      Size  Used Avail Use% Mounted on
tmpfs           6.3G  9.1M  6.3G   1% /run
tmpfs            32G   20M   32G   1% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs            32G     0   32G   0% /sys/fs/cgroup
tmpfs           8.0G  8.0K  8.0G   1% /tmp
tmpfs            64G   61G  3.4G  95% /my-tmp
tmpfs           6.3G  4.0K  6.3G   1% /run/user/1001

让我先发表一些关于如何提高服务效率的评论……它们已经做到了。这只是一个要求非常高的应用程序。我认为有了这么大的交换分区,就没问题了。

迄今为止执行的故障排除:

  1. 在这里阅读 tmpfs 内核文档(多次)

http://man7.org/linux/man-pages/man5/tmpfs.5.html

它说 tmpfs 可以在高内存压力下使用交换空间,但是当系统锁定时,我发现几乎没有交换使用,而不是开始交换。

  1. 阅读许多帮助页面,包括这个

https://unix.stackexchange.com/questions/271211/do-tmpfs-and-devtmpfs-share-the-same-memory-region/271235#271235

假设:

如果我可以将 tmpfs 使用量计为内存使用量,那么也许 vm.swappiness 参数会在这种锁定情况之前发挥作用。

或者,如果我可以独立设置 tmpfs 的交换性,那么这也可以解决问题。

也欢迎其他建议。

感谢您花时间阅读本文。

编辑于 2018-10-11 09:00 PDT:

感谢大家的帮助。我过去尝试过几种交换分区大小和 tmpfs 分区大小的组合。每次我都观察到相同的结果。tmpfs 占用了所有 RAM,这不计入 RAM 使用量(因此 vm.swappiness 不适用于它),并导致操作系统锁定。如果我将 tmpfs 分区设置为小于 RAM,例如 50GB,则不会发生锁定。

这与 ramfs 和 tmpfs 的内核文档相反(这就是我从未使用过 ramfs 的原因)

https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt

https://www.kernel.org/doc/Documentation/filesystems/tmpfs.txt

底线是,如果我系统中的总虚拟内存(RAM + SWAP)大于系统中所有 tmpfs 分区的总大小,则不应该有任何操作系统锁定。这是预期,除非我遗漏了什么。我理解由于交换,事情可能会变慢,但不应该锁定。

编辑于 2018-10-25 09:15 PDT:

顶一下。原问题还没解决。

减少 tmpfs 分区的大小并不是我想要的“解决方案”。我期望有一种方法可以将 tmpfs 分区的大小最大化到系统中可用虚拟内存的极限(RAM + 交换 - tmpfs 分区的其他大小),并且系统可以管理 tmpfs 分区上的数据交换而不会锁定,正如内核文档所述。

答案1

我会尝试……

  • 减少交换至 8G

  • 将 tmpfs 减少到 32G

  • 注释掉修改后的 vm.* sysctl 值:

    # vm.overcommit_memory=2

    # vm.overcommit_ratio=100

    # vm.swappiness=40

  • 将您的 /etc/fstab 条目更改为 32G:

    tmpfs /my-tmp tmpfs rw,size=32G,noexec,nosuid,nodev,noatime 0 0

  • 重启

  • 使用vm.swappiness参数
  • 注意系统性能的任何改善或下降

更新#1:

将 tmpfs 从 64G 减少到 32G 似乎有效。您不希望 tmpfs 消耗所有物理 RAM。

相关内容