web-dev-qa-db-ja.com

マルチユーザーシステムのメモリ不足の問題に対処するにはどうすればよいですか?

プロセスが使用可能なメモリよりも多くのメモリを割り当てようとすると、通常、この状況を適切に処理することは非常に困難です。プログラムが不要なメモリ(キャッシュなど)を解放できる場合もありますが、ほとんどの場合、致命的な例外( [1] も参照)、 スワッピングおよび大規模なシステムの速度低下 または OOM killer を使用して(かなり恣意的な)プロセスを強制終了します。

シングルユーザーシステムでは、すべてのオプションが悪いですが、少なくとも自分自身を傷つけることしかできません(結局のところ、マシンで実行するすべてのコードに対して責任があります)。

ただし、マルチユーザーシステムでは、他のユーザーが所有している可能性のある特定のプロセスをOOMキラーで強制終了できる可能性があると思います。 OOMキラーは「大量のメモリを使用しているが、それほど長くは続かないプロセス」を見つけようとするため、特定の制限があります( ここ を参照)。

それにもかかわらず、プロセスがx MBのメモリを必要とし、非常に長い間存続せず(CPU時間が短い)、ユーザーXが所有し、xがシステムの空きメモリよりも大幅に多い状況をイメージすると、ユーザーYは使用可能なメモリよりも多くのメモリを割り当て、システムにXのプロセスを強制終了させます(より多くのメモリを使用しているため)。

この状況は、シングルユーザーマシンでの同様の影響よりもはるかに恐ろしいように聞こえます。ユーザーごとにメモリ制限を設定したり、コンテナを使用してプロセスをさらに分離したりすることもできます。しかし、私が理解している限り、制限をtotal_memory / number_of_usersに設定するだけで問題は解決します。しかし、そのような制限を設定すると、マルチユーザーシステムからのすべての利点が失われます。このマシンは、実際には、1つのボックス内の複数のシングルユーザーマシンに似ています。ほとんどの場合、ユーザーが必要とするメモリは平均よりも少ないため、通常、ピーク時に1人のユーザーがより多くのメモリを使用できるようにする必要があります。

私は主に、大量のデータを使用して大規模な計算を行う状況でこの問題を解決することに関心があります。 Webサーバーの場合、小さな操作が多く、大きな操作が少なくないため、必要なメモリ量をより正確に見積もることができると思います。しかし、この場合でも、通常の状況では、ピーク時のメモリ不足の問題を回避するために、メモリの50%のみを埋める必要があると聞いています。これはあなたの記憶の50%の無駄ではありませんか?

特に、Jupyterハブなどをホストすることを考えています。しかし、私はユーザーがお互いのプロセスを殺してほしくない。

この問題を軽減する他の解決策はありますか? Travis CIのような巨大なクラウドプロバイダーは、この種の問題にどのように対処しますか?

1
lumbric

今日、あるタスクが他のタスクに与える影響を制限するための推奨される方法は、cgroupを使用して使用できるメモリを制限することだと思います。私が見つけた最も簡単な方法は、systemd-runを使用することです。たとえば、これはlsを1000バイトという途方もなく低いメモリ制限で開始します。

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%を割り当てたいと思うでしょう。これにより、メモリ消費量のピークが可能になりますが、それでも不当な量のメモリを使用するプロセスはすぐに強制終了されます。

3
Jakob

Oomキラー(sysctlによって読み取られたファイルのvm.oom-kill = 0)を無効にし、メモリのオーバーコミット(vm.overcommit_memory = 2)を無効にします。使用可能なメモリよりも多くのメモリを割り当てようとするプロセスはすべて強制終了されます。他のプロセスが強制終了されることはありません。すべてのメモリを使用できます。メモリが無駄になることはありません。

これはメモリの占有を防ぐことはできません。メモリcgroupには(memory.soft_limit_in_bytesおよびmemory.limit_in_bytesと組み合わせて)役立つように見えるmemory.memsw.limit_in_bytes設定がありますが、その動作の詳細な説明は見つかりませんでした。

編集:カーネルソースでmemory.soft_limit_in_bytesがどのように使用されているかを調べました。メモリを再利用できない場合、何も起こりません。

2
Mark Wagner

Sysctl vm.oom_kill_allocating_taskを設定できます。これが設定されていて、プロセスメモリ要求によってメモリが不足する場合、Linuxはそのプロセスを強制終了します。

ドキュメントから:

これにより、メモリ不足の状況でOOMトリガータスクを強制終了できるか無効になります。

これがゼロに設定されている場合、OOMキラーはタスクリスト全体をスキャンし、ヒューリスティックに基づいてタスクを選択して強制終了します。これは通常、強制終了時に大量のメモリを解放する不正なメモリ占有タスクを選択します。

これがゼロ以外に設定されている場合、OOMキラーは、メモリ不足状態をトリガーしたタスクを単に強制終了します。これにより、コストのかかるタスクリストスキャンが回避されます。

Panic_on_oomが選択されている場合、oom_kill_allocating_taskで使用されている値よりも優先されます。

デフォルト値は0です。

1
Michael Hampton