在 Ubuntu 14.04 上禁用 OOM 杀手

Has*_*aig 2 linux debian ubuntu ubuntu-14.04

如何OOM killer在 Ubuntu 14.04 上禁用?有一个描述在这里,但它似乎并没有工作过的OP。能得到明确步骤的答案会很棒。

LSe*_*rni 10

这是一个 XY 问题;也就是说,你确实有一个问题(X),不管你是否知道,并且相信你可以通过解决一个不同的问题来解决问题,这就是问题 Y。

为什么要禁用oomkiller?这就是您需要解决的 X 问题。您应该做的是调查并详细说明问题X。提供详细信息,我们可能会帮助您。

解决问题 Y 并禁用 oomkiller 通常是一个非常糟糕的主意,它肯定会产生可能解决的更大的问题。

调用 oomkiller 是一种绝望的、最后的手段,当事情在记忆方面出了问题,厄运即将来临。您的系统有 6 名乘客,需要一小时,而氧气供应只有 5 个工时。你可能会认为随机杀死一名乘客(不是随机 -实际上新陈代谢较高的人)是一件可怕的事情,但另一种选择是在停靠前十分钟让所有六名乘客窒息死亡。

假设你这样做

您成功禁用了oomkiller。系统重新启动并继续其愉快的方式。现在可能发生两件事:

  • oomkiller从不需要调用。你所做的一切都是徒劳的。
  • oomkiller确实需要调用

但是为什么需要 oomkiller 呢?那是因为某些进程需要内存,而系统发现它无法为该内存提供服务。

有一个我们称之为“memoryhog”的进程,它会被 oomkiller 杀死,现在不是这样。什么没有发生?

选项 1:OOM 意味着死亡

您在启动时发出了这些命令

sysctl vm.panic_on_oom=1
sysctl kernel.panic=5
Run Code Online (Sandbox Code Playgroud)

或将此添加到/etc/sysctl.conf并重新启动

vm.panic_on_oom=1
kernel.panic=5
Run Code Online (Sandbox Code Playgroud)

一旦系统被占用,它会在 5 秒后恐慌并重新启动。

选项2:如果可能,杀死其他人

您在启动时将某些进程分类为“消耗性”,而将其他一些进程分类为“不可消耗性”。例如,Apache 可能是可消耗的,而不是 MySQL。因此,当 Apache 遇到一些荒谬的大请求时(在 LAMP 系统上,通常是通过将 PHP 内存分配设置为可笑的大值而不是更改某些内存绑定或泄漏方法的“简单修复”来实现),即使 MySQL 也会杀死 Apache 子进程是一只更大的猪。通过这种方式,客户只会看到一个空白页面,点击重新加载,获得另一个......最后停止。

您可以通过在启动时记录 MySQL 的 PID 并调整其 OOM 等级来实现:

echo -15 > /proc/$( pidof mysql )/oom_adj
Run Code Online (Sandbox Code Playgroud)

但是在这种情况下,我也会调整Apache 的 child conf

请注意,如果此选项解决了您的问题,则意味着您在其他进程中存在问题(例如,一个太大的 PHP 进程。这源于次优算法或数据选择阶段。您按照链条直到到达在一个真正需要解决的问题上)。

可能,安装更多 RAM 会产生相同的效果。

在这个选项中,如果 MySQL 本身增长太多(例如你搞砸了 innodb_pool_size 值),那么无论如何MySQL 都会被杀死。

选项 3:永远不要杀死 $MYPRECIOUSSS 进程

如上所述,但现在调整设置为-17。

我现在谈论的是 MySQL,但大多数程序的行为方式相同。我确信 PostgreSQL 和 Oracle 都这样做(而且他们有权这样做。滥用 RDBMS 会带来危险)。

这个选项很危险,因为 oomkiller 会杀死其他人,可能会重复,但最重要的是,可能是因为 $MYPRECIOUSSS 本身

因此,失控的进程会从内存中驱逐其他所有人,直到系统无法使用并且您甚至无法登录以进行检查或执行任何操作。不久之后,MySQL 将破坏自己的状态信息并严重崩溃,您将面临一个很长的fsck会话,然后是艰苦的表修复,然后是仔细的事务重建。

我可以根据我自己的经验告诉你,管理层会对设置实际上是一颗滴答作响的定时炸弹的人非常不满。会有很多指责(MySQL 配置错误,Apache 泄漏,OOMKiller 疯了,它是一个黑客......),所以“一个”可能是“许多”。然而,对于这第三个选项,我不能过分强调完整、充分和不断更新和监控备份的需求,以及恢复测试。

选项 4 - “关闭” OOMkiller

这个选项可能看起来像一个笑话。就像旧的 Windows XP 技巧“如何永远避免蓝屏!” - 这实际上确实有效......通过设置一个鲜为人知的变量使它们变成洋红色。

但是您可以通过编辑/etc/sysctl.conf文件并添加以下行来使其永远不会调用 oomkiller :

vm.overcommit_memory = 2
vm.overcommit_kbytes = 0
Run Code Online (Sandbox Code Playgroud)

然后还运行命令sysctl vm.overcommit_memory=2sysctl vm.overcommit_kbytes=0避免需要重新启动。

现在会发生什么?如果系统有足够的内存,什么都不会发生——就像你什么都没做一样。

当系统内存不足时,进程将无法启动或在启动时崩溃。他们需要记忆,而记忆却不存在。所以他们不会被“oomkilled”,而是“被内存不足错误杀死”。结果完全相同,这就是为什么有些人可能认为这是一个笑话。

我自己的推荐

调查系统内存不足的原因。这可以是本质上不可避免的、可以补救的或完全可以避免的。如果本质上不可避免,则将问题提高,并需要安装更多内存。

如果它是由失控的过程中受损,由于错误或故障输入或可以临界之前被识别的状态下,它是可补救。您需要重新设计流程,并为此建立案例。

也可能通过在不同服务器之间拆分服务,或者通过更仔细地调整一个或多个进程,或者通过(再次)重新设计有问题的进程来完全避免该问题。

在某些情况下,更有效的解决方案可能是“投入一些资金”——如果您在使用 256GB RAM 的服务器时遇到问题,并且您知道在可预见的未来最多需要 280 个,升级到 320GB 可能需要花费预付费用低至 3,000 美元,全包,并在周末完成 - 与每天 150,000 美元的停机成本或每个 14,000 美元的四个编程人月相比,这是一笔非常划算的交易,并且很可能即使在日常条件下也能提高性能。

另一种方法是建立一个非常大的交换区,并根据需要激活它。假设我们有 32 GB 可用空间/var/tmp(并且它不是内存支持的):

dd if=/dev/zero of=/var/tmp/oomswap bs=1M count=32768
# or: fallocate -l 32g /var/tmp/oomswap
chmod 600 /var/tmp/oomswap
mkswap /var/tmp/oomswap
swapon /var/tmp/oomswap
Run Code Online (Sandbox Code Playgroud)

这将创建一个 32Gb 文件,用于为各种进程提供一些呼吸。您可能还想检查并可能增加swappiness:

cat /proc/sys/vm/swappiness
Run Code Online (Sandbox Code Playgroud)

Ubuntu 14.04 的默认 swappiness 为 60,这对大多数用户来说是可以的。

sysctl vm.swappiness=70
Run Code Online (Sandbox Code Playgroud)