Linux

在文件記憶體之前創建或強制 tmpfs 交換

  • June 22, 2020

考慮以下場景。你有一個安裝 Linux 的慢速只讀媒體(例如,防寫的拇指驅動器、CD/DVD 等)(不是 Live CD 本身,而是一個普通版本),並在沒有字面意思的電腦上使用它其他形式的儲存。它很慢,因為它是 USB 2。根文件系統作為 overlayfs 安裝,因此它對於日誌和您所做的許多其他臨時工作是“可寫的”,但所有寫入都進入 RAM (tmpfs upperdir)。Live 發行版情況的典型場景。

由於沒有其他形式的儲存,swap 掛載在 zram 上。因此,當 Linux 決定交換時,它會壓縮這些頁面並將它們仍然儲存在 RAM 中,但至少它們是被壓縮的。這實際上是不錯的,因為大多數應用程序的 RAM 很容易壓縮(RAM 通常在數據中非常冗餘,因為它意味著“快速”)。這適用於應用程序記憶體,但不適用於 tmpfs。

事情是這樣的:zram速度很快,令人難以置信。另一方面,拇指驅動器很慢。假設它是 20 MiB/s,相比之下真的很慢。您可以在這裡看到問題以及核心為什麼不能做正確的事情。

請注意,這個問題不是重複如何使 TMPFS 中的文件更有可能交換。問題幾乎相同,但我對那個問題的答案不滿意,對不起。不管設計它的人有多聰明,核心本身肯定不會“正確的事情” 。當人們不了解情況並認為他們知道得更好時,我不喜歡它。他們迎合一般情況。這就是Linux如此可調整的原因,因為無論它多麼聰明,它都無法預測它將用於什麼。

例如,我可以(並且確實)將vm.swappiness (/proc/sys/vm/swappiness) 設置為 100,這告訴它積極交換應用程序記憶體並保留文件記憶體。這個選項很好,但不幸的是,它不是一切。

我希望它在處理交換時優先*保留文件記憶體而不是任何其他 RAM 使用。這是因為刪除文件記憶體會導致它必須從慢速 20 MiB/s 驅動器中讀取,這比交換到 zram 慢得多*。**對於應用程序,vm.swappiness 有效,但不適用於 tmpfs。

tmpfs 被掛載為頁面記憶體,因此它與文件記憶體具有相同的優先級。如果您從 tmpfs 讀取文件,它將優先於較舊的文件記憶體條目(最近使用)。但這很糟糕,核心顯然在這裡沒有做正確的事情。它應該考慮到將 tmpfs 交換到 zram 即使它比文件記憶體“最近使用”也要好得多,因為從驅動器讀取非常慢。

因此,與文件記憶體相比,我需要明確告訴它更頻繁地從 tmpfs 交換:它應該比 tmpfs 保留更多的文件記憶體。/proc/sys/vm 中有很多選項,但我找不到任何選項。真是令人失望。

如果做不到這一點,有沒有辦法告訴核心某些設備/驅動器比其他設備/驅動器慢得多,並且它應該比其他設備更喜歡為它們保留記憶體?tmpfs 和 zram 很快。拇指驅動器不是。我可以告訴核心這些資訊嗎?

如果它對所有驅動器都一視同仁,它本身就不能做“正確的事情”。將 tmpfs 交換到像 zram 這樣的快速驅動器比從慢速驅動器中刪除記憶體要快得多,即使最近使用 tmpfs 也是如此。

當它用完可用記憶體時,它將開始交換應用程序記憶體(好),因為交換性,或者丟棄舊的文件記憶體(壞)。如果我最終從這些文件中重新讀取,它會很慢。比它決定交換一些 tmpfs(即使最近使用)然後再次讀取它要慢得多。因為 zram 快了一個數量級。

增加swappiness值會使核心更願意交換 tmpfs 頁面,並且不太願意從不受交換支持的其他文件系統中逐出記憶體頁面。

由於 zram swap 比您的拇指驅動器快,因此您最好將 swappiness 增加到 100 以上。這僅在核心版本 5.8 或更高版本中才有可能。Linux 5.8 允許將 swappiness 設置為最大 200。

對於記憶體交換,如 zram 或 zswap,

$$ … $$可以考慮超過 100 的值。例如,如果針對交換設備的隨機 IO 平均比來自文件系統的 IO 快 2 倍,則交換量應為 133 (x + 2x = 200, 2x = 133.33)。 –文件/管理指南/sysctl/vm.rst


進一步閱讀

tmpfs 被視為與任何其他可交換記憶體相同

請參閱核心送出“ vmscan:將 LRU 列表拆分為匿名和文件集”-

將 LRU 列表分成兩部分,一組用於由真實文件系統(“文件”)支持的頁面,另一組用於由記憶體和交換(“anon”)支持的頁面。後者包括 tmpfs。

/*
* Determine how aggressively the anon and file LRU lists should be
* scanned.  The relative value of each set of LRU lists is determined
* by looking at the fraction of the pages scanned we did rotate back
* onto the active list instead of evict.
*
* nr[0] = anon inactive pages to scan; nr[1] = anon active pages to scan
* nr[2] = file inactive pages to scan; nr[3] = file active pages to scan
*/
static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,
              struct scan_control *sc, unsigned long *nr,
              unsigned long *lru_pages)
{
   int swappiness = mem_cgroup_swappiness(memcg);

   /*
    * With swappiness at 100, anonymous and file have the same priority.
    * This scanning priority is essentially the inverse of IO cost.
    */
   anon_prio = swappiness;
   file_prio = 200 - anon_prio;

Linux 5.8 允許swappiness值高達 200

mm:允許更喜歡在文件工作集上回收匿名的交換

隨著快速隨機 IO 設備(SSD、PMEM)和記憶體交換設備(如 zswap)的出現,交換可能比文件系統快得多,並且交換比文件系統記憶體更可取。

允許設置 swappiness - 它定義了頁面記憶體和交換支持頁面之間記憶體未命中的粗略相對 IO 成本 - 通過使交換首選範圍可配置來反映這種情況。

這是 Linux 5.8 中一系列更新檔的一部分。在以前的版本中,Linux“主要用於頁面記憶體並推遲交換,直到 VM 處於顯著記憶體壓力之下”。這是因為“算法演化所依據的旋轉驅動器的高尋軌成本也意味著錯誤可能很快導致過於激進的交換(主要是隨機 IO)導致鎖定。”

本系列旨在解決這個問題。自從送出(“a528910e12ec mm:基於抖動檢測的文件記憶體大小”)以來,我們可以精確跟踪故障 IO - 回收錯誤頁面的最終成本。這允許我們使用基於 IO 成本的平衡模型,該模型在記憶體抖動時更積極地掃描匿名記憶體,同時能夠避免不必要的交換風暴。

這些更新檔將 LRU 平衡基於每個列表上的故障率,乘以交換設備和文件系統之間的相對 IO 成本(swappiness),以優化回收以產生最小的 IO 成本。

$$ PATCH 00/14 $$mm:基於相對抖動 v2 平衡 LRU 列表

引用自:https://unix.stackexchange.com/questions/444392