- 過剰なスワッピングにより応答しなくなったり、極端に遅くなったLinuxシステムの制御を回復する最も速い方法は何ですか?
Alt-SysRq-Fで既に回答済み
- たとえば、プロセスが割り当てることを許可されているメモリの量を制限することによって、そのようなスワッピングが最初に発生するのを防ぐ効果的な方法はありますか?
私はこの第2部に答えています。はい、ulimit
それでも単一のプロセスを制限するのに十分に機能します。あなたはできる:
- 制御不能になる可能性があることがわかっているプロセスにソフト制限を設定する
- 追加の保険が必要な場合は、すべてのプロセスにハード制限を設定します
また、簡単に述べたように:
CGroupsを使用して、リソースの使用を制限し、そのような問題を防ぐことができます
確かに、cgroupsはより高度な制御を提供しますが、私の意見では現在、構成がより複雑です。
古い学校のulimit
オフになったら
以下に簡単な例を示します。
$ bash
$ ulimit -S -v $((1*2**20))
$ r2(){r2 $@$@;};r2 r2
bash: xmalloc: .././subst.c:3550: cannot allocate 134217729 bytes (946343936 bytes allocated)
それ:
- 1GBの全体的なメモリ使用のソフト制限を設定します(ulimitはkB単位の制限を想定しています)
- 再帰的にbash関数呼び出し
r2(){ r2 $@$@;};r2 r2
を実行します。これは、スタックメモリを要求している間に無限に倍増することにより、CPUとRAMを指数関数的に噛みます。
ご覧のとおり、1GB以上を要求しようとすると停止しました。
-v
仮想メモリの割り当て(合計、つまり物理+スワップ)で動作することに注意してください。
永久保護
仮想メモリの割り当てを制限するにas
は、と同等-v
ですlimits.conf
。
単一の不正なプロセスから保護するために、次のことを行います。
- すべてのプロセスにハードアドレス空間の制限を設定します。
address space limit = <physical memory> - 256MB
。
- したがって、貪欲なメモリ使用やアクティブループとメモリリークのある単一のプロセスが、すべての物理メモリを消費することはありません。
- 256MBのヘッドルームは、sshまたはコンソールでの重要な処理に使用できます。
一発ギャグ:
$ sudo bash -c "echo -e \"*\thard\tas\t$(($(grep -E 'MemTotal' /proc/meminfo | grep -oP '(?<=\s)\d+(?=\skB$)') - 256*2**10))\" > /etc/security/limits.d/mem.conf"
検証するには、これにより次の結果が得られます(16GBシステムなど):
$ cat /etc/security/limits.d/mem.conf
* hard as 16135196
$ ulimit -H -v
161351960
ノート:
- メモリを使用して1つのプロセスがオーバーボードするのを緩和するだけです。
- マルチプロセスワークロードがスラッシングの原因となる大きなメモリプレッシャーを防ぐことはありません(cgroupsがその答えです)。
rss
limits.confでオプションを使用しないでください。新しいカーネルでは尊重されていません。
- 保守的です。
- 理論的には、プロセスは投機的に多くのメモリを要求できますが、サブセットのみを積極的に使用します(より小さなワーキングセット/常駐メモリの使用)。
- 上記のハード制限により、そのようなプロセスは中止されます(Linuxが仮想メモリアドレス空間のオーバーコミットを許可している場合は、正常に実行されていたとしても)。
新しいCGroups
より多くの制御を提供しますが、現在はより複雑です:
- ulimitオファリングの改善。
memory.max_usage_in_bytes
物理メモリを個別に考慮および制限できます。
- 一方
ulimit -m
および/またはrss
でlimits.conf
同様の機能を提供するためのもの、それはカーネルのLinux 2.4.30以降の仕事をしませんしました!
- ブートローダーでいくつかのカーネルcgroupフラグを有効にする必要があります:
cgroup_enable=memory swapaccount=1
。
- これは、Ubuntu 16.04ではデフォルトでは発生しませんでした。
- おそらく、余分なアカウンティングオーバーヘッドのパフォーマンスへの影響が原因です。
- cgroup / systemdのものは比較的新しく、かなり変更されているため、アップストリームのフラックスは、Linuxディストリビューションベンダーがまだ使いやすくしていないことを意味します。14.04LTSと16.04LTSの間で、cgroupを使用するためのユーザー空間ツールが変更されました。
cgm
現在、公式にサポートされているユーザースペースツールのようです。
- systemdユニットファイルには、sshのような重要なサービスに優先順位を付けるための事前定義された「ベンダー/ディストリビューション」デフォルトはまだないようです。
たとえば、現在の設定を確認するには:
$ echo $(($(cat /sys/fs/cgroup/memory/memory.max_usage_in_bytes) / 2**20)) MB
11389 MB
$ cat /sys/fs/cgroup/memory/memory.stat
...
たとえば、単一プロセスのメモリを制限するには:
$ cgm create memory mem_1G
$ cgm setvalue memory mem_1G memory.limit_in_bytes $((1*2**30))
$ cgm setvalue memory mem_1G memory.memsw.limit_in_bytes $((1*2**30))
$ bash
$ cgm movepid memory mem_1G $$
$ r2(){ r2 $@$@;};r2 r2
Killed
バックグラウンドプロセスとしてRAMを噛み締めてから強制終了する動作を確認するには:
$ bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2' & while [ -e /proc/$! ]; do ps -p $! -o pcpu,pmem,rss h; sleep 1; done
[1] 3201
0.0 0.0 2876
102 0.2 44056
103 0.5 85024
103 1.0 166944
...
98.9 5.6 920552
99.1 4.3 718196
[1]+ Killed bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2'
メモリリクエストの指数関数的な増加(2のべき乗)に注意してください。
将来、SSHやグラフィカルスタックなどの重要なもののcgroupの優先度と制限を事前に設定する「ディストリビューション/ベンダー」を見て、メモリが枯渇しないようにしましょう。