首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux下使用earlyoom限制内存使用量,提前释放内存

Linux下使用earlyoom限制内存使用量,提前释放内存

原创
作者头像
保持热爱奔赴山海
发布2025-09-19 23:04:37
发布2025-09-19 23:04:37
100
代码可运行
举报
文章被收录于专栏:DevOpsDevOps
运行总次数:0
代码可运行

需求背景:

近期某个StarRocks集群,内存128G了,但是架不住有些复杂的大的查询啊。最近出现一次某个大查询导致BE内存暴涨,最后把其中一个ECS节点拖死的情况。

为了尽可能减少这种情况的发生,DBA目前想到了2个方案:

1、完善自动化巡检,show processlist 检测到执行时间超过N秒的会话自动kill掉并通过IM通知出来

2、通过第三方的工具(这里用的是earlyoom),在主机内存不足的情况下即时回收内存(kill掉占用内存最高的进程),避免把宿主机拖死。

earlyoom的安装

代码语言:txt
复制
项目地址 https://github.com/rfjakob/earlyoom/


git clone https://github.com/rfjakob/earlyoom.git
cd earlyoom
make
make install
即可

代码语言:txt
复制
> ./earlyoom  -h                               
earlyoom (unknown version)
Usage: ./earlyoom [OPTION]...

  -m PERCENT[,KILL_PERCENT] set available memory minimum to PERCENT of total
                            (default 10 %).
                            earlyoom sends SIGTERM once below PERCENT, then
                            SIGKILL once below KILL_PERCENT (default PERCENT/2).
  -s PERCENT[,KILL_PERCENT] set free swap minimum to PERCENT of total (default
                            10 %).
                            Note: both memory and swap must be below minimum for
                            earlyoom to act.
  -M SIZE[,KILL_SIZE]       set available memory minimum to SIZE KiB
  -S SIZE[,KILL_SIZE]       set free swap minimum to SIZE KiB
  -n                        enable d-bus notifications
  -N /PATH/TO/SCRIPT        call script after oom kill
  -g                        kill all processes within a process group
  -d, --debug               enable debugging messages
  -v                        print version information and exit
  -r INTERVAL               memory report interval in seconds (default 1), set
                            to 0 to disable completely
  -p                        set niceness of earlyoom to -20 and oom_score_adj to
                            -100
  --ignore-root-user        do not kill processes owned by root
  --sort-by-rss             find process with the largest rss (default oom_score)
  --prefer REGEX            prefer to kill processes matching REGEX
  --avoid REGEX             avoid killing processes matching REGEX
  --ignore REGEX            ignore processes matching REGEX
  --dryrun                  dry run (do not kill any processes)
  --syslog                  use syslog instead of std streams
  -h, --help                this help text

案例演示

开一个窗口1,执行

代码语言:txt
复制
./earlyoom -M 4096000 -r 1 --sort-by-rss

另开一个窗口2,执行一个模拟内存泄露的场景

代码语言:txt
复制
tail /dev/zero

然后再开一窗口3,观察 内存使用情况

代码语言:txt
复制
watch -n 1 'free -g'

在窗口2执行了tail /dev/zero后,可以到窗口3看下内存监控,大致如下:

内存使用在逐步上升1
内存使用在逐步上升1
内存使用在逐步上升2
内存使用在逐步上升2
内存使用在逐步上升3
内存使用在逐步上升3
内存使用回到之前的水平
内存使用回到之前的水平

然后回到窗口1上,可以看到类似如下图:

可以看到earlyoom命令检测到内存不足,先尝试执行了sigterm命令,然后又执行了sigkill命令,将tail /dev/zero 给暴力kill掉了,然后释放出内存。

窗口2,也可以看到被kill的日志,类似如下:

注意,earlyoom的kill逻辑:

earlyoom sends SIGTERM once below PERCENT, then SIGKILL once below KILL_PERCENT (default PERCENT/2)

earlyoom的其它介绍

以下内容来自官方github的翻译。

earlyoom 力求简洁可靠。它采用纯 C 语言编写,没有任何依赖项。丰富的测试套件(单元测​​试和集成测试)则使用 Go 语言编写。

它的作用是什么

earlyoom 每秒最多检查 10 次可用内存和空闲交换空间(如果可用内存充足,则检查频率会降低)。默认情况下,如果两者均低于 10%,它将终止最大的进程(highest oom_score)。百分比值可通过命令行参数配置。

为什么要检查“可用”内存而不是“空闲”内存?在健康的 Linux 系统上,“空闲”内存应该接近于零,因为 Linux 使用所有可用的物理内存来缓存磁盘访问。当需要将内存用于其他用途时,这些缓存可以随时被删除。

“可用”内存就是为了解决这个问题。它总结了所有未使用或可立即释放的内存。

请注意,您需要最新版本的 freeLinux 内核 3.14 及以上版本才能查看“可用”列。如果您使用的是较新的内核,但使用的是旧版本的free,则可以从 中获取值grep MemAvailable /proc/meminfo

当可用内存和空闲交换都低于用户空间进程可用内存总量 (=total-shared) 的 10% 时,它会SIGTERM向内核认为使用最多内存的进程发送信号 ( /proc/*/oom_score)。

参见
  • nohang是一个与 earlyoom 类似的项目,用 Python 编写,并具有附加功能和配置选项。
  • facebook 的压力失速信息 (psi)内核补丁 以及随附的oomd用户空间助手。这些补丁已合并到 Linux 4.20 中。

为什么不触发内核 oom killer?

earlyoom 不使用echo f > /proc/sysrq-trigger,因为:

在某些内核版本(在 v4.0.5 上测试)中,手动触发内核 oom killer 根本不起作用。也就是说,它可能只会释放一些图形内存(这些内存会立即再次分配),而不会真正终止任何进程。您可以在这里看到在我的机器(Intel 集成显卡)上的情况。

该问题已在 Linux v5.17 中修复(提交 f530243a)。

就像 Linux 内核一样,earlyoom 通过阅读来找到它的受害者/proc/*/oom_score

earlyoom 占用多少内存?

关于2 MiB( VmRSS),尽管只有220 kiB是私有内存 ( )。其余的是与其他进程共享的RssAnonlibc 库 ( )。所有内存都使用 锁定,以确保 earlyoom 在内存不足的情况下不会变慢。RssFilemlockall()

使用

只需启动刚刚编译的可执行文件:

代码语言:javascript
代码运行次数:0
运行
复制
./earlyoom

它会告诉您有多少内存和交换空间、最小值是多少、有多少可用内存以及有多少空闲交换空间。

代码语言:javascript
代码运行次数:0
运行
复制
./earlyoom
eearlyoom v1.8
mem total: 23890 MiB, user mem total: 21701 MiB, swap total: 8191 MiB
sending SIGTERM when mem avail <= 10.00% and swap free <= 10.00%,
        SIGKILL when mem avail <=  5.00% and swap free <=  5.00%
mem avail: 20012 of 21701 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%)
mem avail: 20031 of 21721 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%)
mem avail: 20033 of 21723 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%)
[...]

如果值低于最小值,进程将被终止,直到再次高于最小值。每个操作都会记录到 stderr。

如果您将 earlyoom 作为 systemd 服务运行,您可以使用以下命令查看最后 10 行

代码语言:javascript
代码运行次数:0
运行
复制
systemctl status earlyoom

prefer参数

命令行标志--prefer指定优先终止的进程;同样,--avoid指定避免终止的进程。详情请参阅https://github.com/rfjakob/earlyoom/blob/master/MANPAGE.md#--prefer-regex 。

配置文件

如果您将 earlyoom 作为系统服务运行(通过 systemd 或 init.d),则可以通过 中提供的文件调整其配置/etc/default/earlyoom。该文件已在注释中包含一些示例,您可以使用这些示例根据支持的命令行选项构建自己的配置集,例如:

代码语言:javascript
代码运行次数:0
运行
复制
EARLYOOM_ARGS="-m 5 -r 60 --avoid '(^|/)(init|Xorg|ssh)$' --prefer '(^|/)(java|chromium)$'"

调整文件后,只需重启服务即可应用更改。例如,对于 systemd:

代码语言:javascript
代码运行次数:0
运行
复制
systemctl restart earlyoom

请注意,此配置文件对 systemd/init.d 之外的 earlyoom 实例没有影响。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 案例演示
  • earlyoom的其它介绍
    • 它的作用是什么
    • 为什么不触发内核 oom killer?
    • earlyoom 占用多少内存?
    • 使用
      • prefer参数
      • 配置文件
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档