Linuxカーネルに特定の割合のメモリのみをバッファキャッシュとして使用するように指示する方法はありますか?一時的にキャッシュを消去するために使用できることはわかっていますが、/proc/sys/vm/drop_caches
キャッシュがメインメモリの50%を超えて増加するのを防ぐ永続的な設定はありますか?
私がこれをやろうとしているのは、ディスクからデータを継続的に提供し、数時間以内に物理メモリ全体をバッファキャッシュとして使用するCeph OSDを実行しているサーバーがあるためです。同時に、大量(数十GB)の物理メモリを割り当てるアプリケーションを実行する必要があります。一般的な信念(バッファキャッシングに関するほとんどすべての質問に提供されているアドバイスを参照)とは異なり、クリーンなキャッシュエントリを削除して自動的にメモリを解放することは、いいえ一時的:バッファキャッシュがいっぱいになると(*)アプリを実行するのに最大1分かかりますが、キャッシュをクリアした後は(を使用してecho 3 > /proc/sys/vm/drop_caches
)同じアプリがほぼすぐに起動します。
(*)名前付き関数のVtuneによると、この起動時間中にアプリケーションは新しいメモリでクラッシュしますが、その時間の100%をカーネルで消費しますpageblock_pfn_to_page
。この機能は、巨大なページを見つけるために必要なメモリ圧縮に関連しているようで、これは実際に断片化が問題であると信じています。
答え1
絶対的な制限は必要ありませんが、バッファをより速くフラッシュするようにカーネルに圧力をかける場合は、次の点を見てください。vm.vfs_cache_pressure
この変数は、VFSキャッシュ(ページキャッシュとスワップと比較)キャッシュに使用されるメモリを回復するカーネルの傾向を制御します。この値を大きくすると、VFS キャッシュの回収率が高くなります。
範囲は0〜200です。より高い圧力を得るには、200ページに進みます。デフォルト設定は100です。このslabtop
コマンドを使用してメモリ使用量を分析することもできます。あなたの場合は、dentry
その金額が*_inode_cache
高くなければなりません。
絶対限度が欲しいなら探してみなければなりませんcgroups
。 Ceph OSDサーバーをcgroupに配置し、memory.limit_in_bytes
cgroupのパラメータを設定して使用できる最大メモリを制限します。
memory.memsw.limit_in_bytes
結合メモリとスワップ使用量の最大量を設定します。単位が指定されない場合、値はバイトとして解釈されます。ただし、より大きな単位を表すためにサフィックスを使用できます。 k または K はキロバイト、m または M はメガバイト、g または G はギガバイトです。
引用:
[1]-GlusterFS Linuxカーネルのチューニング
[2]-RHEL 6リソース管理ガイド
答え2
Ceph OSDが別々のプロセスの場合は、次のものを使用できます。cgroupプロセスで使用されるリソースを制御します。
group1というcgroupを作成し、メモリ制限を設定します(たとえば、CPUなどの他の制限をサポートする50 GBも例に記載されています)。
cgcreate -g memory,cpu:group1
cgset -r memory.limit_in_bytes=$((50*1024*1024*1024)) group1
その後、アプリケーションがすでに実行されている場合は、アプリケーションをこのcgroupに入れます。
cgclassify -g memory,cpu:group1 $(pidof your_app_name)
または、このcgroupでアプリケーションを実行します。
cgexec -g memory,cpu:group1 your_app_name
答え3
A%についてはわかりませんが、x分後に削除されるようにタイムアウトを設定できます。
まずターミナルで
sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
現在のキャッシュを消去します。
cron-job
Alt-F2で作成しgksudo gedit /etc/crontab
、 次に、下部近くにこの行を追加します。
*/15 * * * * root sync && echo 3 > /proc/sys/vm/drop_caches
**15分ごとに清掃してください。本当に必要な場合は、最初のパラメータを*に変更するか、1分または5分に設定できます。/ 5の代わりに/ 15
使用可能なRAMを確認するには(キャッシュを除く):
free -m | sed -n -e '3p' | grep -Po "\d+$"
答え4
質問の終わりに、あなたの直感が正しいと思います。私は、A. NUMA認識メモリ割り当てがCPU間のページを移行するか、B.連続して整列された領域を見つけようとする透明なhugepageデフラグコードである可能性が高いと思います。
HugepagesとTransparent hugepagesは、特定のワークロードのパフォーマンスを大幅に向上させることが知られていますが、多くの利点を提供することはできず、CPU時間を大量に消費します。
実行中のカーネル、/proc/meminfoの内容(または少なくともHugePages_ *値)、および(可能であれば)pageblock_pfn_to_page()を参照する追加のvtuneプロファイラ呼び出しグラフを知ることが役立ちます。
また、私の推測を受け入れたい場合は、大きなページの最適化を無効にしてみてください。
echo 'never' >/sys/kernel/mm/transparent_hugepage/defrag
(たぶんカーネルによって異なるかもしれません。)
echo 'never' > /sys/kernel/mm/redhat_transparent_hugepage/defrag
最後に、このアプリケーションは数十ギガバイトのメモリを使用します。どの言語?
「メモリページエラー」という用語を使っていたので、運用設計や仮想メモリについては十分に慣れているようです。非常に深刻に失敗し、多くのI / Oを読み取ることができない状況/アプリケーションを想像するのは難しいです。ほとんど常に制限したいバッファキャッシュから読み込みます。
(気になる場合は、MAP_ANONYMOUSやMAP_POPULATEなどのmmap(2)フラグと、実際にどの仮想ページが物理ページをマップしているかを確認するために使用できるmincore(2)を確認してください。)
頑張ってください!