すべてのデバイスのデフォルトBDI `max_ratio`および/または `min_ratio`を変更するには?

すべてのデバイスのデフォルトBDI `max_ratio`および/または `min_ratio`を変更するには?

私は異なる書き込みスループットを持つ複数のストレージデバイスを持つシステムで作業しています。質問の説明に従って2013年に「USBフラッシュドライブの停止」の問題が発生したのはなぜですか?既存の「I / Oダーティスロットリングなし」コードがこの問題を解決できないのはなぜですか?デフォルトでは、Linuxでは、単一の低速デバイスが書き込みバッファリングのためにほぼすべてのディスクキャッシュを使用できるようにします。これにより、他のデバイスに書き込む場合でも、すべてのプロセスのパフォーマンスが低下します。プロセスがキャッシュ全体を書き込むために遅延を使用すると、void sync(void)状況はさらに悪化します。たとえば、プロセスが遅いUSBスティックにISOイメージを書き込むと、プロセスの開始からイメージ全体がカーネルキャッシュにある可能性があるため、最終的にISOイメージ全体がスローsync()USBスティックに書き込まれるのを待ちます。バー。

プロセス呼び出しがなくても、void sync(void)現在のシステム全体の書き込みキャッシュがバイトを超えると、すべてのプログラムが通常どおりバックグラウンド書き込みの代わりに同期書き込みを使用する必要があるため、すべてのプログラムが遅くなります/proc/sys/vm/dirty_background_bytes

単一(または並列に実行される複数)の低速ストレージデバイスがシステム全体の速度を遅くするのを防ぎ、この現象を防ぐことができることを願っています。私が知る限り、これを行うには、単一の低速デバイスに対する書き込みバッファのキャッシュ使用を制限する必要があります。キャッシュは、低速デバイスと高速デバイスがこれらのデバイスを使用するすべてのプロセスに対してボトルネックを引き起こすのに十分な大きさでなければなりませんが、基本構成で発生するように、そのプロセスは他のデバイスによって制限されません。

/proc/sys/vm/dirty_background_bytes50MBと200MBに制限すると、/proc/sys/vm/dirty_bytesシステムのレイテンシが大幅に悪くなることはありませんでしたが、遅いデバイスに書き込むときにまだ遅くなることがわかりました。 50MB以上のダーティキャッシュを使用すると、すべての書き込みが強制的に同期されるため、これが起こると思います。低速メモリに書き込むプロセスのキャッシュが52 MBで、他のプロセスが別の高速SSDデバイスに4KBファイルを書き込もうとすると、対応する4KB書き込みも同期する必要があり、SSDデバイスの速度が低下します。 RAMの速度で実行されるのではなく、速度が遅くなります。一方、非常に高速なSSDデバイスに書き込むと、データを生成するプロセスはキャッシュを埋めるほど高速ではないため、最大200MBの書き込みキャッシュが小さすぎる可能性があります。したがって、これらの2つの重要な設定を厳しく制限することは、最悪の待ち時間を避けながら、最適ではなく平均パフォーマンスを得るバランスを取ることです。

デバイスBDIをmax_ratioより小さい値に設定すると、100その値がそのデバイスで使用可能なフルライトキャッシュの割合として使用されることがわかります。

ただし、すべてのデバイスのデフォルト設定は、システムが遅いため100にシステム全体が遅くなることを許可することです。max_ratio以下のように値を設定すると、うまく機能し、100デバイスがすべてのキャッシュを無駄にすることができないため、デバイスが遅いデバイスによる速度低下を防ぐかどうかをテストしました。

今後接続するデバイスを含むすべてのデバイスにmax_ratio小さい値を設定するにはどうすればよいですか?100システムの起動中に実行され、接続されているすべてのデバイスを構成するスクリプトを作成できますが、新しく接続されたストレージ(USB、eSATA、またはその他の接続方法)はすべての書き込みキャッシュを取得できます。

答え1

max_ratioすべてのデバイスのルールを設定して使用できます。たとえば、コンテンツと共に次の名前の新しいファイルを作成できます。min_ratioudev/etc/udev/rules.d/90-bdi-set-min_ratio-and-max_ratio.rulesroot

# For every BDI device, set max cache usage to 30% and min reserved cache to 2% of the whole cache
ACTION=="add|change", SUBSYSTEM=="bdi", ATTR{min_ratio}="2", ATTR{max_ratio}="30"

(ファイルの構文は、現在の状態を確認してアクションを適用すること*.rulesです。この場合、モニタリングサブシステムに通知し、デバイスが追加または変更されるたびにルールと。===udevbdiATTR{min_ratio}="2"ATTR{max_ratio}="30"

ファイルが作成されたら、システムを再起動または実行してsudo udevadm trigger新しいルールを適用できます。 (これはUbuntu 18.04以降で動作し、コマンドをsudo udevadm control --reload-rules実行する前にいくつかの以前のバージョンを実行する必要があるかもしれません。)trigger

次のコマンドを使用すると、すべてのデバイスの現在の状態を確認できます。

$ grep . /sys/devices/virtual/bdi/*/{min,max}_ratio

上記の例の値(2と30)を使用すると、システムは特定のデバイスに対して少なくとも2%のキャッシュを予約し、単一のデバイスが最大許容キャッシュの最大30%を使用できるようにします。 3つのストレージデバイスがあり、これを50に設定すると、何が起こるのかわかりませんmin_ratio。論理的には、そのデバイスのキャッシュ領域全体の150%を予約する必要があるためです。これをテストする場合は、以下に説明を追加してください。

hugeや値の設定とどのようにやり取りするかをテストしていませんが、カーネルの動作をdirty_bytes正しく理解しても、dirty_background_bytes書き込みキャッシュに最小(+)/バイトまたはこの値の合計の50%が含まれるまで、これらの制限は適用されません。したがって、大規模なキャッシュが許可されている場合、非常に低い割合を設定すると、システムがキャッシュに多くのRAMを使用するのを実際に防ぐことはできません。コアが常に書き込みキャッシュに+合計の半分を使用すると仮定すると、残りの半分のバランスをとることができます。将来のカーネルではこの機能が改善される可能性がありますが、私が正しく理解している場合、カーネル開発者は現在の実装を使用して、すべてがスムーズに実行されるときに書き込みキャッシュのどの部分がどのデバイスで使用されるかを追跡するオーバーヘッドを減らします。dirty_bytesdirty_background_bytes2min_ratiomax_ratiodirty_bytesdirty_background_bytes

min_ratio遅いデバイスがそのデバイスの代わりにキャッシュを使用するのを防ぐために、パフォーマンスが実際に重要なすべてのデバイスのみを向上させることをお勧めしますが、カーネルの動作をよりよく理解するには、より多くのベンチマークが必要です。私が選択したmax_ratio値は、30最大3つの遅いデバイスが並列に動作できるようにし、まだ高速デバイスで使用できるキャッシュの10%を持ちます(まだ帯域幅に制限はありません)。カーネルはデフォルトでキャッシュの半分を使用し、残りの半分max_ratioのバランスを維持するため、事実上制限は0.5 + 0.5 * 0.3または単一の低速デバイスで許可される最大ディスクキャッシュの約65%に設定されます。

パーティションまたはデバイス全体にBDI制限を適用できます。 RAIDの場合、RAID内の個々のパーティション、RAIDデバイス全体、またはRAID内の個々のデバイスにBDI制限を適用できるとします。上記udevのスクリプトはすべてのレベルに制限を適用します。これが最適かどうかはわかりません。基本デバイスにのみ制限を適用するのが最善です。

関連情報