近日,LinkedIn工程團隊發(fā)表了一篇題為“不要讓Linux控制組不受控制地運行”的文章??刂平M(cgroup)是Linux的一項特性,像Docker和CoreOS這樣的項目使用該特性限制進程的資源使用。該文概括地介紹了cgroup在內(nèi)存管理方面存在的幾個可能導(dǎo)致性能退化的問題以及可能的解決方案。
Cgroup是一種可以確保應(yīng)用程序使用的資源不超出限額的機制,但不保證隔離性。一個操作系統(tǒng)實例中可以運行多個cgroup,其中每一個所使用的內(nèi)存、CPU等都有不同的限額。不過,當(dāng)有額外的內(nèi)存需求(文章作者稱之為“內(nèi)存壓力”)時,操作系統(tǒng)的行為可能會導(dǎo)致在cgroup中運行的應(yīng)用程序出現(xiàn)意料之外的不良結(jié)果。
Cgroup是按層次組織的,操作系統(tǒng)在“根”cgroup中運行,其他cgroup都是根cgroup的子節(jié)點。例如,Docker容器會運行在根cgroup的一個子cgroup中。
該文探討的問題涉及“匿名內(nèi)存”和“頁面緩存”,前者是程序請求的內(nèi)存,后者用來存儲程序數(shù)據(jù)的緩存版本。通常,這些數(shù)據(jù)是保存在類似硬盤這樣的永久性存儲上,供程序執(zhí)行時使用。緩存用于提高那些數(shù)據(jù)的訪問速度。這兩種內(nèi)存類型的分配總是可以被根cgroup或操作系統(tǒng)作廢。
當(dāng)主存可用時,操作系統(tǒng)會將頁面緩存加載到RAM,但當(dāng)應(yīng)用程序請求額外的內(nèi)存時,它會回收內(nèi)存。內(nèi)存回收會導(dǎo)致頁面緩存被刪除,這是跨cgroup的,因為在這種情況下,OS不會遵守cgroup自己的設(shè)置。這可能導(dǎo)致cgroup的頁面緩存被回收,影響了應(yīng)用程序的性能。
當(dāng)通過回收頁面緩存滿足了cgroup的內(nèi)存需求時,另一個問題出現(xiàn)了。用于存儲頁面緩存的內(nèi)存是cgroup內(nèi)存限額的一部分。因此,如果cgroup(在Docker環(huán)境里,則是容器)分得了8GB內(nèi)存,則它需要將這8GB的空間同時用于頁面緩存和匿名內(nèi)存。這一點很容易忽視,因而可能會導(dǎo)致錯誤的性能預(yù)期。
當(dāng)需要的主存超過系統(tǒng)可用的內(nèi)存時,操作系統(tǒng)會執(zhí)行交換操作,將存儲在主存中的程序數(shù)據(jù)寫入輔存,如硬盤。操作系統(tǒng)可以從任意子cgroup把用戶內(nèi)存交換出去,導(dǎo)致那些組中的應(yīng)用程序性能退化。
對于這些問題,文章作者提出了幾項建議,其中包括“預(yù)觸(pre-touching)”內(nèi)存,即確保內(nèi)存在進程啟動時分配,而不是在程序請求時。在不同的平臺上,具體的做法也不相同。另外,也可以更好地估計應(yīng)用程序的內(nèi)存占用,那樣,內(nèi)存分配就可以更準(zhǔn)確。頁面緩存不容易估計,但匿名內(nèi)存很容易。匿名內(nèi)存可以通過類似駐留集大?。≧SS)這樣的系統(tǒng)指標(biāo)來估計。
新版本的cgroup已經(jīng)發(fā)布。該版本包含若干改進,但尚未針對這些情況進行測試。
查看英文原文:Memory Issues with Linux Control Groups Might Affect Containerized Applications