Linuxオペレーティングシステムが長期間稼働すると、メモリの断片化が発生する可能性があります。 このトピックでは、この問題の解決策を提供します。

問題の説明

インスタンスにデプロイされたサービスの応答に長時間がかかる場合や、システムコールに長時間がかかる場合、システムのsysメトリック値はそれに応じて増加します。 バディシステムには、上位メモリ (次数が3を超えるメモリ) がありません。 次のコードは、cat /proc/buddyinfoコマンドの出力例を示しています。 第4列目から始まる各列は、バディシステムの異なる順序での空きメモリを示す。
cat /proc/buddyinfo
ノード0、ゾーンDMA 1 0 1 2 1 1 1 0 1 3
ノード0、ゾーンDMA32 3173 856 529 0 0 0 0 0 0 0
ノード0、ゾーン通常19030 8688 7823 0 0 0 0 0 0 0

考えられる原因

Linuxオペレーティングシステムが長期間稼働すると、連続した大きな物理メモリチャンクが小さな物理メモリブロックに分割されます。 サービスが連続した大規模なメモリチャンクを必要とする場合、システムはメモリコンパクション手順を開始しますが、これには時間がかかり、システムパフォーマンスのジッターが発生する可能性があります。 メモリ断片化は通常、カーネルスタック情報を生成する。 カーネルスタック情報の例を次に示します。
0xffffffff8118f9cb compaction_alloc ([kernel.kallsyms])
0xffffffff811c88a9 migrate_pages ([kernel.kallsyms])
0xffffffff811901ee compact_zone ([kernel.kallsyms])
0xffffffff8119041b compact_zone_order ([kernel.kallsyms])
0xffffffff81190735 try_to_compact_pages ([kernel.kallsyms])
0xffffffff81631cb4 __alloc_pages_direct_compact ([kernel.kallsyms])
0xffffffff811741d5 __alloc_pages_nodemask ([kernel.kallsyms])
0xffffffff811b5a79 alloc_pages_current ([kernel.kallsyms])
0xffffffff811c0005 new_slab ([kernel.kallsyms])
0xffffffff81633848 __slab_alloc ([kernel.kallsyms])
0xffffffff811c5291 __kmalloc_node_track_caller ([kernel.kallsyms])
0xffffffff8151a8c1 __kmalloc_reserve.isra.30 ([kernel.kallsyms])
0xffffffff8151b7cd alloc_sib ([kernel.kallsyms])
0xffffffff815779e9 sk_stream_alloc_skb ([kernel.kallsyms])
0xffffffff8157872d tcp_sendmsg ([kernel.kallsyms])
0xffffffff815a26b4 inet_sendmsg ([kernel.kallsyms])
0xffffffff81511017 sock_aio_write ([kernel.kallsyms])
0xffffffff811df729 do_sync_readv_writev ([kernel.kallsyms])
0xffffffff811e0cfe do_readv_writev ([kernel.kallsyms])

ソリューション

Linuxオペレーティングシステムのメモリ断片化のトラブルシューティングには、次のいずれかの対策を講じることができます。
  • 最小透かしを調整する
    ほとんどの場合、minウォーターマークを合計メモリの1% 〜3% に設定することをお勧めします。 合計メモリの2% に設定することを推奨します。 メモリリソースが不足すると、非同期再利用がトリガーされます。 次のコマンドを実行して、最小透かしを調整できます。
    sysctl -w vm.min_free_kbytes =memtotal_kbytes * 2%
    上記のコマンドでは、memtotal_kbytes * 2% 変数は、インスタンスの総メモリの2% であるメモリサイズを示します。
  • 最小透かしと低透かしの差を調整する
    watermark_scale_factorカーネルパラメーターを指定して、突然のメモリ需要に対処するために最小透かしと低透かしの差を調整できます。 watermark_scale_factorのデフォルト値はメモリ全体の0.1% であり、最小値は次の式に基づいて計算されます: 0.5 × <min watermark> 。 最小値は、最小透かしと低透かしとの間の最小差である。 次のコマンドを実行して、watermark_scale_factorの値を調整できます。
    sysctl -w vm.watermark_scale_factor =value
    上記のコマンドでは、value変数は、最小透かしと低透かしの間に指定された差を示します。
  • 通常のメモリ圧縮の実行
    次のコマンドを実行すると、オフピーク時に非同期メモリのコンパクションをトリガーできます。
    エコー1 > /proc/sys/vm/compact_memory
  • 定期的にキャッシュを手動でドロップする
    上記の方法でメモリの断片化を効果的に処理できない場合は、オフピーク時にキャッシュをドロップして、メモリを再割り当てすることもできます。 キャッシュを削除することで、メモリの断片化を効果的に防ぎます。 ただし、この操作を実行すると、短期間のシステムパフォーマンスのジッターが発生することがあります。 次のコマンドを実行して、キャッシュを削除します。
    エコー3 > /proc/sys/vm/drop_caches