我的 Debian 服务器有问题。我们运行 4 台不同的服务器,它们都配有 Intel CPU 和 128GB RAM。其中两台运行 Wheezy,两台运行 Jessie。我们在这些系统上运行 Java 软件,该软件占用大量内存,可能会耗尽所有内存。
对于这些情况,我在每台服务器上安装了一个交换分区,该分区位于运行在 2 个 SSD 上的 RAID 1 上。
Jessie 系统的问题:当系统内存即将耗尽时,它会开始交换。这由 vm.swappiness = 10 参数调整,在我看来没问题。但交换本身进行得太频繁,以至于系统完全挂起/冻结。磁盘 io 太多,以至于系统不再响应。
我在所有系统上进行了一些测试,并使用以下方法人为地将 RAM 填充到 120%:
stress --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 1.2;}' < /proc/meminfo)k --vm-keep -m 1
系统开始交换,并在 20% 的交换运行时冻结。大约 20 秒后,系统恢复正常并再次可用,但在冻结期间,一切都不再起作用。
当然,这种行为对于生产系统来说是不可接受的。我期望交换具有高优先级,但不应使用超过 90% 的系统资源,以便系统仍能以某种方式处理。
将交换性调整为不同的值没有帮助。
我们使用以下内核:
Wheezy:Linux A 3.2.0-4-amd64 #1 SMP Debian 3.2.68-1+deb7u1 x86_64 GNU/Linux
杰西:Linux B 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u4 (2016-02-29) x86_64 GNU/Linux
有没有人遇到过同样的问题并找到了解决方案?
编辑: 感谢大家的评论和解释。当然我不想使用交换作为备用内存。120% 的使用率只是一个测试。在生产中,系统可能使用了 100,0001% 的内存,并且已经停止响应。在运行我们软件的生产模式下,数据更改频率也很高,因此系统可能会很忙,因为整个过程中只会来回交换少量数据。
答案1
即使在采用当前 Debian Buster OS 版本的服务器上,我们的 Java 应用程序仍然面临这个问题。
我们为防止这种情况发生所采取的措施是:在
/etc/sysctl.conf
配置参数
vm.swappiness = 0
除非系统确实不需要交换,否则不会使用它。除此之外,我们确保将 Java 应用程序配置为仅使用最大内存量。
答案2
您可能需要考虑以下三个选项:
1) 调整应用程序的内存使用量,使其不超过系统中的可用内存,并完全禁用交换。我只在非常特殊的情况下才配置带有交换的系统。如果您的服务器有多个 NUMA 节点,请查看最大的内存消耗者的配置并查找与 NUMA 相关的选项。如果没有,请使用 numactl 设置进程的内存以在节点之间交错。在 Google 上搜索“mysql swapping insanity”以了解更多详细信息,了解为什么 NUMA 会导致不寻常的交换和 OOM 情况,即使有足够的内存可用。
2) 设置 swappiness=100。这将使内核在出现压力迹象时立即换出页面。这可能会导致交换更频繁地发生,但增量更小,从而导致系统长时间停机。
3) 使用 lz4 压缩在 zram 上配置交换。这比交换到旋转的 rust 或 SATA SSD 要快得多(不过可能比现代 NVMe 慢)。确保将 zram 大小配置为小于扣除为大页面保留的任何内存后的可用内存量。例如,如果您有 128GB 的 RAM 并且保留了 64GB 的大页面,则将 zram 配置为 60GB。它是动态分配和释放的,并且 0 填充的页面(您会惊讶于工作内存中有多少这样的页面)会被直接丢弃。