Linuxメモリの断片化


20

Linuxでメモリの断片化を検出する方法はありますか?これは、一部の長時間実行されているサーバーでパフォーマンスの低下に気づき、プロセスを再起動した後にのみパフォーマンスが向上するためです。Linuxのヒュージページサポートを使用すると、Linuxのヒュージページが断片化されやすくなることに気付きました。

特に/ proc / buddyinfoを見ました。私はそれを見るためのより良い方法(CLIコマンド自体だけでなく、プログラムや理論的背景が行うであろう)があるかどうかを知りたいです。


簡単なコマンドラインソリューションだけを見ているわけではありません。単純なプログラム/理論でも同様です。したがって、私はserverfaultで尋ねませんでした。
ラグー

1
私はここで一つの点を理解していません。私が理解している限り、メモリの断片化はメモリ不足につながり、その結果としてメモリ割り当てエラーが発生するはずです。ただし、パフォーマンスの低下について尋ねています。ディスクに大量のメモリがスワップされているためですか?もしそうならvmstat、フィールドに何を与えるso

@skwllsp-回答をより具体的に編集しました。
ティムポスト

@Raghu-ほとんどのシステム管理者がカーネルコードを変更してメモリ管理の動作を変えるとは思わないでしょうが、熟練した Linux管理者は少なくともLinuxがメモリを管理する方法の概要を知っている必要があります。この質問は実際に行方不明です。あなたの質問に答えるコードを(私の答えでは)提案できないので、私はそれを移行することに投票しました。/ procからの読み取りまたは使用vmstatは、一般的なユーザーエクスペリエンスです。あなたが同じことをするプログラムを書いているなら、それは違うでしょう。bashを使用してこの情報を収集する場合は、質問を編集してください。閉じられません:)
ティムポスト

@Tim-知りたいbash / cliコマンドだけではないことを示唆したように、ベンチマーク手順(結果を実行するのではなく、結果を分析する)に役立つ情報が必要でした。
ラグー

回答:


12

タグに答えています。私の答えはLinuxだけに固有のものです。

はい、巨大なページは断片化の傾向があります。メモリには2つのビューがあります。1つはプロセスが取得するもの(仮想)、もう1つはカーネルが管理するもの(実際)です。特にページが大きいほど、隣接するグループをグループ化(および維持)するのが難しくなります。特に、デフォルトで他のメモリよりも多くのメモリを割り当てて書き込むシステムもサポートしているシステムで実行している場合はなおさらです。実際に使用することになります。

(実際の)許可されたアドレスのカーネルのマッピングはプライベートです。カーネルはユーザー空間を混乱させることなくオーバーコミットできる必要があるため、カーネルがそれらを表示するときにユーザー空間がそれらを見る非常に良い理由があります。あなたのプロセスは、素敵な、連続的な取得「Disneyfied」カーネルが実際にされているものの忘れて仕事にでアドレス空間、やっ舞台裏そのメモリとを。

長時間実行されているサーバーでパフォーマンスが低下するのは、明示的にロックされていない(たとえば、mlock()/ mlockall()またはposix_madvise())しばらくの間変更されていない割り当てられたブロックがページアウトれたためです。それら。この動作を変更すると、プロセスが悪い隣人になります。これが、多くの人がweb / php / python / ruby​​ / whateverとはまったく異なるサーバーにRDBMSを配置する理由です。それを正す唯一の方法は、連続したブロックの競合を減らすことです。

断片化は、ページAがメモリ内にあり、ページBがスワップに移動した場合にのみ(ほとんどの場合)実際に顕著です。当然、サービスを再起動するとこれが「治癒」するように見えますが、それはカーネルがプロセスをページアウトする機会をまだ持っていないためです(現在)、オーバーコミット率の範囲内で新しく割り当てられたブロック。

実際、高負荷の状態で「apache」を再起動すると(たとえば)、他のサービスが所有するブロックを直接ディスクに送信する可能性があります。そのため、「apache」は短期間で改善されますが、「mysql」は、少なくとも十分な物理メモリが不足しているときに少なくともカーネルが同等に苦しめるまでは苦しむ可能性があります。

メモリを追加するか、要求の厳しいmalloc()コンシューマーを分割します:)注目すべき断片化だけではありません。

vmstat実際に何がどこに保存されているかの概要を取得してください。


答えてくれてありがとう。私はmysql-innodbバッファープールに巨大なページ(サイズ= 2048 KB)を使用して、(sysbenchを使用して)どれだけうまくいくかを確認していました。最初は、プロセスのアップタイム(およびシステムのアップタイムも)が低い場合、非常に良い結果が得られていました。ただし、そのパフォーマンスは数回の実行で低下し始めました。あなたが言及したページについて、私は確かに高いVMアクティビティに気づきましたが、ベンチマークとinnodbログフラッシュ(VMアクティビティは巨大なページの方が高いよりも高い)のためであると推測しました。また、vm.swappinessを1に設定しました。大幅な変更はありませんでした。
ラグー

細かいマニュアルによると、「メモリのプレッシャーの下で巨大なページをスワップアウトすることはできません。」これはw / r / t標準メモリでは良い答えだと思いますが、巨大ページではそうではありません。
ダンプリッツ

5

カーネル

現在の断片化インデックスを取得するには、次を使用します。

sudo cat /sys/kernel/debug/extfrag/extfrag_index

カーネルメモリを最適化するには、次を実行してください。

sysctl vm.compact_memory=1  

また、Transparent Huge Pages(別名THP)をオフにするか、swap(または減少swappiness)を無効にします。

ユーザースペース

ユーザースペースの断片化を減らすために、たとえば、異なるアロケーターを試してみることをお勧めしますjemalloc(これには優れたイントロスペクション機能があり、アロケーターの内部断片化の内部を知ることができます)。

あなたはそれでまたはちょうどであなたのプログラムを実行して、プログラムを再コンパイルすることで、カスタムのmallocに切り替えることができますLD_PRELOADLD_PRELOAD=${JEMALLOC_PATH}/lib/libjemalloc.so.1 app (の用心THPとメモリのメモリアロケータの間の相互作用

メモリの断片化とは少し関係ありません(ただし、メモリの圧縮/移行に接続されています)が、おそらくNUMAノードごとに1つのサービスの複数のインスタンスを実行し、を使用してそれらをバインドする必要がありますnumactl


1
スワップを無効にするとなぜ役立つと思いますか?私にとっては、スワップを無効にするとさらに傷つく可能性が高いようです。
カスペルド

1
元の投稿に十分な情報がないため、プロセスがリークしてスワップを開始している可能性があります。また、ほとんどすべての実稼働システムでスワップを使用する正当な理由はありません(学生用の共有ワークステーションのみ)。
SaveTheRbtz

2
十分なスワップ領域があると、パフォーマンスが向上します。スワップスペースが不十分な場合に発生するパフォーマンスの問題は、スワップを有効にするのに十分な理由です。
カスペルド

1
@SaveTheRbtz実稼働システムでスワップを使用する正当な理由は、システムに有益だと思われる場合にのみ使用するオプションをシステムに提供することです。また、数時間以内にアクセスされていない(アクセスされていない可能性がある)変更されたページを貴重な物理メモリから取り出すこともできます。最後に、システムは、使用されているよりもはるかに多くのメモリが予約されているケースを正常に処理できます。
デビッドシュワルツ

2
「有益であると考えられる場合のみ」-ヒューリスティックが追加され、システムの予測が難しくなります。また、ページ置換アルゴリズム(swapおよびanonymousで使用mmap)は、異なるカーネル(LinuxとFreeBSDなど)、または同じOSの異なるバージョン(2.6.32対3.2対3.10)でも異なる方法で実装されます。 ..] [...]物理メモリから排出されます」-メモリリークを隠します。「使用されているよりも多くのメモリが予約されているケースを処理する」-遅いシステムはダウンしたシステムよりもはるかに悪いため、「正気」は疑わしい。
SaveTheRbtz

4

巨大なページを使用しても、Linuxで余分なメモリの断片化は発生しません。Linuxのhugeページのサポートは共有メモリ(shmgetまたはmmap経由)のみであり、使用されるhugeページはシステム管理者によって特別に要求され、事前に割り当てられる必要があります。メモリに格納されると、それらはそこに固定され、スワップアウトされません。メモリの断片化に直面して巨大なページをスワップすることの難しさは、まさにメモリ内に固定されたままである理由です(2MBの巨大なページを割り当てるとき、カーネルは512個の連続した空き4KBページを見つける必要がありますが、これは存在しないこともあります)。

巨大なページのLinuxドキュメント:http : //lwn.net/Articles/375098/

メモリの断片化により巨大なページの割り当てが遅くなる場合があります(ただし、巨大なページメモリの断片化を引き起こす場合はありません)。それは、アプリケーションから要求された場合に巨大なページのプールを拡大するようにシステムが構成されている場合です。/ proc / sys / vm / nr_overcommit_hugepagesが/ proc / sys / vm / nr_hugepagesより大きい場合、これが発生する可能性があります。


確かに-TLBミスを防ぐため、一般にパフォーマンス向上させるはずです(説明については、リンクされた記事を参照してください)。
ダンプリッツ

0

あり/proc/buddyinfo非常に有用です。このPythonスクリプトができるように、素敵な出力形式でより便利です。

https://gist.github.com/labeneator/9574294

巨大なページの場合、2097152(2MiB)サイズ以上の空きフラグメントが必要です。透過的な巨大なページの場合、カーネルに要求されたときに自動的に圧縮されますが、取得できる数を確認するには、rootで実行します。

echo 1 | sudo tee /proc/sys/vm/compact_memory

また、はい、巨大なページは断片化に大きな問題を引き起こします。巨大なページを取得できないか、そのページが存在するため、カーネルが取得しようとして余分な時間を費やすことになります。

私に合った解決策があります。いくつかのサーバーとラップトップで使用しています。仮想マシンに最適です。

kernelcore=4GLinuxカーネルコマンドラインにオプションを追加します。私のサーバーでは8Gを使用しています。カーネルがそのメモリ外に何かを割り当てることを防ぐため、数値に注意してください。多くのソケットバッファを必要とするサーバーや、ディスク書き込みを数百のドライブにストリーミングするサーバーは、このように制限されることを好みません。スラブまたはDMAに「固定」する必要があるメモリ割り当ては、このカテゴリに属します。

その後、他のすべてのメモリが「移動可能」になります。つまり、巨大なページ割り当てのために素敵なチャンクに圧縮できます。透明な巨大ページは、想定どおりに実際に離陸して機能します。カーネルがさらに2Mページを必要とするときはいつでも、4Kページを別の場所に単純に再マッピングできます。

また、これがゼロコピーダイレクトIOとどのように相互作用するのか、完全にはわかりません。「可動ゾーン」のメモリは固定されることを想定していませんが、直接IOリクエストはDMAに対してそれを正確に行います。コピーするかもしれません。とにかくそれを可動ゾーンに固定するかもしれません。どちらの場合でも、おそらくあなたが望んでいたものではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.