如何關閉單一進程的區塊快取?

如何關閉單一進程的區塊快取?

我有一個包含許多磁碟綁定服務的大型系統。使用區塊快取它們可以更好地工作。

除此之外,還有一些備份進程正在運作。

我知道他們應該如何使用塊緩存:他們絕對不應該。

備份是透過將一個區塊設備複製到另一個區塊設備來進行的buffer命令。需要任何快取的可能性幾乎為零。

但是,如果備份運行,就會使普通服務變得更糟。給予低ionice對它沒有太大幫助 - 問題不在於它的 IO 優先級,而是它用不需要的資料覆蓋了區塊快取。

我可以以某種方式設定此buffer命令以完全不使用區塊快取嗎?

如果重要的話,它會將 lvm 磁碟區複製到另一個磁碟區。

答案1

我找到了nocache任務的工具。

一般來說,這在 Linux 中是不可能的:沒有這樣的選項、標誌或任何東西,可以為過程

但是,那posix_fadvise(...)當需要連續讀取/寫入操作時,呼叫可用於通知區塊/緩衝區快取子系統。 APOSIX_FADV_DONTNEED向核心提供“額外資訊”,它不應該快取它們,因為它不會在不久的將來重新讀取。

nocacheposix_fadvise(...)透過環境變數注入的共享庫攔截所有重要的檔案操作LD_PRELOAD

正如其名稱所示,這只是一個建議;然而我的實驗表明巨大的效能改進(實際上,其他重要任務可以與後台備份並行運行,而最終用戶不會出現明顯的效能下降)。

答案2

像這樣的工具nocache其實是不是適當的解決方案。引用無緩存的來源:

這個工具是什麼不是適合:

  • 控制頁面快取的使用方式
    • 為什麼你認為你在 GitHub 上找到的一些隨機工具可以比 Linux 核心做得更好?
  • 防禦快取抖動
    • 使用 cgroup 來限制進程擁有的記憶體量。請參閱下文或在互聯網上搜索,這是眾所周知的,工作可靠,並且不會像此工具那樣引入性能損失或潛在的危險行為。

因此,使用 cgroups(更準確地說,在 2023 年,只要有可能,肯定是 cgroupsv2)來限制您的進程可以使用的快取量(從而限制它可以驅逐的快取量):

如何在記憶體有限的 cgroup 中運行進程及其子進程

例如,如果您想要執行備份,但不希望系統因頁面快取抖動而減慢速度,請執行此操作。

如果你使用systemd

如果您的發行版使用systemd,這非常簡單。 Systemd 允許在「範圍」(即 cgroup)中執行進程(及其子進程),並且您可以指定轉換為 cgroup 限制的參數。

當我運行備份時,我會:

$ systemd-run --scope --property=MemoryLimit=500M -- backup command 

MemoryMax對於 v2)

其效果是快取空間受到額外的最大 500MiB 的限制:

前:

$ free -h
              total        used        free      shared  buff/cache   available
Mem:           7.5G        2.4G        1.3G        1.0G        3.7G        3.7G
Swap:          9.7G         23M        9.7G

期間(注意 buff/cache 只增加了約 300MiB):

$ free -h
              total        used        free      shared  buff/cache   available
Mem:           7.5G        2.5G        1.0G        1.1G        4.0G        3.6G
Swap:          9.7G         23M        9.7G

這是如何運作的?

用於systemd-cgls列出 systemd 建立的 cgroup。在我的系統上,上述命令建立一個名為run-u467.scopesystem.slice群組的群組;你可以像這樣檢查它的記憶體設定:

$ mount | grep cgroup | grep memory cgroup on
/sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec
latime,memory)

$ cat /sys/fs/cgroup/memory/system.slice/run-u467.scope/memory.limit_in_bytes
524288000

相關內容