在寫《VMware內存機制初探》之后,原本是計划寫一篇《VMware內存機制再探》的,講一講VMware內存機制中的另外幾個重要內容,比如透明內存共享(TPS, Transparent Page Sharing), Relaim Memory, Ballooning, swapping等等。但有網友反映說前面的文章還是不好懂。於是想,如果如同官方文檔那樣條條框框地列出來,那還不如大家都去看原版手冊呢,所以有了這么一篇東西。
首先,大家要記住,在內存沒有過量配置(Memory Overcommitment)的情況下,內存的調度機制完全不會啟動,就沒有Reclaim內存。很明顯嘛,主機總的物理內存(Host Physical Memory)大於所有虛機配置內存的總額的情況下,每台虛機想要多少內存,都能得到滿足,當然不需要調度。
所以,以下探討的VMware的內存機制,都是在內存過量配置的情況下發生的。
我的故事發生在一個有智慧的水池(Host)中,水池有不少水(4GB物理內存),里面還有2個水箱(配置了2台VM),水箱有一定的容量(配置內存是4GB),原本是空的(沒有開機)。
但是現在水箱1里面要養魚了,必須放點水進去以便魚可以存活(開機了)。最少需要1GB內存。於是水箱1(VM1)就向水池(Host)要水(物理內存),水池里面有足夠的水,就滿足了水箱1的要求。現在水箱1有1GB的活水,而水池里面只剩下3GB的水了。
現在我們又向水箱1里面多丟了些魚(啟動新的應用),原來1GB的水不夠用了,於是水箱1就繼續向水池要水,水池里面還有足夠的水,就又滿足了水箱1的要求。現在水箱1里面有3GB的水,而水池里面只剩下1GB的水了。
解釋:要注意的是,此時VM1里面的應用程序都是活動的(active),所以這些內存都屬於活躍狀態,叫做活動內存(Active Memory)。
解釋:要注意的是,此時VM1里面的應用程序都是活動的(active),所以這些內存都屬於活躍狀態,叫做活動內存(Active Memory)。
經過了一段時間以后,水箱1里面的魚被捕走了,現在水箱1不需要那么多水也足夠養活剩下的魚了。但是水池並不知道水箱1的狀況。於是水箱1還是有那么多水。
解釋: VM1的某些應用結束后,釋放了部分內存,但是這些內存釋放動作是在VM的Guest OS層面釋放的,因此Host並不知道有內存被釋放了,這些內存沒有歸還Host,仍然由VM1霸占着。VM1中就有一部分內存屬於idle,另外一些正在使用的內存就是active memory。當然,就VM1自己的GOS看起來,有3GB空閑內存(idle memory),1GB的活動內存;而此時就Host看來,只看見有3GB內存是分配給了VM1的。Host通過VMware Tools中的驅動,每隔一定的時間(ESX4中默認是60秒,ESX3中默認是30秒)去掃描一下VM1的內存使用狀態,以便了解它到底有多少活動內存(active memory)
此時,我們開始在水箱2中養魚了(VM2開機),水箱2也開始從水池中抽水。但是水池里面的水不能枯竭,因此水池有警戒水位,第一條警戒水位是6%,當下降到第一警戒水位以下並仍然在不停下降時,就要開動其他機制從其他水箱反抽水。
解釋: VM2開機時也需要1GB內存,在啟動時,它也不斷向Host請求內存。Host則將自己的內存源源不斷地分配給VM2,直到下降到第一條警戒位6%。Host內存有4種狀態,分別是High, Soft, Hard和Low,它們間的分界線分別是6%, 4%, 2%和1%。可用內存高於6%時,不會啟動Balloon或Swap機制。當低於6%並往4%逼近的時候(soft狀態),Balloon機制就啟動了。(關於內存的4種狀態的更多解釋,請參閱官方文檔《Understanding Memory Resource Management in VMware ESX Server》。如何查看這4種狀態?可以用esxtop或者resxtop)
那到底向哪個水箱抽水呢?誰的水最富裕就向誰抽。
解釋: 如何判斷呢?剛才我們說過,Host每隔一定時間就會掃描Guest OS的內存使用狀況,此時,Host會計算每個VM的份額內存比ρ,ρ和VM的空閑內存還有空閑內存稅(IMT, Idel Memory Tax)密切相關,對ρ最小的那台虛機啟動氣球驅動(balloon driver),氣球開始膨脹(inflating)。關於ρ和IMT的算法,請參見本人博文《 空閑內存稅的算法 》。
於是,氣球開始膨脹,並將多余的水擠出水箱。
解釋:Balloon驅動如同普通驅動那樣,不斷向Guest OS索取內存,Guest OS盡自己可能滿足氣球驅動,並優先將空閑部分的內存分配給它,注意,此時可能出現Guest OS自己的物理內存不足,並引起Guest OS的paging機制,將一部分內存page out到自己的swap中。這個例子中,VM1還有很多空閑內存,因此足夠讓主機回收並滿足VM2的需求。
主機將比較氣球膨脹獲得的這部分內存的地址,如果原先是分配給VM1獨享的,(也就是沒有TPS共享),那么就可以收回。主機將不停的通過氣球驅動收回內存,收回的目標是保持至少6%的內存。這個回收內存的過程就叫Reclaim。
注意:此時內存沒有出現爭用情況,因此shares仍然沒有起作用,但是Overcommitment是存在的,所以會有reclaim,會有ballooning。
Ballooning回收內存是比較慢的,通常需要幾分鍾。
如果主機可用內存池的內存減少速度大於氣球驅動返還主機的內存,那么可用內存會進一步下降,當突破4%的第2警戒線時,進入到hard狀態,主機就會啟用第2種reclaim機制——swapping,將VM1的一部分物理內存交換到swap文件中,以加快回收內存的速度。目的是將可用內存保持在4%的警戒線以上。
如果可用內存繼續下降到2%以下,進入到low狀態的時候,ESX不僅會繼續加速Swapping,還會阻止其上所有VM的內存請求。
現在,情況又發生了變化,水箱2中的魚越來越多了,它不停地向水池要水,而水池也通過氣球驅動,不停地將水箱1中的空閑內存擠出來,直到水箱1和2的總需求量大於了水池能供給的水量。水池再也不能提供更多的水了,只能部分滿足2個水箱的要求了。不夠的部分怎么辦?用一些臟水(swap)來滿足。臟水雖然臟(swap內存速度很慢),魚在臟水里面生存的很困難,但畢竟還是有水的,不至於因為沒有足夠的水而導致魚死掉。
此時,VM1和VM2的active memory由2部分組成,1部分是獲得的主機物理內存,另一部分是swap。請注意,Guest OS是不知道自己的一部分物理內存是硬盤上的swap文件的。
當機器內存不足競爭開始的時候,shares開始起作用。但是,請注意,如果IMT是0,對空閑內存不征稅,由於4GB的VM1和4GB的VM2的份額都是40960,因此它們最終會拿到相同的物理內存2GB。但是如果IMT是默認值,那么空閑內存的代價更大,那么這2台VM會根據active內存數量的不同,獲得不同數量的物理內存。
【本文的知識要點回顧】
(1) 在內存沒有過量配置(Memory Overcommitment)的情況下,不需要Reclaim內存
(2) 什么時候開始Reclaim內存?當突破6%的警戒線,內存狀態從High變成了Soft的時候
(3) Reclaim優先用Ballooning,只有Ballooning不夠用的時候,才會用Swapping
(4) 什么時候開始swapping? 當主機可用內存跌破4%警戒線,內存狀態變成Hard的時候
(5) Host無法知道VM內的哪些內存塊已經處於空閑(idle)狀態。必須用Ballooning才能收回空閑內存。
(6) 盡量避免資源爭用,否則造成的Chasing-the-tail效應,會導致更嚴重的性能負面影響。
【參考文檔】
(1) Carl, A. Waldspurger, 2002, Memory Resource Management in VMware ESX Server
http://waldspurger.org/carl/papers/esx-mem-osdi02.pdf
(2) VMware Inc. Understanding Memory Resource Management in VMware ESX Server
http://www.vmware.com/files/pdf/perf-vsphere-memory_management.pdf
(3) VMware Inc. Understanding Host & Guest Memory Usage (2007)
http://mylearn.vmware.com/courseware/12400/PS_TA21_288707_166-1_FIN_v3.pdf
(4) Idel memory tax
http://www.boche.net/blog/index.php/2009/01/29/idle-memory-tax/
本文出自 “三角陽台的技術筆記本” 博客,請務必保留此出處http://delxu.blog.51cto.com/975660/288682