私は異なる書き込みスループットを持つ複数のストレージデバイスを持つシステムで作業しています。質問の説明に従って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_bytes
50MBと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_ratio
udev
/etc/udev/rules.d/90-bdi-set-min_ratio-and-max_ratio.rules
root
# 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
です。この場合、モニタリングサブシステムに通知し、デバイスが追加または変更されるたびにルールと。==
=
udev
bdi
ATTR{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_bytes
dirty_background_bytes
2
min_ratio
max_ratio
dirty_bytes
dirty_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
のスクリプトはすべてのレベルに制限を適用します。これが最適かどうかはわかりません。基本デバイスにのみ制限を適用するのが最善です。