...

Linuxカーネルにおけるライトバックキャッシュとダーティページを理解する

Linuxカーネルのライトバックキャッシュは、変更されたデータがいつ ダーティページ RAMに残るタイミングと、カーネルがそれらをまとめて記憶媒体に書き込むタイミングについて、この一連の流れを説明します。 パフォーマンス, 、レイテンシやデータセキュリティにどのような影響を与えるか、そして日常において本当に重要な制御要素は何か。.

中心点

  • ダーティページ 変更されたページのうち、まだデータ媒体に書き込まれていないものをRAM上でマークします。.
  • ライトバック 変更点をまとめて、より大きなブロック単位で効率的に書き込みます。.
  • しきい値 vm.dirty_ratioと同様に、処理速度とスロットリングを制御します。.
  • 同期 fsync/Flush を使用することで、データ損失を防ぐことができます。.
  • モニタリング /proc および各種ツールを通じて、負荷や遅延を表示します。.

ページキャッシュの仕組み

ファイルを読み込むと、カーネルがそのデータをページキャッシュに格納し、その後のアクセスはそこから行われる。 メモリ ディスクからではなく。書き込みの際、システムは変更されたページを ダーティ そして、アプリケーションが正常に動作し続けるよう、多くの場合その呼び出しを即座に完了させます。この分離により、処理速度の遅いI/Oアクセスがすべてのアプリケーションの動作を直接遅らせることはなくなるため、待ち時間が短縮されます。また、キャッシュは頻繁に利用されるブロックを保持しており、再アクセス時のヒット率を高めます。 さらに詳しく知りたい方は、私の概要記事で背景についてご確認ください。 ファイルシステムのキャッシュ, 、日常生活における読み取りパスと書き込みパスの役割を示すものです。.

「ダーティ・ページズ」:その意味と影響

「ダーティ・ページ」とは、変更されたがまだ永続的に保存されていないメモリページであり、したがって RAM 存在している。それらが汚れている限り、私はある程度の リスク: 停電が発生すると、これらの変更が破棄される可能性があります。それでも、カーネルが多数の小さな更新をまとめて処理するため、この方法の方が書き込みレートが高くなります。汚染されたページの割合が増えると、書き込み処理への負荷が高まります。その場合、システムは該当するページを優先的にドライブに書き込むことで、メモリを解放することができます。.

Writeback:トリガーと処理の流れ

Writebackは、スケジュール駆動、イベント駆動、およびオンデマンドで実行されます アプリ. カーネルはダーティページを束ね、適切なI/Oシーケンスを形成し、ブロックレイヤーを経由して 記憶装置. その過程で、ファイルシステム、リクレーマー、I/Oスケジューラが介入し、処理の順序やサイズを制御します。fsync のような同期呼び出しは、処理を続行する前に特定のデータが確実にメディアに書き込まれるように強制します。 アクティビティが高い時期には、統計データにおいてライトバックの割合が増加し、フラッシュ後に再び減少する傾向が見られます。.

内部メカニズム:balance_dirty_pages、BDI、およびWriteback-Worker

内部では、複数の構成要素が相互に連携しています。書き込みスレッドは以下を経由します balance_dirty_pages(), これは現在のダーティ・ロード、デバイスの速度、および設定された制限を考慮に入れます。これにより、バックグラウンドでのライトバックが追いつくよう、プロセスの書き込みレートを調整(スロットリング)します。各 バッキング・デバイス-コンテキスト(bdi)――通常はブロックデバイスまたはファイルシステム・バックエンド――は、独自のワークキューを持ち、 フラッシャー・スレッド, 、ダーティ・ページを整理されたI/Oリクエストに変換する。この分割により、低速なデバイスが他のすべてのデバイスの処理を遅らせることを防ぎ、ワークロード間の公平性を高める。.

このスロットリングは適応型です。書き込み処理が高速化したり、連続した領域が大きくなったりすると、許容されるダーティ量が一時的に増加します。 輻輳、高いレイテンシ、またはキューの飽和が発生した場合、カーネルはより積極的に抑制を行い、バッファに余裕が戻るまでライターに一時停止を強制します。まさにこの相互作用こそが、わずかなパラメータの変更が、レイテンシプロファイルに顕著な違いをもたらす理由を説明しています。.

しきい値:vm.dirty_background_ratio および vm.dirty_ratio

私は、汚染されたページの割合を相対的に制限する2つの重要な制限を設けることで、その挙動を制御しています。 RAM を定義する。この閾値を超えると、カーネルは 背景 書き込みを行う。この厳格な制限値に達すると、システムは十分なデータがフラッシュバックされるまで、書き込みを行っているプロセスの処理を制限します。これにより、個々のプログラムが大量の変更を生成した場合でも、ストレージは引き続き利用可能になります。 バイト単位の制限を使用する場合は、比率の値の代わりに、対応する *_bytes パラメータを設定します。.

表:関連するカーネルパラメータと指標

私は、ライトバック、レイテンシ、スループットを的確に制御し、可視化するために、いくつかの主要なスイッチを利用しています。以下の概要は、そのための参考になります。 分類 そして迅速な 審査.

パラメータ/指標 効果 初期値/注意事項
vm.dirty_background_ratio / vm.dirty_background_bytes 汚染されたページの割合がこの閾値を超えた場合、バックグラウンド・ライトバックを開始します。. サーバーの場合は、フラッシュがより早く開始されるよう、やや控えめな設定にする。.
vm.dirty_ratio / vm.dirty_bytes ダーティページの最大値。この値を超えると、ライターの処理が制限される。. 高すぎるとレイテンシのリスクが高まり、低すぎるとスループットを無駄にしてしまう。.
vm.dirty_writeback_centisecs カーネルがバックグラウンドフラッシュのためにダーティページをチェックする間隔。. 間隔を短くすると、負荷のピークは平滑化されますが、ウェイクアップの回数が増加します。.
vm.dirty_expire_centisecs 『Dirty Pages』が「執筆時期が到来した」とみなされ、優先的に執筆されるようになる年齢。. 値が大きいほど集約度は高くなりますが、エラーが発生した場合の一貫性保証は低下します。.
/proc/meminfo: ダーティ、ライトバック 現在、汚染されている、あるいはアクティブに書き戻されたページの件数。. 負荷テスト中のリアルタイム監視に役立ちます。.
マウント/FSオプション(例:バリア、ジャーナルモード) 個々のフラッシュの順序、持続時間、およびコストに影響を与えます。. ファイルシステムやデバイスに応じて、適切なものを選択してください。.

私はこれらの値を定期的に読み取り、topやiostatなどのツールで表示されるI/O待ち時間と照らし合わせています。 ツール. これにより、Writeback自体が制限されているのか、それとも ストレージ 限界にある。.

モニタリングと診断:測定項目

まず /proc/meminfo を確認し、「Dirty」と「Writeback」の項目を観察しながら、意図的に 負荷 生成する。ダーティが急上昇して高水準を維持する場合、適切なフラッシュが欠けているか、あるいは ミディアム がフル稼働している。ライトバックが増加しているにもかかわらず、ダーティがゆっくりとしか減少しない場合は、ターゲットデバイスまたはI/Oパスがボトルネックとなっている。レイテンシのピークがライトバックのピークと一致する場合は、インターバルを平滑化するか、比率の値を下げる。典型的なパターンを把握するには、簡単な ページキャッシュブースター, 、実用的な調整ネジと測定ポイントをまとめたものです。.

拡張測定ポイント、vmstat、およびトレース

/proc/meminfo のほか、原因と結果を区別するために、より詳細なカウンタも参照しています。 /proc/vmstat nr_dirty、nr_writeback、nr_dirtied、nr_written といったフィールドは、その動的な挙動を示しています。つまり、どのくらいの速さで「汚染」され、どのくらいの速さで「洗浄」されるのかということです。さらに、I/O キューの長さや、ブロックレイヤーにおけるマージ操作の中断率についても監視しています。.

  • vmstat 1:1秒あたりのダーティ/ライトバックのドリフトおよびI/O待機時間(wa)を表示し、,
  • /proc/pressure/memory:間接的にライトバックをトリガーするメモリプレッシャーを表示し、,
  • トレースポイント(writeback:*)およびブロックイベント:フラッシュの順序とサイズを明らかにし、,
  • perf/ftrace:balance_dirty_pages および Flusher ワークキュー内のホットスポットを特定します。.

nr_dirtied が nr_written より常に高い状態にあるのを見かけたら、それはスロットリングの圧力が迫っているか、バックグラウンドでのフラッシュ処理が遅れていることを示す明確な兆候です。 writebackトレースポイントのピークがレイテンシのピークと一致する場合は、インターバルとバッチサイズを最適化します。.

HDD 対 SSD:ライトバック設計への影響

回転するプレート上では、大規模で連続したフラッシュが特に大きな成果をもたらす。なぜなら、それらはコストのかかる探索を省くことができるからだ。 避ける. SSDも同様に恩恵を受けるが、ここでは書き込みの分散と、 コントローラー. ファームウェアが効率的に動作できるよう、過度な小規模な同期を回避しています。 同時に、SSDにおいては、デバイスの保証を最大限に活用できるよう、一貫性バリアやフラッシュの挙動に一層注意を払っています。ランダム読み取りと書き込みが混在するワークロードでは、ダーティ閾値やフラッシュタイミングの微調整によって、顕著なパフォーマンス向上が見られます。.

デバイスキャッシュ、フラッシュの挙動、および停電保護(PLP)

フラッシュが実際に持続するかどうかは、 デバイスのキャッシュ 。多くのドライブは、独自のDRAMにデータをバッファリングします。なし 電力損失保護(PLP) キャッシュが適時にクリアされない場合、データ損失のリスクが生じます。ライトバックはデバイスキャッシュの恩恵を受けますが、私はバリアやフラッシュ命令が確実に遵守されるようにしています。 RAIDコントローラを搭載したシステムでは、バッテリーバックアップまたはフラッシュバックアップ付きのキャッシュが存在するかどうかを評価します。その場合、セキュリティを犠牲にすることなく、同期書き込みの方が多くの場合、より有利になります。.

さらに、次のように区別します。FUA(Force Unit Access)はI/Oごとに永続化を強制しますが、IOPSを消費します。フラッシュ・バリアは、複数の書き込みをまとめて保存することができます。 特にクリティカルなパス(ジャーナルなど)については、FUAやフラッシュのオーバーヘッドを許容する一方で、バルクデータについてはライトバックストリームのままにしています。 マウントオプションやコントローラ設定を変更した場合は、その後、負荷テストを実施して、意図したフラッシュの挙動が正しく機能していることを確認してください。.

データの整合性:fsync、Flush、FUAの適切な活用

私は、特に高負荷のデータに対してfsyncを意図的に使用しています。 価値, 、明確な耐久性保証を必要とするもの。カーネルはフラッシュ操作をメディアまで実行し、FUA を通じて、書き込みが確実に 持続する, 、確認応答が返ってくる前に。この方法には時間とIOPSを要しますが、クラッシュ時のデータ損失を防ぐことができます。こうした障壁がなければ、バイトがまだSSDのキャッシュやRAMに残っているにもかかわらず、システムは成功と報告してしまいます。私はこれらの判断をアプリケーションに合わせて調整しています。トランザクションログはハードにバックアップし、バルク更新はソフトにバックアップします。.

ホスティングおよびDBワークロードのチューニング事例

Webサーバーやデータベースサーバーの場合、私はよく「dirty_background_ratio」を適度な値に設定し、「dirty_ratio」をそれを大幅に上回る値に保つことで、バックグラウンドフラッシュを適時に実行するようにしています。 スタート, 、シュライバーを早すぎる段階で ブレーキ. 書き込みが集中する状況では、ライトバック間隔を短くして、ライトバック処理がより早く実行されるようにしています。RAM容量の大きいシステムでは、パーセンテージではなく実際の数値が反映されるよう、*_bytes単位の値を優先しています。 変更のたびに再現性のあるベンチマークでテストを行い、レイテンシ、スループット、95パーセンタイルおよび99パーセンタイルを測定しています。ページキャッシュの効果に関する簡潔なガイドとして、以下の実践的な概要が参考になります: Linuxページキャッシュのパフォーマンス向上策.

ダイレクトI/Oとmmap:ページキャッシュがバイパスされる場合

すべてのアプリケーションがページキャッシュを同じように利用しているわけではありません。 O_DIRECT キャッシュを意図的にバイパスして、デバイスに直接書き込みや読み取りを行うことができます。これによりRAMへの負荷が軽減され、データ転送経路が短縮されますが、バッチ処理やリードアヘッドのメリットが失われてしまいます。大規模な単発の転送では有効かもしれませんが、多数の小さな書き込みを行う場合、ライトバックの利点が失われてしまいます。.

と一緒に ミマップ また、Copy-on-Write では、変更時にページを「ダーティ」としてマークし、フラッシュは通常のライトバックパスを通じて、あるいは msync. アプリケーションがメモリマッピングI/Oを多用する場合、この点を考慮に入れるようにしています。アプリが「単に」メモリに書き込んでいるだけの場合でも、予期せぬダーティピークが発生することがあるからです。ここでも、比率やバイト数による制限を設定することで、書き込みのタイミングを制御するのに役立ちます。.

コンテナ環境とcgroupのライトバック

マルチテナント環境では、以下の方法で「ノイジー・ネイバー」を防止しています。 cgroups. カーネルはダーティページを発生元グループに割り当て(cgroup-Writeback)、これによりバックグラウンドフラッシュとスロットリングがより公平に分散される。メモリ制限(メモリ.high, memory.max) を使用して、コンテナごとのダーティピークを制限しています。さらに、個々のワークロードによってデバイスのキュー全体が埋まってしまうのを防ぐため、I/O コントローラーを介して I/O クォータを設定しています。.

実際の運用では、サービスクラスごとに現実的な上限値を設定しています。書き込み負荷の高いバッチジョブには余裕のあるダーティ・バジェットを割り当て、レイテンシが重要なフロントエンドにはより厳しい制限を設けています。 これにより、個々のコンテナの動作が不安定になったとしても、Writebackがすべてのコンテナに対して一気に帯域を制限することはないため、全体的なレイテンシをより安定させることができます。.

ネットワークファイルシステム(NFS、SMB、分散ファイルシステム)

ネットワークファイルシステムの場合、さらに1つのバッファ段階が追加されます。ローカルのダーティページは、データが転送中であることを示すだけであり、それが リモート データが永続化されるかどうかは、プロトコル(コミットセマンティクス)とサーバーによって決定されます。 私は暗黙的なフラッシュには頼らず、重要なデータは明示的に同期させます。同時に、ラウンドトリップのコストにも配慮しています。ネットワーク経由での同期が頻繁すぎると、レイテンシが著しく悪化するためです。.

混合ワークロードでは、パスを分けています。ローカルの臨時ファイルはページキャッシュを最大限に活用し、ネットワークマウントにはより厳格な同期ポイントを設定しています。これにより、ローカルのジョブにはまだ余裕があるにもかかわらず、ネットワーク経由のライトバックがボトルネックになるのを防いでいます。.

I/Oスケジューラ、blk-mq、およびキューの深さ

Writebackバッチがデバイスにどれほど効率的に書き込まれるかは、 ブロックレイヤー から。~で blk-mq I/Oは複数のキューに分散されます。mq-deadlineやkyberなどのスケジューラが優先順位を付け、順序付けを行います。私はメディアに合わせてスケジューラを選択しています。NVMeでは「none」が適していることが多く、SATAやSASでは、Deadlineが書き込みの順序付けに役立ちます。.

キューの深さ 私は、デバイスがフル稼働しているものの、過負荷にならないように設定しています。深さが浅すぎるとスループットが低下し、深すぎるとレイテンシのばらつきが増大し、スロットリングが慢性化します。ライトバックは、適度な深さと、大規模で連続したリクエストによって効果を発揮します。 マージ率と「インフライト」カウンタを監視しています。マージ率が低下している場合は、バッチサイズが小さすぎるか、競合するランダムなワークロードが存在していることを示唆しています。.

再現性のあるテストと確実なロールバック

スライダーを動かす前に、現在の状態を確認し、テストを行います 再現可能 また、バックトレースも計画的に実施しています。テスト結果の比較が可能になるよう、同一のワークロードと同一のデータ量を使用し、キャッシュを意図的に温めたり、意図的にクリアしたりしています。設定の変更については、まず一時的に適用し、メトリクスを観察した上で、その後で恒久的に反映するようにしています。.

# の例:一時的なチューニング手順(root)
sysctl -w vm.dirty_background_bytes=$((512*1024*1024))
sysctl -w vm.dirty_bytes=$((2*1024*1024*1024))
sysctl -w vm.dirty_writeback_centisecs=100
sysctl -w vm.dirty_expire_centisecs=3000

# 短時間の負荷テスト(例、ワークロードに依存)
# fio --name=wbtest --filename=/data/testfile --size=8G --ioengine=libaio \
#     --rw=randwrite --bs=128k --iodepth=32 --direct=0 --numjobs=4 --runtime=60 --time_based

その間、/proc/meminfo、vmstat、iostatを並行して読み取り、ピーク値を相関分析します。テスト終了後は、値をリセットするか、システム設定に慎重に反映させます。その際、以下の内容を記録します。 日付, カーネル-バージョン、デバイスおよびファイルシステムの詳細。これにより、後日の比較でも信頼性を確保できます。.

よくある問題と対処法

システムの動作はスムーズに見えるのに、書き込み処理が滞る場合は、設定値が低すぎるためにスロットリングが発生していないか確認します。 ダーティレシオ. もしDirtyが高水準にとどまり続けるなら、帯域幅が不足するか、あるいはその インターバル フラッシュには時間がかかりすぎる。短い同期ストームでレイテンシが急増する場合は、負荷を小さなバッチに分割し、I/O計画を最適化することで対応する。キャッシュがなかなか活性化しない場合は、*_bytesの制限が小さすぎるために、適切なバッチ処理が行われていない可能性がある。さらに詳しく調べてみると、 印刷時のキャッシュエヴィクション 記憶容量の不足がさらに障害となる場合に役立ちます。.

ベストプラクティスと簡単なチェックリスト

私は、即座に書き込む必要があるデータと、書き込みを遅らせてもよいデータとを厳密に区別しています。その理由は、 パフォーマンス を獲得するためです。ログやトランザクションジャーナルについては同期を強制し、一時的なアーティファクトについてはライトバックを自由に実行させ、スロットリング制限のみを監視しています。 調整を行う前には毎回現状を測定し、定義済みのシナリオに基づいてA/B比較を行います。また、調整されていない書き込みの集中はバッチ処理の利点を損なうため、同時書き込み数を適切に抑制しています。さらに、将来の分析が明確な基準に基づいて行えるよう、変更内容は直ちに文書化しています。 データ をベースにしています。

実践的な要約で、短期間で成果を上げる

ライトバックキャッシュは、 ページ キャッシュは、I/Oコストを削減し、アプリケーションの負荷を軽減します。ダーティページはエラーではなく、制限や一貫性要件を把握している限り、パフォーマンスを向上させるための意図的な手段です。 vm.dirty_background_ratio および vm.dirty_ratio パラメータを使用することで、カーネルがバックグラウンドで静かに動作するタイミングと、書き込みを抑制するタイミングを調整できます。 各種ツールや /proc ディレクトリにより、ダーティページやライトバックに関する必要な可視性が得られ、手探り状態になることはありません。これらの調整手段をマスターすれば、Web アプリケーション、データベース、バッチジョブは、 誠実さ 私のデータを危険にさらすこと。.

現在の記事