OpenStack计算节点OOM杀进程规则及批量杀VM进程原因咨询
OOM Killer 进程选择规则
OOM Killer触发时会按以下逻辑计算每个进程的优先级,优先杀死得分最高的进程:
- 核心判断指标为内核维护的
oom_score值,满分为1000,得分越高越优先被杀死 oom_score基础值为进程实际占用物理内存(RSS,含进程关联的共享内存、子进程占用内存统计)占系统总内存的百分比,比如进程占用了系统60%的物理内存,基础得分约为600- 基础得分叠加
oom_score_adj调整值得到最终得分:oom_score_adj取值范围为-1000~1000,若设置为-1000,该进程永远不会被OOM Killer杀死(通常用于内核线程、sshd等核心系统进程);若设置为1000,该进程无论占用内存多少都会优先被杀死 - 额外微调规则:root用户运行的进程默认减30分,运行时间越长、优先级越高的进程会适当减分,优先杀死普通用户启动、运行时间短、优先级低的进程
批量杀死多进程的原因
你观察到的杀死128GB实例后仍继续杀9个进程的现象,主要有4个原因:
- 内存释放存在延迟
QEMU进程被杀死后,其占用的物理内存不会瞬时全部释放,需要依次清理页表、回收匿名页、销毁KVM虚拟化资源、清理虚拟网卡缓存等,整个过程耗时从几百毫秒到数秒不等。这段时间内节点上其他进程仍在持续申请内存,前一个进程释放的内存还未被内核统计到,新的内存申请失败就会再次触发OOM Killer,对应你日志中每秒都有不同进程(CPU 5/KVM、tp_librbd、apache2等)触发OOM的记录。 - 内存碎片化导致连续内存申请失败
OpenStack计算节点通常会开启内存超额分配,且长期运行大量大内存虚拟机后会出现严重的物理内存碎片化。此时即使系统总空闲内存足够,当内核、KVM等需要申请连续大块物理内存时(对应你日志中gfp_mask的不同内存申请标记),找不到足够的连续物理页,仍会触发OOM Killer。 - 未被杀进程的
oom_score_adj优先级更高
你提到的最后两个被杀进程内存低于部分未被杀实例,是因为这些未被杀的进程oom_score_adj设置得更低,比如OpenStack的nova-compute、neutron-agent等服务进程通常会被调整oom_score_adj,哪怕实际占用内存更高,最终oom_score也会低于小内存的QEMU进程,因此优先杀死QEMU进程。 - OOM处理队列积压
你日志中所有OOM记录都集中在同一秒内,内核的OOM处理队列存在积压,前几次触发的杀进程操作还未执行完成,后续的内存申请失败又进入队列,导致批量执行了多个杀进程操作,直到所有被杀进程内存完全释放、内存申请能正常满足后才会停止。
内容的提问来源于stack exchange,提问作者Victor Lee
相关产品推荐
相关产品推荐

