需要一些专家的建议才让我来到这里。
观察:在 RAM 使用率高、交换使用率极低(可用空间充足)、tmpfs 使用率高的情况下,操作系统会锁定。
我的设置:
- Ubuntu Server 16.04.5 带有内核 4.4.0-131-generic。
- 1TB NVMe SSD 上有 64GB RAM、200GB 交换分区。
64GB tmpfs 分区,具有以下 fstab 条目
tmpfs /my-tmp tmpfs rw,size=64G,noexec,nosuid,nodev,noatime 0 0
/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
让我先发表一些关于如何提高服务效率的评论……它们已经做到了。这只是一个要求非常高的应用程序。我认为有了这么大的交换分区,就没问题了。
迄今为止执行的故障排除:
- 在这里阅读 tmpfs 内核文档(多次)
http://man7.org/linux/man-pages/man5/tmpfs.5.html
它说 tmpfs 可以在高内存压力下使用交换空间,但是当系统锁定时,我发现几乎没有交换使用,而不是开始交换。
- 阅读许多帮助页面,包括这个
假设:
如果我可以将 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。