Linuxバックグラウンドフラッシュの制限(ダーティページ)


26

Linuxでのバックグラウンドフラッシュは、書き込まれたデータが多すぎる(/ proc / sys / vm / dirty_background_ratioで調整可能)か、保留中の書き込みのタイムアウトに達した(/ proc / sys / vm / dirty_expire_centisecs)場合に発生します。別の制限(/ proc / sys / vm / dirty_ratio)に達していない限り、より多くの書き込みデータがキャッシュされる場合があります。それ以上の書き込みはブロックされます。

理論的には、これにより、他のプロセスに影響を与えることなく、ダーティページを書き込むバックグラウンドプロセスが作成されるはずです。実際には、キャッシュされていない読み取りまたは同期書き込みを行うプロセスを妨害します。ひどく。これは、バックグラウンドフラッシュが実際に100%のデバイス速度で書き込みを行い、この時点で他のデバイスリクエストが遅延するためです(道路上のすべてのキューと書き込みキャッシュがいっぱいになるため)。

フラッシュプロセスが実行する1秒あたりの要求量を制限する方法、または他のデバイスI / Oを効果的に優先する方法はありますか?


多分これは、Linuxカーネルメーリングリストに送信するには良い質問だろうvger.kernel.org/vger-lists.html#linux-kernel

どのIOスケジューラを使用していますか?
3dinfluence

いろいろ試してみました(cfq、deadline)が、これらはバッテリバックアップ式の書き込みキャッシュが含まれていない場合にのみ確実に機能すると思います。1つのディスクアレイのように、PCIeバス速度(RAM)で1 GiBのデータを消費し、現実の壁にぶつかった。すべてのLUNの数秒のゼロI / O。フラッシュ(少なくともバックグラウンドフラッシュ)を実際のデバイス速度の大まかな推定値に調整すると、その輻輳問題が解決します。
コルクマン

1
最近、/ sys / block / sdX / queue / nr_requestsが主要な調整可能パラメータであることに気付きました。最小値(私の場合は4)に下げると、同時ロードレイテンシーが大幅に改善されます。Sysbenchのfsyncランダム書き込み/秒は、ddでバス速度で書き込み中に4(!)から80-90にジャンプしました。ロードされていないパフォーマンスは影響を受けないようです。スケジューラーはすべて同じで、何もしないか期限が最適だと思われます。これは、ほとんどのBBWC構成に当てはまる場合があります。
コルクマン

回答:


20

sysbenchで多くのベンチマークを行った後、次の結論に達しました。

(パフォーマンス面で)状況を生き残るために

  • 邪悪なコピープロセスがダーティページをあふれさせる
  • ハードウェア書き込みキャッシュが存在します(おそらくそれもありません)
  • 同期読み取りまたは書き込み/秒(IOPS)が重要です

エレベータ、キュー、ダーティページキャッシュをすべてダンプするだけです。ダーティページの正しい場所は、そのハードウェア書き込みキャッシュのRAMです。

dirty_ratio(または新しいdirty_bytes)をできる限り低く調整しますが、シーケンシャルスループットに注意してください。私の場合、15 MBが最適でした(echo 15000000 > dirty_bytes)。

ダーティキャッシュではなく、ギガバイトのRAMが読み取りキャッシュにのみ使用されるようになったため、これはソリューションというよりはハックです。この状況でダーティキャッシュが適切に機能するためには、Linuxカーネルバックグラウンドフラッシャーは、基になるデバイスが要求を受け入れる速度で平均化し、それに応じてバックグラウンドフラッシュを調整する必要があります。簡単ではありません。


比較のための仕様とベンチマーク:

ながら試験ddディスクにゼロをINGの」sysbenchを示した大成功を 8から400までの単一スレッドIOPS:33から700 IOPS(1500 IOPSアイドル限界)に16キロバイトで書き込みFSYNC 10個のスレッドを高めます。

負荷がなければ、IOPSは影響を受けず(〜1500)、スループットはわずかに低下しました(251 MB / sから216 MB / sへ)。

dd コール:

dd if=/dev/zero of=dumpfile bs=1024 count=20485672

sysbenchの場合、test_file.0は次のようにスパースされないように準備されました。

dd if=/dev/zero of=test_file.0 bs=1024 count=10485672

10スレッドのsysbench呼び出し:

sysbench --test=fileio --file-num=1 --num-threads=10 --file-total-size=10G --file-fsync-all=on --file-test-mode=rndwr --max-time=30 --file-block-size=16384 --max-requests=0 run

1つのスレッドのsysbench呼び出し:

sysbench --test=fileio --file-num=1 --num-threads=1 --file-total-size=10G --file-fsync-all=on --file-test-mode=rndwr --max-time=30 --file-block-size=16384 --max-requests=0 run

ブロックサイズを小さくすると、さらに劇的な数値が示されました。

--file-block-size = 4096、1 GBのdirty_bytes:

sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
1 files, 10Gb each
10Gb total file size
Block size 4Kb
Number of random requests for random IO: 0
Read/Write ratio for combined random IO test: 1.50
Calling fsync() after each write operation.
Using synchronous I/O mode
Doing random write test
Threads started!
Time limit exceeded, exiting...
Done.

Operations performed:  0 Read, 30 Write, 30 Other = 60 Total
Read 0b  Written 120Kb  Total transferred 120Kb  (3.939Kb/sec)
      0.98 Requests/sec executed

Test execution summary:
      total time:                          30.4642s
      total number of events:              30
      total time taken by event execution: 30.4639
      per-request statistics:
           min:                                 94.36ms
           avg:                               1015.46ms
           max:                               1591.95ms
           approx.  95 percentile:            1591.30ms

Threads fairness:
      events (avg/stddev):           30.0000/0.00
      execution time (avg/stddev):   30.4639/0.00

--file-block-size = 4096、15 MBのdirty_bytes:

sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
1 files, 10Gb each
10Gb total file size
Block size 4Kb
Number of random requests for random IO: 0
Read/Write ratio for combined random IO test: 1.50
Calling fsync() after each write operation.
Using synchronous I/O mode
Doing random write test
Threads started!
Time limit exceeded, exiting...
Done.

Operations performed:  0 Read, 13524 Write, 13524 Other = 27048 Total
Read 0b  Written 52.828Mb  Total transferred 52.828Mb  (1.7608Mb/sec)
    450.75 Requests/sec executed

Test execution summary:
      total time:                          30.0032s
      total number of events:              13524
      total time taken by event execution: 29.9921
      per-request statistics:
           min:                                  0.10ms
           avg:                                  2.22ms
           max:                                145.75ms
           approx.  95 percentile:              12.35ms

Threads fairness:
      events (avg/stddev):           13524.0000/0.00
      execution time (avg/stddev):   29.9921/0.00

--file-block-size = 4096、アイドルシステム上の15 MBのdirty_bytes:

sysbench 0.4.12:マルチスレッドシステム評価ベンチマーク

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
1 files, 10Gb each
10Gb total file size
Block size 4Kb
Number of random requests for random IO: 0
Read/Write ratio for combined random IO test: 1.50
Calling fsync() after each write operation.
Using synchronous I/O mode
Doing random write test
Threads started!
Time limit exceeded, exiting...
Done.

Operations performed:  0 Read, 43801 Write, 43801 Other = 87602 Total
Read 0b  Written 171.1Mb  Total transferred 171.1Mb  (5.7032Mb/sec)
 1460.02 Requests/sec executed

Test execution summary:
      total time:                          30.0004s
      total number of events:              43801
      total time taken by event execution: 29.9662
      per-request statistics:
           min:                                  0.10ms
           avg:                                  0.68ms
           max:                                275.50ms
           approx.  95 percentile:               3.28ms

Threads fairness:
      events (avg/stddev):           43801.0000/0.00
      execution time (avg/stddev):   29.9662/0.00

テストシステム:

  • Adaptec 5405Z(保護付きの512 MB書き込みキャッシュ)
  • Intel Xeon L5520
  • 6 GiB RAM @ 1066 MHz
  • マザーボードSupermicro X8DTN(5520チップセット)
  • Seagate Barracuda 1 TBディスク12個
    • LinuxソフトウェアRAID 10の10
  • カーネル2.6.32
  • ファイルシステムxfs
  • Debian不安定版

要約すると、この構成は、そうでなければシーケンシャルトラフィックによって枯渇してしまうデータベーストラフィックのアイドル、高負荷、さらには全負荷の状況でも良好に機能するはずです。とにかく2つのギガビットリンクが提供できるシーケンシャルスループットよりも高いので、少しでも問題はありません。


「dirty_buffersの15MBが最適」部分に到達するための方法論は何ですか?
マーチン

1
試行錯誤。たとえば、次回は半分に変更するなど、たった15 MBでOK IOPSになります。現在のカーネル3.2の動作は、BTWとは大きく異なる場合があります。
コルクマン

2
私を正しい方向に導いてくれてありがとう。XenServerノードで同様の問題がいくつかありました。PHP-FPM / APCキャッシュであることが判明し、ダーティページが発生しました。APCキャッシュメモリモデルを調整すると、問題が解決しました。DiskIOの使用率が20%から0になりました
。– jeffatrackaid

論理的にdirty_bytesは、プロセスがデバイスのスループットで平均して書き込みを行っている場合、プロセスの書き込み中にCPUをストールさせないように十分に高くする必要があります。アプリケーションコードが大量のデータの書き込みを伴う巨大な計算のサイクルを実行している場合、短時間の平均は長時間の平均と大きく異なるため、最適化は非常に困難です。正しい解決策はプロセス固有のdirty_bytes設定を調整することですが、Linuxは私の知る限りそのようなことをサポートしていません。
ミッコランタライネン

3

カーネルパラメーターの調整で問題が停止した場合でも、パフォーマンスの問題は、2012年2月1日のファームウェア更新で修正されたAdaptec 5405Zコントローラーのバグの結果である可能性があります。リリースノートには、「I / O負荷が高いときにファームウェアがハングする可能性がある問題を修正した」と書かれています。おそらくあなたが行ったようにI / Oを広げることで、このバグが引き起こされるのを防ぐのに十分でしたが、それは単なる推測です。

リリースノートは次のとおりです。http//download.adaptec.com/pdfs/readme/relnotes_arc_fw-b18937_asm-18837.pdf

これがあなたの特定の状況に当てはまらなかったとしても、これは将来この投稿に出くわすユーザーに利益をもたらすと考えました。dmesgの出力で次のようなメッセージが表示され、最終的にファームウェアの更新に至りました。

aacraid: Host adapter abort request (0,0,0,0)
[above was repeated many times]
AAC: Host adapter BLINK LED 0x62
AAC0: adapter kernel panic'd 62.
sd 0:0:0:0: timing out command, waited 360s
sd 0:0:0:0: Unhandled error code
sd 0:0:0:0: SCSI error: return code = 0x06000000
Result: hostbyte=DID_OK driverbyte=DRIVER_TIMEOUT,SUGGEST_OK
sd 0:0:0:0: timing out command, waited 360s
sd 0:0:0:0: Unhandled error code
sd 0:0:0:0: SCSI error: return code = 0x06000028
Result: hostbyte=DID_OK driverbyte=DRIVER_TIMEOUT,SUGGEST_OK
sd 0:0:0:0: timing out command, waited 360s
sd 0:0:0:0: Unhandled error code
sd 0:0:0:0: SCSI error: return code = 0x06000028

高いI / Oハング修正を備えたファームウェアのリリースノートにリストされているAdaptec RAIDコントローラのモデル番号は次のとおりです。2045、2405、2405Q、2805、5085、5405、5405Z、5445、5445Z、5805、 5805Q、5805Z、5805ZQ、51245、51645、52445。


1
わあ、ご意見ありがとうございます。これは私には当てはまりませんでしたが、HW RAIDを完全に回避し、HBAのみのセットアップに進むもう1つの理由を教えてください。HW RAIDにはまだBBWCの利点がありますが、bcacheのようなものがカーネルに移行すると、それも消えます。HW RAIDの考慮事項は、まさにあなたが説明する種類のファームウェアバグです。私はDRBDセットアップとファームウェアリセットを引き起こす高I / O負荷を備えた別のシステムを持っていたので、これは遭遇することは珍しくありません(まさにそのバグであったかもしれません)。
コルクマン14年

1

「WBT」を含むカーネル:

ブロック層の改善、LWN.net

ライトバックスロットリングでは、[ブロックレイヤー]はCoDelネットワークスケジューラーから借用した戦略を使用して、過度のI / Oレイテンシなしで最大のパフォーマンスを得ようとします。CoDelは、観測されたネットワークパケットの最小遅延を追跡し、それがしきい値を超えると、パケットのドロップを開始します。I / Oサブシステムでは書き込みのドロップが嫌われますが、カーネルが読み取りと書き込みの両方の最小レイテンシを監視し、それがしきい値を超えるとバックグラウンドライトバックの量を減らし始めるという点で同様の戦略に従いますそれが行われています。この動作は4.10で追加されました。Axboeは、かなり良い結果が見られたと言いました。

WBTでは、新しいblk-mqブロックレイヤーに切り替える必要はありません。ただし、CFQまたはBFQ I / Oスケジューラーでは機能しません。deadline / mq-deadline / noop / noneスケジューラでWBTを使用できます。新しい「kyber」I / Oスケジューラーでも機能すると思います。

待機時間を制御するためにキューサイズをスケーリングするだけでなく、WBTコードは、計算されたキュー制限の割合としてバックグラウンドライトバック要求の数を制限します。

ランタイム構成はにあり/sys/class/block/*/queue/wbt_lat_usecます。

検索するビルド構成オプションは次のとおりです。

/boot/config-4.20.8-200.fc29.x86_64:CONFIG_BLK_WBT=y
/boot/config-4.20.8-200.fc29.x86_64:# CONFIG_BLK_WBT_SQ is not set
/boot/config-4.20.8-200.fc29.x86_64:CONFIG_BLK_WBT_MQ=y

あなたの問題の声明はWBTの作者によって100%確認されています-よくやった:-)。

[PATCHSET]ブロック:バッファリングされたライトバック調整

d明期から、バックグラウンドのバッファリングされたライトバックは吸い込まれました。バックグラウンドでバッファリングされたライトバックを行う場合、フォアグラウンドアクティビティへの影響はほとんどありません。これがバックグラウンドアクティビティの定義です...しかし、覚えている限り、バッファ付きのライターはそのように振る舞っていません。たとえば、次のようなことをすると:

$ dd if=/dev/zero of=foo bs=1M count=10k

私のラップトップで、クロムを試して起動すると、バッファされたライトバックが完了する前に基本的に起動しません。または、サーバー指向のワークロードの場合、大きなRPM(または同様の)のインストールがデータベースの読み取りまたは同期の書き込みに悪影響を及ぼします。それが起こると、私は人々に怒鳴られます。

最近のいくつかのテストの結果はここにあります:

https://www.facebook.com/axboe/posts/10154074651342933

パッチセットの詳細については、以前の投稿を参照してください。


この問題がカーネル内で認識され、対処されているのを見てうれしいです。blk-mqはかなり新しく、まだ成熟してない可能性があることに留意してください。
コルクマン

@korkmanため息、間違った意味合いを避けるために引用をマングルします。私はこれがここ数年で追加されたものであることに同意しますが、それでもパフォーマンスの低下またはそれ以上の可能性があります。メンテナーAFAIRは、それがまぐれであるという意味で、データ破損の修正を却下します。 blk-mqが開発されたカーネルバージョンを使用している場合、「レガシー」ブロックレイヤーを使用することでバグを回避できることは間違いありません。私が修正したサスペンドバグはblk-mqに起因するバグでしたが、その後リファクタリングされるか、何らかの影響を受け、両方に影響しました。 github.com/torvalds/linux/commit/1dc3039bc87a
sourcejedi

0

/ proc / meminfoのDirtyの平均は?通常、これは/ proc / sys / vm / dirty_ratioを超えることはありません。専用のファイルサーバーでは、dirty_ratioを非常に高い割合のメモリ(90)に設定していますが、これを超えることはありません。dirty_rationが低すぎるため、ヒットするとすべてがガタガタと上がります。


問題は、dirty_ratioをヒットしたときにプロセスがブロックされないことです。大丈夫です。ただし、ディスクにダーティデータを書き込む「バックグラウンド」プロセスは、容赦なくキューをいっぱいにし、IOPSパフォーマンスを低下させます。IO飢vと呼ばれます。実際、dirty_ratio_bytesを非常に低く設定すると(1 MBなど)、多くの場合に役立ちます。フラッシュがほぼすぐに発生し、キューが空のままになるためです。欠点は、シーケンシャルのスループットが低下する可能性がありますが、それでかまいません。
コークマン

すべてのエレベーターをオフにしましたか?バニラシステムから他に何を調整しましたか?
ルーク

1
私の自己回答をご覧ください。ストーリーの最後は、ダーティキャッシングを削除し、その部分をハードウェアコントローラーに任せることでした。エレベーターは、HW書き込みキャッシュが適切に配置されているとは無関係です。コントローラーには独自のエレベータアルゴリズムがあるため、ソフトウェアでエレベータを使用してもオーバーヘッドが増えるだけです。
コルクマン

ソフトウェアのエレベーターはトレードオフです。帯域幅を改善するためにレイテンシーを犠牲にします。たとえば、ランダムな順序で送信されたソフトウェアキューでの100Kの書き込み操作を想像してください。ソフトウェアエレベータが巨大なバッファを使用してこれらのopを注文できる場合、デバイスに送信されるリクエストははるかに大きい5Kだけになります。ただし、結果として、最初の2K opsと最後の1K opsがデバイス上で実際に互いに近いため、レイテンシを100K ops増やす必要があります。遅延を追加しないと、それらをマージすることはできません。
ミッコランタライネン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.