32G RAMがインストールされ、16Gスワップが設定されているDebian 4.0.5(カーネル4.0.0-2)を実行するLinuxサーバーがあります。システムはパーティショニングに lxc コンテナを使用しますが、ここでは重要ではありません。問題は、他のコンテナの内側と外側に存在します。
典型的なものは次のとおりですfree -h
。
total used free shared buff/cache available
Mem: 28G 2.1G 25G 15M 936M 26G
Swap: 15G 1.4G 14G
/proc/meminfo
持つ
Committed_AS: 12951172 kB
したがって、割り当てられたすべてを実際にすぐに使用しても、まだ空きメモリがたくさん残ります。ただし、システムは実行中のプロセスもすぐにページングします。
iotop
これは、Unicornを使用するRailsアプリケーションであるGitlabで最も顕著です。新しく分岐したUnicornワーカースレッドはすぐに交換され、要求が受信されるとディスクから約1400 kB / s(のデータ)で読み取られ、タイムアウト(現在30秒)を設定して、いつでも再起動できます。通常の要求はメモリに完全にロードされ、すぐに終了するまで5秒以上かかることはありません。これは単なる例であり、redis、amavis、postgres、mysql、java(openjdk)などでこれが起こるのを見ました。
それ以外の場合は、システムの負荷が低く、CPU使用率が約5%、負荷平均が約2(8コア)です。
私たちが試したこと(特定の順序なし):
swapoff -a
:800M程度交換失敗- 削減された交換性を使用します(段階別)
sysctl vm.swappiness=NN
。まったく効果がないようです。 0%に低下しましたが、まだ同じ動作をしています。 - 必須ではないサービス(JettyベースのWebアプリケーション、Gitlab ...)を停止しておおよそのリリースします。 8GのコミットされたがマップされていないメモリとComfilled_ASを約5Gに減らします。まったく変わったことはありません。
- 明確なシステムキャッシュを使用してください
sync && echo 3 > /proc/sys/vm/drop_caches
。これはメモリを解放しますが、スワップケースには何もしません。 - 上記の組み合わせ
テストでfstabを介してスワップを完全に無効にするためにシステムを再起動することは、実際にはオプションではありません。一部のサービスには可用性の問題があり、「狩り」ではなく計画されたダウンタイムが必要なためです。そして、私たちは通常スワップを無効にしたくありません。 。
ここでなぜ交換が起こるのか理解できません。何が起こるのかというアイデアはありますか?
この問題はしばらく存在していましたが、高いIO負荷(長いバックグラウンドデータ処理操作)中に最初に現れたため、特定のイベントを正確に見つけることはできません。この作業が完了してから数日が経過しましたが、問題は引き続き解決され、この質問が発生します。
答え1
私が言ったことを覚えておいてください:
システムはパーティショニングに lxc コンテナを使用しますが、ここでは重要ではありません。
まあ、それは明らかになったした問題。それとも、lxcの中心にあるcgroupが重要です。
ホストはカーネルがアップグレードされたときにのみ再起動されます。それでは、最後に使用されたカーネルは何でしたか? 3.19は2ヶ月前の4.0.5と昨日の4.1.3に置き換えられました。昨日何があったの?左、右、中央のプロセスが膜化されます。検査の結果/var/log/kern.log
、影響を受けたプロセスはメモリが 512M の cgroup にあります。待って、512M?これは正しくありません(予想要件が約4Gの場合!)。明らかなように、これは数ヶ月前に設定したときにlxc設定で設定されたものとまったく同じです。
したがって、3.19はcgroupのメモリ制限を完全に無視します。 4.0.5は、許可されたよりも多くのcgroupが必要な場合は常にページングを実行します(これはこの問題の中心です)、4.1.3のみが完全なmemkiller-sweepを実行します。
ホストシステムのスワップ可能性は、物理メモリがほとんど不足しないため、これに影響を与えません。
解決策:
box1
一時変更の場合、たとえば cgroup という lxc コンテナを呼び出して cgroup を直接変更し、lxc/box1
ホストシステムで root として以下を実行できます。
$ echo 8G > /sys/fs/cgroup/memory/lxc/box1/memory.limit_in_bytes
永続的な解決策は、コンテナを正しく構成することです。/var/lb/lxc/...
lxc.cgroup.memory.limit_in_bytes = 8G
物語の教訓:常に設定を確認してください。これが問題になることができないと思っても(実際に失敗するカーネルには他のバグ/不一致があります)。