首先,大家要記住,在記憶體沒有過量配置(Memory Overcommitment)的情況下,記憶體的排程機制完全不會啟動,就沒有Reclaim記憶體。很明顯嘛,主機總的實體記憶體(Host Physical Memory)大于所有虛機配置記憶體的總額的情況下,每台虛機想要多少記憶體,都能得到滿足,當然不需要排程。
是以,以下探讨的VMware的記憶體機制,都是在記憶體過量配置的情況下發生的。
我的故事發生在一個有智慧的水池(Host)中,水池有不少水(4GB實體記憶體),裡面還有2個水箱(配置了2台VM),水箱有一定的容量(配置記憶體是4GB),原本是空的(沒有開機)。
<a href="http://img1.51cto.com/attachment/201003/27/975660_1269708030z9Lw.jpg" target="_blank"></a>
但是現在水箱1裡面要養魚了,必須放點水進去以便魚可以存活(開機了)。最少需要1GB記憶體。于是水箱1(VM1)就向水池(Host)要水(實體記憶體),水池裡面有足夠的水,就滿足了水箱1的要求。現在水箱1有1GB的活水,而水池裡面隻剩下3GB的水了。
<a href="http://img1.51cto.com/attachment/201003/27/975660_1269708032APgt.jpg" target="_blank"></a>
現在我們又向水箱1裡面多丢了些魚(啟動新的應用),原來1GB的水不夠用了,于是水箱1就繼續向水池要水,水池裡面還有足夠的水,就又滿足了水箱1的要求。現在水箱1裡面有3GB的水,而水池裡面隻剩下1GB的水了。
解釋:要注意的是,此時VM1裡面的應用程式都是活動的(active),是以這些記憶體都屬于活躍狀态,叫做活動記憶體(Active Memory)。
<a href="http://img1.51cto.com/attachment/201003/27/975660_1269708035pZ3r.jpg" target="_blank"></a>
經過了一段時間以後,水箱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)
<a href="http://img1.51cto.com/attachment/201003/27/975660_1269708037Lelx.jpg" target="_blank"></a>
此時,我們開始在水箱2中養魚了(VM2開機),水箱2也開始從水池中抽水。但是水池裡面的水不能枯竭,是以水池有警戒水位,第一條警戒水位是6%,當下降到第一警戒水位以下并仍然在不停下降時,就要開動其他機制從其他水箱反抽水。
<a href="http://img1.51cto.com/attachment/201003/27/975660_1269708039qG2E.png" target="_blank"></a>
那到底向哪個水箱抽水呢?誰的水最富裕就向誰抽。
<a href="http://img1.51cto.com/attachment/201003/27/975660_1269708041cw9r.jpg" target="_blank"></a>
于是,氣球開始膨脹,并将多餘的水擠出水箱。
解釋:Balloon驅動如同普通驅動那樣,不斷向Guest OS索取記憶體,Guest OS盡自己可能滿足氣球驅動,并優先将空閑部分的記憶體配置設定給它,注意,此時可能出現Guest OS自己的實體記憶體不足,并引起Guest OS的paging機制,将一部分記憶體page out到自己的swap中。這個例子中,VM1還有很多空閑記憶體,是以足夠讓主機回收并滿足VM2的需求。
主機将比較氣球膨脹獲得的這部分記憶體的位址,如果原先是配置設定給VM1獨享的,(也就是沒有TPS共享),那麼就可以收回。主機将不停的通過氣球驅動收回記憶體,收回的目标是保持至少6%的記憶體。這個回收記憶體的過程就叫Reclaim。
注意:此時記憶體沒有出現争用情況,是以shares仍然沒有起作用,但是Overcommitment是存在的,是以會有reclaim,會有ballooning。
<a href="http://img1.51cto.com/attachment/201003/27/975660_1269708044Am3g.jpg" target="_blank"></a>
Ballooning回收記憶體是比較慢的,通常需要幾分鐘。
如果主機可用記憶體池的記憶體減少速度大于氣球驅動返還主機的記憶體,那麼可用記憶體會進一步下降,當突破4%的第2警戒線時,進入到hard狀态,主機就會啟用第2種reclaim機制——swapping,将VM1的一部分實體記憶體交換到swap檔案中,以加快回收記憶體的速度。目的是将可用記憶體保持在4%的警戒線以上。
如果可用記憶體繼續下降到2%以下,進入到low狀态的時候,ESX不僅會繼續加速Swapping,還會阻止其上所有VM的記憶體請求。
現在,情況又發生了變化,水箱2中的魚越來越多了,它不停地向水池要水,而水池也通過氣球驅動,不停地将水箱1中的空閑記憶體擠出來,直到水箱1和2的總需求量大于了水池能供給的水量。水池再也不能提供更多的水了,隻能部分滿足2個水箱的要求了。不夠的部分怎麼辦?用一些髒水(swap)來滿足。髒水雖然髒(swap記憶體速度很慢),魚在髒水裡面生存的很困難,但畢竟還是有水的,不至于因為沒有足夠的水而導緻魚死掉。
<a href="http://img1.51cto.com/attachment/201003/27/975660_1269708046CNEZ.jpg" target="_blank"></a>
此時,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
(2) VMware Inc. Understanding Memory Resource Management in VMware ESX Server
(4) Idel memory tax
<a href="http://www.boche.net/blog/index.php/2009/01/29/idle-memory-tax/" target="_blank">http://www.boche.net/blog/index.php/2009/01/29/idle-memory-tax/</a>
本文轉自 qq8658868 51CTO部落格,原文連結:http://blog.51cto.com/hujizhou/1688812,如需轉載請自行聯系原作者