Page Cache Limit 機能は、Alibaba Cloud Linux 3 のカーネルバージョン 5.10.134-14 以降で提供されており、無制限のページキャッシュ使用によって引き起こされるシステムの不安定性の問題 (ビジネスのジッターや予期しない Out-of-Memory (OOM) エラーなど) を解決します。
背景情報
カーネルでは、メモリコントロールグループ (memcg) によって指定されたメモリの上限に達すると、メモリが割り当てられ、memcg 上で直接的なメモリ回収がトリガーされます。メモリの回収は、現在のプロセスのパフォーマンスに影響を与える可能性があります。この問題を解決するために、memcg バックエンド非同期回収機能が提供されています。しかし、この機能はバースト的なメモリリクエストに対してはあまり効果的ではありません。Spark フレームワークなどの特定のジョブが実行されている場合、大量のメモリがページキャッシュとして使用されます。ページキャッシュ内のほとんどのページはダーティページです。ダーティページの回収は遅いです。その結果、カーネルは動作を継続するのに十分なメモリを取得できず、予期せず OOM エラーが発生する可能性があります。ビジネスの安定性を確保し、予期しない OOM エラーを防ぐためには、ページキャッシュの使用量を制限する必要があります。
Alibaba Cloud Linux 3 は、ルート memcg を含む memcg のページキャッシュ使用量を制限するための Page Cache Limit 機能を提供します。Page Cache Limit 機能を使用して、ページキャッシュ使用量の制限を指定し、制限を超えた場合に超過したページキャッシュを非同期または同期的に回収できます。これにより、予想以上に大量のメモリがページキャッシュとして使用されるのを防ぎ、システムの安定性と信頼性を向上させます。
インターフェイス
インターフェイス | 説明 |
/sys/kernel/mm/pagecache_limit/enabled | カーネルで Page Cache Limit 機能をグローバルに有効にするかどうかを制御するスイッチ。有効な値: 0 および 1。デフォルト値: 0。
|
/sys/fs/cgroup/memory/<Memcg ディレクトリ名>/memory.pagecache_limit.enable | 特定の memcg に対して Page Cache Limit 機能を有効にするかどうかを制御するスイッチ。有効な値: 0 および 1。デフォルト値: 0。
|
/sys/fs/cgroup/memory/<Memcg ディレクトリ名>/memory.pagecache_limit.size | 特定の memcg の最大ページキャッシュ使用量。単位: バイト。有効な値: 0 から memcg に指定した
|
/sys/fs/cgroup/memory/<Memcg ディレクトリ名>/memory.pagecache_limit.sync | memcg がページキャッシュ使用量の制限を超えた場合に、非同期または同期の回収を実行するかどうかを制御します。有効な値: 0 および 1。デフォルト値: 0。 タスクのバーストによって非同期ワークキューが回収できるよりも速く多くのページキャッシュが生成された場合、ページキャッシュの数が一時的に
|
機能の仕組み
Page Cache Limit 機能を有効にすると、この機能は以下の原則に基づいて memcg 上で動作します。
memcg プロセスにページキャッシュが割り当てられると、この機能は現在の memcg がページキャッシュ使用量の制限を超えているかどうかを判断し、memcg から上方に走査して親 memcg の
memory.pagecache_limitの値を階層的にチェックします。親 memcg の memory.pagecache_limit の値が 0 の場合、その親 memcg では Page Cache Limit 機能は無効になります。その親 memcg とその子 memcg のページキャッシュ使用量は制限されません。現在の memcg がページキャッシュ使用量の制限を超えている場合、この機能は
memory.pagecache_limit.syncの値に基づいて同期または非同期の回収を実行するかどうかを決定します。この機能はページキャッシュを回収します。
同期回収: デフォルトでは、マップされていないファイルページのみが回収可能です。カーネルが 4 回以上のスキャンを実行すると、マップされたファイルページも回収可能になります。
非同期回収: デフォルトでは、マップされていないファイルページとマップされたファイルページが回収可能です。カーネルが 2 回以上のスキャンを実行すると、ダーティページも回収可能になります。
説明以下のメモリページが利用可能です。
マップされていないファイルページ: ファイルにマップされていないメモリページ。ほとんどの場合、これらのページは一時的なデータやプロセスを保持するメモリのプライベート領域であり、ディスクに永続化されません。
マップされたファイルページ: ファイルにマップされているメモリページ。これらのページにより、プロセスはメモリ内でファイルデータを読み書きでき、ファイルへのランダムアクセスが可能になります。
ダーティページ: 変更されたマップされたファイルページ。プロセスがマップされたファイルページにデータを書き込むと、そのページはダーティとしてマークされます。このマークは、メモリ内のファイルコピーが変更され、ディスク上のファイルとは異なることを示します。ダーティページは、データの永続性を確保するために定期的にディスクに書き戻されます。
インターフェイスの設定例
この例では、20 MiB のページキャッシュを作成し、ページキャッシュの使用量を 10 MiB に制限します。Page Cache Limit 機能を有効にした後、機能が期待どおりに動作するかどうかを確認します。
Elastic Compute Service (ECS) インスタンスに接続します。
詳細については、「ワークベンチを使用して Linux インスタンスにログインする」をご参照ください。
Page Cache Limit 機能をグローバルに有効にします。
sudo sh -c 'echo 1 > /sys/kernel/mm/pagecache_limit/enabled'Page Cache Limit 機能を有効にし、特定の memcg のページキャッシュ使用量を制限します。
memcg ディレクトリを作成します。例:
/sys/fs/cgroup/memory/test/。sudo mkdir -p /sys/fs/cgroup/memory/test/memcg のページキャッシュ使用量の制限を指定します。
この例では、memcg のページキャッシュ使用量制限を 10,485,760 バイト (約 10 MiB) に設定します。
sudo sh -c 'echo 10485760 > /sys/fs/cgroup/memory/test/memory.pagecache_limit.size'memcg のページキャッシュ回収スキームを設定します。
非同期回収スキームを使用するには、次のコマンドを実行します:
sudo sh -c 'echo 0 > /sys/fs/cgroup/memory/test/memory.pagecache_limit.sync'同期回収スキームを使用するには、次のコマンドを実行します:
sudo sh -c 'echo 1 > /sys/fs/cgroup/memory/test/memory.pagecache_limit.sync'
memcg の Page Cache Limit 機能を有効にします。
sudo sh -c 'echo 1 > /sys/fs/cgroup/memory/test/memory.pagecache_limit.enable'
ページキャッシュを作成します。
libcgroupパッケージをインストールします。ページキャッシュを作成するには
cgexecコマンドが必要です。ほとんどの場合、cgexecコマンドは libcgroup パッケージの一部として提供されており、インストールする必要があります。システムでcgexecコマンドが利用できない場合は、libcgroup パッケージをインストールしてください。sudo yum install libcgroup-toolsページキャッシュを作成します。
この例では、
ddコマンドを使用して、1 MiB のブロックを 20 回連続で書き込むことにより、20 MiB のページキャッシュを作成します。sudo dd if=/dev/zero of=./testfile bs=1M count=20 oflag=direct sudo cgexec -g "memory:test" cat ./testfile > /dev/null
Page Cache Limit 機能が期待どおりに動作するかどうかを確認します。
次のコマンドを実行して、ページキャッシュの使用量を確認します:
grep cache /sys/fs/cgroup/memory/test/memory.stat次のコマンド出力が返されます。

上記のコマンド出力では、
cacheはページキャッシュの使用量が 10,543,104 バイト (約 10 MiB) に制限されていることを示しています。Page Cache Limit 機能が期待どおりにページキャッシュを回収するかどうかを確認します。
cat /sys/fs/cgroup/memory/test/memory.exstat次のコマンド出力が返されます。

上記のコマンド出力では、
pagecache_limit_reclaimed_kbは 10,108 KB (約 10 MiB) のページキャッシュが回収されたことを示しています。検証結果は、20 MiB のページキャッシュが作成され、ページキャッシュの使用量が 10 MiB に制限されていることを示しています。ページキャッシュの使用量が制限を超えると、Page Cache Limit 機能によって期待どおりに 10 MiB のページキャッシュが回収されます。
説明pagecache_limit_reclaimed_kbの値が予想よりも高い場合、シーケンシャル読み取り操作中に先読みまたはプリフェッチされたデータ量が不適切で、ページキャッシュの過剰な回収が発生している可能性があります。echo 128 | sudo tee /sys/block/<ディスクデバイス名>/queue/read_ahead_kbコマンドを実行して、ディスクの read_ahead_kb パラメーターを設定することをお勧めします。この例では、ディスクデバイス名としてvdaが使用されます。read_ahead_kb パラメーターは、シーケンシャル読み取り操作中にカーネルが先読みまたはプリフェッチするキロバイト数を指定します。その後、Page Cache 機能を再度検証してください。