诊断虚拟机频繁 OOM 的问题

原创 2018年01月03日 00:00:00

女主宣言

本文作者霍明明负责 360 HULK 云平台虚拟化和容器化服务的技术布道和解决方案推广等工作。本文主要探究的 OOM Killer 是一个内核功能,当宿主机内存不足时,会使用一系列启发式技术来选择杀死一个进程。本文最先发布于 opsdev, 转载已获取作者授权。

PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!

前言

虚拟机被 OOM 应该是运维 Iaas 平台人员经常会遇到的一个问题。这不,前段时间我们就遇到了某几个业务的虚拟机频繁被 OOM 的情况,我们来看一下是什么原因。


场景描述:

  • Iaas 管理平台: OpenStack

  • 计算节点: CentOS7.2、QEMU、KVM、128GB内存

1

问题定位

现象是业务虚拟机非人为宕机,且运行一段时间就会发生。在查看操作历史和审计记录确认不是人为操作后,通过计算节点系统日志发现,是系统内存不足触发 OOM 导致。


原因是找到了,但是发现比较诡异,为什么呢?


首先,这些虚拟机所在的计算节点并没有开启内存超卖;


其次,我们已经给计算节点 OS 预留了 12GB 的内存(12GB / 128GB = 9.375%)。也就是说撑死了虚拟机使用内存,所有虚拟机内存使用总量也不会超过总内存的 100% - 9.375% = 90.625%,按照这个理论值计算的话,除非 OS 的内存使用量非常大,否则不应该有 OOM 情况的发生。


0?wx_fmt=png

2

问题排查

经验上来说,计算节点 OS 上跑的服务内存不会吃满 12GB, 除非是某些服务出现内存泄露的情况。带着疑问,我们将被 OOM 的虚拟机重新启动,在宿主机上观察内存使用情况。


经过一段时间的运行后虚拟机还是被 OOM 掉了,但是 OS 上的服务并没有内存泄露等情况,且总内存使用量也很正常,大约在 4GB 左右。此时,理论内存最大使用率约为 (128 - 12 + 4) / 128 = 93.75%,此时,系统不应该触发 OOM,这还不算 swap (4GB). 这里,我们排除了计算节点 OS 内存使用问题导致的 OOM.


0?wx_fmt=png

既然,OS 内存使用没问题,那么换个角度看看虚拟机内存使用是否有问题呢?


通过对计算节点上触发 OOM 前后虚拟机进程 (qemu-kvm) 分配的内存进行统计,发现了一个“大”问题。


0?wx_fmt=png

如上图,RES 一列,内存的使用量远大约分配给虚拟机的内存量。套餐是 4核8GB 的虚拟机内存实际使用量基本在 8.3 ~ 8.9GB 之间,套餐是 2核4GB 的虚拟机内存实际使用量也基本在 4.6 ~ 4.8GB 之间。至此,我们知道了多出来的内存被谁使用了。


为什么虚拟机内存使用量会比分配的值要大呢?到虚拟机内部去看,其内存使用虽然很满,但是没有达到超过分配值的情况。


0?wx_fmt=png

带着疑问,Google 了一些资料,其他人也有类似的疑惑。

https://lime-technology.com/forums/topic/48093-kvm-memory-leakingoverhead/


文章的意思是说除了虚拟机内部使用的内存外,qemu-kvm 进程还需要为虚拟的设备提供内存,这部分内存也算在了虚拟机进程 qemu-kvm 头上了。


问题我们定位了,那如何解决这个问题,减少虚拟机被 OOM 情况发生呢?


3

解决方案

  1. 增大 OS 预留内存空间。通过增大 OS 预留内存空间来填充虚拟机膨胀部分内存,使得总体内存使用率不会超过 OOM 的临界值。

  2.  调大 swap 值。目前我们计算节点 swap 值统一为 4GB,对于一个 128GB 内存的节点来说 4GB 内存有点小。我们发现在虚拟机 OOM 时,swap 使用率肯定是 100%,这也很符合 OOM 产生的前提条件。所以,如果你的节点上有 SSD 盘的话,建议将 swap 适当调大。

  3.  修改 OpenStack 逻辑,在虚拟机调度内存计算时,比套餐值大一些,给虚拟机预留出膨胀部分内存。不过这种方式不太通用,不建议使用。


参考文献:


1.https://lime-technology.com/forums/topic/48093-kvm-memory-leakingoverhead/


2.https://unix.stackexchange.com/questions/140322/kvm-killed-by-oomkiller



扫描下方二维码了解更多内容

0?wx_fmt=gif

Kubernetes高级实践:Master高可用方案设计和踩过的那些坑

今天我将为大家介绍如何构建Kubernetes Master High Availability环境。此次分享内容是我在工作中经验总结,如果有不正确的或者需要改进的地方,欢迎各位大神指正。 Kub...
  • houdaiye
  • houdaiye
  • 2016年09月26日 17:52
  • 1893

K8S实战——SIG PIPE问题造成kubernetes集群工作不正常的分析

本文简单介绍在实际使用K8S集群的过程中,因为Go的SIG PIPE bug造成较老版本的Docker,flannel,kubernetes相关进程运行一段时间后就退出造成集群工作不稳定的问题的发现、...
  • xingwangc2014
  • xingwangc2014
  • 2016年06月05日 22:30
  • 2747

CentOS7.1 KVM虚拟化之虚拟机内存、CPU调整(6)

一、调小虚拟机内存 调小虚拟机内存可以动态实现,不用关机 1.查看当前内存大小 [root@kvm01 ~]# virsh dominfo vm1-clone | grep memory M...
  • hnhuangyiyang
  • hnhuangyiyang
  • 2016年03月16日 10:09
  • 7685

KVM总结-KVM性能优化之内存优化

我们说完CPU方面的优化,接着继续内存方面的优化。内存优化有以下四个方向去着手:1)EPT 技术、2)大页和透明大页、3)KSM 技术、4)内存限制...
  • dylloveyou
  • dylloveyou
  • 2017年05月07日 17:28
  • 888

Andorid Volley框架加载图片OOM问题分析

Android volley 引起的context 上下文 内存泄露,导致的OOM问题分析解决
  • hlglinglong
  • hlglinglong
  • 2015年01月06日 14:53
  • 2921

Flume OOM 问题

Spark,Hadoop交流群,群QQ号:521066396,欢迎加入共同学习,一起进步~1、问题使用Flume遇到如下报错:java.lang.OutOfMemoryError: GC overhe...
  • leegh1992
  • leegh1992
  • 2017年03月29日 17:38
  • 468

使用virsh调整运行中的KVM虚拟机内存,CPU(centos6.x)

centos5.x版本不支持动态调整内存,CPU以下在centos6.4上测试通过 1.查看虚拟机信息# virsh dumpxml vm1| head -n 10 vm2 160d7bce...
  • x_i_y_u_e
  • x_i_y_u_e
  • 2016年02月26日 10:26
  • 1963

KVM/QEMU虚拟机申请和释放内存的步骤

1)内存申请 1,QEMU调用malloc()函数为虚拟机分配虚拟内存页,但是此时并没有申请真正的物理内存。 2,虚拟机开始访问该虚拟内存页,并且认为该虚拟内存页是真正的物理内存页,但是由于该内存页没...
  • xuqiaobo
  • xuqiaobo
  • 2017年05月03日 10:56
  • 854

OOM原因和解决方案

1.什么是OOM Android开发中经常会遇到OOM,而且现在已经是Android面试必问的问题了。 OOM(out of memory)即内存泄露。一个程序中,已经不需要使用某个对象,但是因为...
  • wenwins
  • wenwins
  • 2016年05月20日 21:48
  • 1486

JVM内存区域分区及OOM分析

Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来。   概述: 对于从事C、C++程序开发的开发人员来说,在内存管理领域,他们...
  • qq_15465097
  • qq_15465097
  • 2016年04月21日 20:35
  • 475
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:诊断虚拟机频繁 OOM 的问题
举报原因:
原因补充:

(最多只允许输入30个字)