OOM 杀进程 or 应用卡顿?该如何抉择

简介: 阿里云操作系统控制台推出了 FastOOM 功能,支持节点以及 Pod 级别的用户态 OOM 配置,通过提前介入杀进程的方式避 Near-OOM 导致的抖动夯机。

【阅读原文】戳:OOM 杀进程 or 应用卡顿?该如何抉择

 

背景

 

近期,大量用户反馈系统在运行过程中出现 CPU 利用率与系统负载(load)突发性飙升,甚至引发系统短时卡顿(持续数秒至数十秒)的问题;对于业务来说,轻则导致几百毫秒的抖动,重则连机器都无法ssh上去。经分析发现,此类异常现象普遍存在一个显著特征:均发生在系统内存占用率接近阈值(90%-95%)时。用户就发出了灵魂拷问:

 

“水位这么高了,为什么内核不触发 OOM 杀掉一些进程来释放内存?"

 

“我宁愿内核 OOM 把我业务进程杀了,我也不希望应用卡顿和系统夯机影响我其他业务!”

 

其实这个现象的核心原因就是:内核想确保应用实在没内存用了才 OOM

 

思想总体是正确的!但是一条思想要满足所有场景也是非常难的!

 

为什么还不 OOM ?!

 

内存水位这么高,为什么还不 OOM!其实主要是由于系统进入了 Near-OOM 状态。我们先回顾一下 Linux 的内存回收机制,如下图所示:

 

图/Linux内存水线

 

Linux 划分了 high、low、min 三个内存水线。当系统剩余内存低于 low 水线后,内核会唤醒 kswapd 进程会被唤醒开始进行异步的内存回收,此时对系统没什么影响;系统剩余内存低于 min 水线后,内核会阻塞要分配的内存进程尝试尽可能地回收所有可回收的内存(主要是文件缓存以及一些内核结构体缓存),回收的过程中可能涉及到将文件缓存写入磁盘或遍历一些内核结构体,从而导致系统负载飙高、应用被阻塞。如果能成功回收内存并满足申请需求则不触发 OOM;

 

更糟糕的是,系统可能进入一种 Near-OOM 的活锁状态,即内核一边在尝试回收文件缓存;但是应用运行过程中从磁盘加载代码段等行为也在不断产生文件缓存,那么就会使整个系统负载持续飙高,甚至发生夯机。

 

所以,内核 OOM 的策略在业务延时敏感的场景,还是太保守了!

 

那么如果我们希望宁愿 OOM 把我业务进程杀了,我也不希望应用卡顿和系统夯机影响我其他业务?还有什么办法呢?

 

 

 

新OOM方案

 

 

 

为了应对 Near-OOM 现象,核心就是“快” OOM,在内核还在犹豫要不要 OOM 的时候,我们就替他做出决定!目前业界已有的方案主要是通过用户态提前杀死相关进程来提前释放内存,比如应用较为广泛的是Facebook(Meta)推出的 oomd。oomd 目前已经集成于systemd中成为systemd-oomd,且从Ubuntu 22.04 开始集成于 Ubuntu 中。但是 oomd 方案存在以下问题:

 

与 cgroupV2 以及 Linux 内核的 PSI(Pressure Stall Information)特性深度绑定。但 cgroupV1 目前仍然是云计算中主流 cgroup 版本,且由于PSI功能有一定的性能开销,在大部分云计算场景中都是默认关闭的。

 

只支持以 cgroup 为粒度杀进程,配置 cgroup 级别的杀进程策略。

 

所以oomd在适用性和灵活性上仍有欠缺。

 

为了解决上述问题,阿里云操作系统控制台推出了 FastOOM 功能,支持节点以及 Pod 级别的用户态 OOM 配置,通过提前介入杀进程的方式避 Near-OOM导致的抖动夯机。

 

FastOOM 同样采取用户态提前杀进程的形式来避免系统进入 Near-OOM 状态,主要分为采集预测模块和 kill 模块:采集预测模块会从阿里云自研操作系统中读取内存压力相关的指标,通过统计学方法对 OOM 发生的概率进行实时预测并判定当前节点或 pod 是否达到相应的内存压力或即将进入 Near-OOM 状态。kill 模块会根据用户配置的杀进程策略,选取对应的进程杀死。

 

最终所有由 FastOOM 执行的 kill 操作事件都会上报到控制台中心端进行展示,让用户方便了解底层的实际操作(不用担心 FastOOM 偷偷杀死了其他进程)。

 

 

 

 

使用 FastOOM 避免

Near-OOM 系统夯机抖动

 

 

 

案例一:配置节点级别策略解决系统

Near-OOM 抖动夯机问题

 

客户遇到的问题

 

某汽车行业发现某实例上业务长时间无响应、登录实例也十分卡顿。通过监控发现客户实例使用的内存在某个时间点开始徒增,接近系统的总内存(即 available 非常低),但没有超过系统总内存。

 

 

 

通过 top 命令可以看到系统的 CPU sys 利用率和 iowait 利用率和系统负载都持续飙高,kswapd0 线程占用非常高的 CPU 进行内存回收。

 

 

通过操作系统控制台的系统概览可以看到,在发生OOM 夯(即处于 Near-OOM 状态)的同时,也发生了用户态收包延时,业务发生了抖动。

 

 

解决方案

 

通过配置开启节点级别的 FastOOM 功能,由于业务是实验较为敏感的业务,内存压力选择中,且设置业务程序(以 python 启动,进程名包含 python 子串)为避免被 OOM 进程且设置无关的日志程序优先杀死。

 

 

开启后,当节点内存水位处于 Near-OOM 状态时,用户态提前介入,根据配置杀死了如下进程,从而释放了部分内存避免系统进入了夯机状态。通过操作系统控制台的系统概览可以看到 FastOOM 介入的相关记录

 

如下图所示,由于 kube-rbac-proxy 和 node_exporter 等进程 oom_score_adj 被设置为接近 999,FastOOM 会匹配内核策略优先杀死这些进程,但是由于杀死这些进程后释放内存较小,仍处于 Near-OOM;因此 FastOOM 杀死了配置优先杀死的 logcollect 进程。

 

 

由于用户态及时介入杀死进程释放出内存,使系统避免进入了 Near-OOM 的抖动状态。

 

案例二:配置 Pod 级别策略解决

Pod 应用抖动夯机问题

 

客户遇到的问题

 

在 Kubernetes 环境中,我们是可以为 Pod 中的容器配置对应的内存限制的。和节点 OOM 同理,如果 Pod 中的内存使用接近限制时。内核也会尝试回收 Pod 中所有可回收内存,才触发 OOM,这时候也会导致 Pod 内业务进程的延时阻塞。

 

某大数据客户会部署一些延时敏感的业务 pod(即 pod 中运行了多个业务进程)。业务时不时会存在响应长尾延时,但是网络相关指标一切正常。

 

后面我们接手问题后,通过 Alibaba Cloud Linux OS自研指标(该指标反映容器由于内存回收阻塞的时长)发现,存在非常高的内存回收延时,且时间节点和抖动时间匹配:

 

 

推荐客户配置 Pod 级别的 FastOOM 后,通过提前杀死 Pod 中的相关内存占用进程,避免了内存回收延时的发生,抖动也不再出现。

 

解决方案

 

操作系统控制台提供较为灵活的 Pod 级别的 OOM 杀进程策略配置,可以灵活配置 Pod 中容器内发生 OOM 时,避免和优先杀死的进程。

 

假设在集群中通过名为 test-alinux 的 daemonset 在每一个节点部署了对应的 pod。

 

 

在操作系统控制台中设置 Pod 级别 FastOOM 策略:

为了匹配对应的 pod,pod 名称填写 test-alinux(正则表达式会匹配不同节点上的 test-alinux-xxx pod),命名空间为 default。

 

由于只是希望控制 OOM 时的杀进程策略,将内存压力级别设置为高,则触发用户态 OOM 的时机会近似于内核 OOM 的时机。

 

对于杀进程策略:配置优先杀死特定进程和避免杀死业务进程和 pod 中的 1 号进程,从而避免 pod 重启或影响业务,设置完成后下发至特定节点。

 

 

将配置下发到对应节点后,当 Pod 中容器内存使用超过容器 limit 后,发生 OOM;可以通过操作系统控制台系统概览看到 FastOOM 事件记录,可以看到FastOOM 根据策略杀死了对应的进程,也避免了特定进程被杀死。

 

 

总结

 

人无完人,内核的 OOM 其实也不是万能的。为了能尽可能的回收内存,内核在发生 OOM 前会阻塞申请内存的进程,并尝试回收内存,这对于延时敏感的业务的影响是非常大的;如果内存持续保持在接近 OOM的水位,还会进入 Near-OOM 的活锁状态导致整机夯机。阿里云操作系统控制台的 FastOOM 功能,通过相关指标,支持节点/容器/pod 级策略,可精准杀指定进程,轻松弥补了内核 OOM 带来的延时卡顿问题。

/END/


我们是阿里巴巴云计算和大数据技术幕后的核心技术输出者。

欢迎关注 “阿里云基础设施”同名微信微博知乎

获取关于我们的更多信息~

相关文章
|
3月前
|
监控 Java C语言
Java内存排查太难?阿里云操作系统控制台上线「内存诊断」新利器
帮助用户结合应用和操作系统的角度,快速揪出 Java 应用内存占用的元凶。
|
5月前
|
人工智能 运维 安全
|
6月前
|
存储 人工智能 弹性计算
WordPress AI助手操作
本文将介绍如何使用阿里云百炼平台创建知识库与AI助手应用,包括数据上传、模型配置、应用部署及资源清理等步骤,并详细说明了如何在Web页面集成AI助手悬浮框,实现智能对话功能。
461 5
|
监控 调度 开发工具
IO神器blktrace使用介绍
## 前言 1. blktrace的作者正是block io的maintainer,开发此工具,可以更好的追踪IO的过程。 2. blktrace 结合btt可以统计一个IO是在调度队列停留的时间长,还是在硬件上消耗的时间长,利用这个工具可以协助分析和优化问题。 ## blktrace的原理 一个I/O请求的处理过程,可以梳理为这样一张简单的图: ![](http://image
21010 0
|
Linux 数据安全/隐私保护
【Cloud】修改CentOS官方 云镜像的ROOT密码
在私有云平台使用中,去CentOS官网下载qcow2格式的镜像,发现运行之后不知道密码无法进入系统。现在提供两种修改or注入密码的方法
7237 0
【Cloud】修改CentOS官方 云镜像的ROOT密码
|
6月前
|
运维 Dubbo Cloud Native
Dubbo 云原生重构出击:更快部署、更强控制台、更智能运维
Apache Dubbo 最新升级支持云原生,提供一键部署微服务集群与全新可视化控制台,提升全生命周期管理体验,助力企业高效构建云原生应用。
477 25
|
6月前
|
Java 数据库 C++
Java异常处理机制:try-catch、throws与自定义异常
本文深入解析Java异常处理机制,涵盖异常分类、try-catch-finally使用、throw与throws区别、自定义异常及最佳实践,助你写出更健壮、清晰的代码,提升Java编程能力。
|
3月前
|
Kubernetes Cloud Native 调度
寻因生物 × 阿里云 ACS:Argo Workflows 驱动的基因分析新范式
国家级专精特新“小巨人”企业寻因生物[1],基于阿里云容器服务全托管工作流引擎 Argo Workflows[2] (以下简称:全托管 Argo Workflows)与容器计算服务 ACS[3](以下简称:ACS)构建的了新一代基因生信分析平台。该平台实现生信流程编排效率提升 70%、计算成本降低超 50%、运维复杂度下降 70%,为单细胞、空间转录组、表观测序技术等前沿研究提供了高效、弹性、标准化的算力基础设施。
268 1
|
6月前
|
消息中间件 人工智能 Apache
Apache RocketMQ EventBridge:为什么 GenAI 需要 EDA?
本文探讨了事件驱动架构(EDA)在AI时代的重要价值。首先,通过RAG技术缓解AI幻觉问题,提高大模型回答的准确性;其次,作为推理触发器,实现自动化任务处理和系统联动;最后,构建Agent通信基础设施,推动AI系统间的高效协作。EDA以其事件为中心、实时响应的特点,为AI系统提供感知与行动能力,是构建智能系统的关键支撑。
262 10
|
6月前
|
存储 人工智能 安全
【阿里云基础设施 AI Tech Day】 AI Infra 建设方案及最佳实践沙龙圆
聚焦 AI Infra 建设方案及最佳实践,「智驱未来,云网随行:AI Infra 建设方案及最佳实践」沙龙阿里云基础设施 AI Tech Day 北京站于 8 月 8 日下午在北京全球创新社区顺利举办,活动现场吸引了来自月之暗面、字节、小米、爱奇艺、360、雪球、猿辅导、奥迪等 16 家相关 AI 领域领先企业或有AI建设诉求企业的 32 名业务/技术骨干参与。本次技术沙龙旨在聚焦企业建设高效、高可用的 AI Infra,深入解析 AI 驱动的原子能力与场景化架构设计,分享从基础网络建设、算力池化、存储调度,以及 VPC RDMA 性能优化、Agent 智能体出海等场景的全链路方案,助力企业
525 1