1. 程式人生 > >診斷虛擬機器頻繁 OOM 的問題

診斷虛擬機器頻繁 OOM 的問題

本文作者霍明明負責 360 HULK 雲平臺虛擬化和容器化服務的技術佈道和解決方案推廣等工作。本文主要探究的 OOM Killer 是一個核心功能,當宿主機記憶體不足時,會使用一系列啟發式技術來選擇殺死一個程序。

前言

虛擬機器被 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 情況的發生。

 OOM

2.問題排查

經驗上來說,計算節點 OS 上跑的服務記憶體不會吃滿 12GB, 除非是某些服務出現記憶體洩露的情況。帶著疑問,我們將被 OOM 的虛擬機器重新啟動,在宿主機上觀察記憶體使用情況。

經過一段時間的執行後虛擬機器還是被 OOM 掉了,但是 OS 上的服務並沒有記憶體洩露等情況,且總記憶體使用量也很正常,大約在 4GB 左右。此時,理論記憶體最大使用率約為 (128 – 12 + 4) / 128 = 93.75%,此時,系統不應該觸發 OOM,這還不算 swap (4GB). 這裡,我們排除了計算節點 OS 記憶體使用問題導致的 OOM.

記憶體

既然,OS 記憶體使用沒問題,那麼換個角度看看虛擬機器記憶體使用是否有問題呢?

通過對計算節點上觸發 OOM 前後虛擬機器程序 (qemu-kvm) 分配的記憶體進行統計,發現了一個“大”問題。

OOM

如上圖,RES 一列,記憶體的使用量遠大約分配給虛擬機器的記憶體量。套餐是 4核8GB 的虛擬機器記憶體實際使用量基本在 8.3 ~ 8.9GB 之間,套餐是 2核4GB 的虛擬機器記憶體實際使用量也基本在 4.6 ~ 4.8GB 之間。至此,我們知道了多出來的記憶體被誰使用了。

為什麼虛擬機器記憶體使用量會比分配的值要大呢?到虛擬機器內部去看,其記憶體使用雖然很滿,但是沒有達到超過分配值的情況。

虛擬機器

帶著疑問,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 邏輯,在虛擬機器排程記憶體計算時,比套餐值大一些,給虛擬機器預留出膨脹部分記憶體。不過這種方式不太通用,不建議使用。

原文來自微信公眾號:HULK一線技術雜談