Page Cache限制功能
Alibaba Cloud Linux 3(內(nèi)核版本5.10.134-14
開(kāi)始)增加了Page Cache(文件緩存)限制功能,用于解決因Page Cache無(wú)限制使用帶來(lái)的系統(tǒng)穩(wěn)定性問(wèn)題,例如業(yè)務(wù)抖動(dòng)、預(yù)期外的內(nèi)存溢出OOM(Out Of Memory)等。
背景信息
在內(nèi)核系統(tǒng)中,系統(tǒng)分配內(nèi)存并在相應(yīng)內(nèi)存子系統(tǒng)(memcg)中的統(tǒng)計(jì)達(dá)到memcg設(shè)定的內(nèi)存上限時(shí),會(huì)觸發(fā)memcg級(jí)別的直接內(nèi)存回收,這可能導(dǎo)致當(dāng)前進(jìn)程的性能抖動(dòng)。盡管具有Memcg后臺(tái)異步回收功能,但對(duì)于突發(fā)性的內(nèi)存申請(qǐng)來(lái)說(shuō),其效果有限。有些任務(wù)例如Spark計(jì)算框架,Page Cache會(huì)經(jīng)常占用大量?jī)?nèi)存,并且大部分是臟頁(yè)。臟頁(yè)的回收速度較慢,導(dǎo)致了預(yù)期外的OOM情況的發(fā)生。因此,限制Page Cache的使用量對(duì)于保持業(yè)務(wù)的穩(wěn)定性和減少預(yù)期外的OOM問(wèn)題非常重要。
Alibaba Cloud Linux 3增加了Page Cache限制功能,支持以memcg為粒度(包括根組即整機(jī))對(duì)Page Cache的使用進(jìn)行限制。該功能可以通過(guò)設(shè)置Page Cache的上限,對(duì)超過(guò)限制的Page Cache進(jìn)行異步回收或者同步回收。這可以幫助控制Page Cache的使用量,防止其占用過(guò)多的內(nèi)存資源,從而提高系統(tǒng)的穩(wěn)定性和可靠性。
接口說(shuō)明
接口 | 說(shuō)明 |
/sys/kernel/mm/pagecache_limit/enabled | 該接口是全局開(kāi)關(guān),用于設(shè)置當(dāng)前內(nèi)核系統(tǒng)是否啟用Page Cache限制功能。取值范圍:0~1,默認(rèn)值為0。
|
/sys/fs/cgroup/memory/<memcg目錄名稱>/memory.pagecache_limit.enable | 該接口是memcg開(kāi)關(guān),用于設(shè)置各memcg是否啟用Page Cache限制功能。取值范圍:0~1,默認(rèn)值為0。
|
/sys/fs/cgroup/memory/<memcg目錄名稱>/memory.pagecache_limit.size | 該接口限制當(dāng)前memcg的Page Cache使用量(單位:字節(jié))。取值范圍:0~當(dāng)前memcg的
|
/sys/fs/cgroup/memory/<memcg目錄名稱>/memory.pagecache_limit.sync | 該接口控制當(dāng)前memcg的Page Cache使用量超出限制后,采用異步回收還是同步回收。取值范圍:0~1,默認(rèn)值為0。
|
工作原理
開(kāi)啟Page Cache限制功能后,memcg粒度的工作原理如下。
當(dāng)memcg進(jìn)程分配Page Cache時(shí),判斷當(dāng)前memcg的Page Cache是否超過(guò)限制,并從當(dāng)前memcg開(kāi)始往上遍歷,逐級(jí)檢查父memcg的
memory.pagecache_limit
值,如果該值為0,表示父memcg禁用了Page Cache限制,則當(dāng)前memcg以及其子memcg不會(huì)受到Page Cache的限制。當(dāng)memcg的Page Cache使用超過(guò)限制時(shí),根據(jù)
memory.pagecache_limit.sync
判斷當(dāng)前回收采用同步回收還是異步回收。開(kāi)始回收Page Cache。
同步回收:默認(rèn)僅支持未映射文件頁(yè)回收,當(dāng)掃描次數(shù)超過(guò)4次時(shí),允許對(duì)映射文件頁(yè)進(jìn)行回收。
異步回收:默認(rèn)支持未映射文件頁(yè)和映射文件頁(yè)回收,當(dāng)掃描次數(shù)超過(guò)2次時(shí),允許對(duì)臟頁(yè)進(jìn)行回收。
說(shuō)明在內(nèi)存管理中,存在以下不同類型的頁(yè)。
未映射文件頁(yè):這些頁(yè)是指未被映射到任何文件的內(nèi)存頁(yè)。通常用于臨時(shí)數(shù)據(jù)和進(jìn)程私有的內(nèi)存區(qū)域,不會(huì)持久化到磁盤(pán)上。
映射文件頁(yè):這些頁(yè)是指被映射到文件的內(nèi)存頁(yè)。映射文件頁(yè)允許進(jìn)程通過(guò)訪問(wèn)內(nèi)存的方式來(lái)讀取和寫(xiě)入文件數(shù)據(jù),從而實(shí)現(xiàn)了文件的隨機(jī)訪問(wèn)。
臟頁(yè):臟頁(yè)是指映射文件頁(yè)中已經(jīng)被修改過(guò)的頁(yè)。當(dāng)進(jìn)程對(duì)映射文件頁(yè)進(jìn)行寫(xiě)入時(shí),相應(yīng)的頁(yè)會(huì)被標(biāo)記為臟頁(yè)。這表示文件在內(nèi)存中的副本已經(jīng)與磁盤(pán)上的文件內(nèi)容不一致。臟頁(yè)通常會(huì)定期地被寫(xiě)回磁盤(pán),以確保數(shù)據(jù)的持久性。
接口配置示例
本示例的場(chǎng)景是構(gòu)造20 MiB大小的Page Cache,并限制Page Cache的使用量為10 MiB。開(kāi)啟Page Cache限制功能后,測(cè)試是否符合預(yù)期。
遠(yuǎn)程登錄ECS實(shí)例。
具體操作,請(qǐng)參見(jiàn)通過(guò)密碼或密鑰認(rèn)證登錄Linux實(shí)例。
運(yùn)行以下命令,打開(kāi)Page Cache限制功能的全局開(kāi)關(guān)。
sudo sh -c 'echo 1 > /sys/kernel/mm/pagecache_limit/enabled'
啟用Page Cache限制功能并限制Page Cache的使用量。
運(yùn)行以下命令,創(chuàng)建一個(gè)memcg目錄,例如
/sys/fs/cgroup/memory/test/
。sudo mkdir -p /sys/fs/cgroup/memory/test/
運(yùn)行以下命令,設(shè)置memcg的Page Cache使用量。
本示例限制memcg的Page Cache使用量為10485760字節(jié)(約10 MiB),命令為:
sudo sh -c 'echo 10485760 > /sys/fs/cgroup/memory/test/memory.pagecache_limit.size'
運(yùn)行以下命令,設(shè)置一種回收方式。
異步回收
sudo sh -c 'echo 0 > /sys/fs/cgroup/memory/test/memory.pagecache_limit.sync'
同步回收
sudo sh -c 'echo 1 > /sys/fs/cgroup/memory/test/memory.pagecache_limit.sync'
運(yùn)行以下命令,啟用memcg的Page Cache限制功能。
sudo sh -c 'echo 1 > /sys/fs/cgroup/memory/test/memory.pagecache_limit.enable'
構(gòu)造Page Cache。
(條件必選)運(yùn)行以下命令,安裝
libcgroup
軟件包。構(gòu)造Page Cache需要使用
cgexec
命令。cgexec
命令通常與libcgroup軟件包一起提供,并且需要在系統(tǒng)上進(jìn)行安裝。如果您的系統(tǒng)中沒(méi)有cgexec
,請(qǐng)先安裝libcgroup軟件包。sudo yum install libcgroup-tools
運(yùn)行以下命令,構(gòu)造Page Cache。
本示例使用
dd
命令以每次寫(xiě)入1 MiB的塊大小,連續(xù)寫(xiě)入20次,來(lái)構(gòu)造一個(gè)總計(jì)20 MiB的Page Cache。命令為:sudo dd if=/dev/zero of=./testfile bs=1M count=20 oflag=direct sudo cgexec -g "memory:test" cat ./testfile > /dev/null
查看是否符合預(yù)期。
運(yùn)行以下命令,查看當(dāng)前Page Cache的使用量。
grep cache /sys/fs/cgroup/memory/test/memory.stat
返回結(jié)果如下:
在返回結(jié)果中,
cache
表示當(dāng)前Page Cache的使用量為10543104字節(jié)(約10 MiB),說(shuō)明已成功限制。運(yùn)行以下命令,查看Page Cache限制功能的回收結(jié)果。
cat /sys/fs/cgroup/memory/test/memory.exstat
返回結(jié)果如下:
在返回結(jié)果中,
pagecache_limit_reclaimed_kb
表示回收的頁(yè)數(shù)(單位:千字節(jié)),這里是10108千字節(jié)(約10 MiB),說(shuō)明回收了10 MiB。通過(guò)測(cè)試結(jié)果可以看出,構(gòu)造了20 MiB的Page Cache,限制Page Cache的使用量為10 MiB。當(dāng)Page Cache的使用量超出限制時(shí),回收了10 MiB的Page Cache,符合預(yù)期。
說(shuō)明如果測(cè)試發(fā)現(xiàn)
pagecache_limit_reclaimed_kb
值較大不符合預(yù)期,可能是IO預(yù)讀引入的問(wèn)題導(dǎo)致額外的回收。此時(shí)建議您運(yùn)行echo 128 | sudo tee /sys/block/vda/queue/read_ahead_kb
命令(vda
是云盤(pán)的設(shè)備名稱,請(qǐng)您根據(jù)實(shí)際環(huán)境替換),設(shè)置IO預(yù)讀量,然后重新測(cè)試。