Memory

如何處理多使用者系統上的記憶體不足問題?

  • January 12, 2019

當一個程序試圖分配比可用記憶體更多的記憶體時,通常很難以一種好的方式處理這種情況。在某些情況下,程序可能能夠釋放非必要的記憶體(例如記憶體),但大多數情況下它會導致致命異常(另請參閱$$ 1 $$),通過使用OOM 殺手來交換和大規模系統減慢甚至殺死(相當任意的)程序。

在單使用者系統上,所有選項都不好,但至少你只能傷害自己(畢竟你對你機器上執行的所有程式碼負責)。

然而,在多使用者系統上,我希望有可能讓 OOM 殺手殺死可能由其他使用者擁有的某些程序。有一定的限制,因為 OOM 殺手試圖找到一個“正在使用大量記憶體但壽命不長的程序”(參見此處)。

儘管如此,想像一個程序需要 x MB 記憶體並且沒有存活很長時間(低 CPU 時間)並且由使用者 X 擁有並且 x 遠遠超過系統上的可用記憶體的情況,使用者 Y 可能能夠分配比可用記憶體更多的記憶體並導致系統終止 X 的程序(因為它正在使用更多記憶體)。

這種情況聽起來比單使用者機器上的類似含義更可怕。可以為每個使用者設置記憶體限制,甚至可以使用容器來進一步分離程序。但據我了解,只有將限制設置為total_memory / number_of_users才能解決問題。但是,當設置這樣的限制時,就會失去多使用者系統的所有好處。該機器實際上類似於一個盒子中的多台單使用者機器。人們通常希望允許一位使用者在高峰時間使用更多記憶體,因為大多數時候使用者需要的記憶體比平均記憶體少。

我最感興趣的是在具有大量數據的大型計算的情況下解決這個問題。我想在 Web 伺服器的情況下,可能能夠更好地估計需要多少記憶體,因為有很多小操作,而不是少數大操作。但即使在這種情況下,我聽說在正常情況下,只有 50% 的記憶體應該被填充,以避免在高峰期出現記憶體不足的問題。這不是浪費你50%的記憶體嗎?

特別是我正在考慮託管一個 Jupyter 集線器或類似的東西。但我不希望使用者殺死彼此的程序。

有沒有其他解決方案可以緩解這個問題?像 Travis CI 這樣的大型雲提供商如何處理此類問題?

我相信現在限制一項任務對其他任務的影響的推薦方法是使用 cgroup 來限制它可以使用的記憶體。我發現最簡單的方法是使用systemd-run. 例如,這以ls1000 字節的低記憶體限制開始:

sudo systemd-run --uid $USER --gid $UID -p MemoryMax=1000 ls

執行journalctl -f,你會看到程序已經被立即殺死:

Memory cgroup out of memory: Kill process 3543 ((ls)) score 2503000 or sacrifice child
Killed process 3543 ((ls)) total-vm:205348kB, anon-rss:5612kB, file-rss:4276kB, shmem-rss:0kB

那麼當然你會想要超額訂閱機器,也許給每個任務 70% 的可用記憶體?這將允許記憶體消耗達到峰值,同時仍會快速終止使用不合理記憶體量的程序。

引用自:https://serverfault.com/questions/948676