だから私のLinuxデスクトップでは、いくつかの大容量ファイルをローカルディスクまたはNFSマウントに書き込みます。
書き込むデータをキャッシュする一種のシステムバッファがあります。 (私のシステムのサイズは0.5-2GBの範囲だと思いますか?)
バッファがいっぱいになると、すべてのファイルアクセスがブロックされ、書き込みが完了するまでシステムは効果的に停止します。 (読み取りアクセスもブロックされていると確信しています。)
保証するには何を構成する必要がありますか?いいえ起こる?
私が望むもの:
プロセスがディスク(またはネットワークマウントなど)にデータを十分に高速に書き込めない場合そのプロセスディスクが追いつくまでブロックできますが、他のプロセスは依然として合理的な速度と待ち時間でデータを読み書きできます。どの邪魔する
理想的には、特定の種類のプログラム(cp、git、mplayer、firefoxなど)に対してdsikの総読み書き速度を設定できます。すべてのmplayerプロセスの総速度は、システムの残りの部分が実行する操作に関係なく、少なくとも10 MB / sです。「。でも」それにもかかわらず、すべてのmplayerインスタンスは全体の速度の少なくとも50%を受け取ります。「それは大丈夫です。(つまり、絶対比率を設定できるのか、総比率を設定できるのかはあまり関係ありません。)
さらに重要なのは、(最も重要な読み取り/書き込みが小さいため)同様のレイテンシ設定が必要なことです。繰り返しますが、何が起こっても単一プロセスの読み取り/書き込みが10ミリ秒以上(または何でも)システムの残りの部分をブロックしないことを保証します。理想的には「システムが何をしているかにかかわらず、mplayerは読み取り/書き込み操作を処理するために10ミリ秒以上待つ必要はありません。」。
これは、問題のプロセスがどのように開始されたか(実行中のユーザーなどを含む)に関係なく機能する必要があるためです。大きなCPをイオニスで包む「またはほとんど役に立たない他のものです。イオン化することを覚えておくと、特定のジョブが期待どおりにすべてを停止するのを防ぐことができますが、クローンジョブ、特定の実行中のデーモンのexec呼び出しなどはどうですか?
(最悪の犯罪者をいつもイオン化するシェルスクリプトで包むことができると思いますが、それにもかかわらず、ioniceのマニュアルページを検索してみると、それが提供する正確な保証が少し曖昧であるようになり、より体系的でメンテナンス可能な代替手段)。
答え1
通常、Linuxはキャッシュを使用してディスクに非同期にデータを書き込みます。ただし、書き込み要求と実際の書き込みとの間の時間間隔、または未書き込み(ダーティ)データの量が非常に大きくなる場合があります。この場合、競合はかなりのデータ損失を引き起こすため、ダーティキャッシュが大きくなるか古い場合、Linuxは同期書き込みに切り替えます。書き込み順序も遵守する必要があるため、キュー内のすべての以前の書き込みとは完全に独立しているという保証がなければ、小さなIOをバイパスすることはできません。したがって、書き込みに依存すると、膨大な遅延が発生する可能性があります。 (この依存関係はファイルシステムレベルでも発生する可能性があります。https://ext4.wiki.kernel.org/index.php/Ext3_Data%3DOrdered_vs_Data%3DWriteback_mode)。
私の考えでは、相関書き込みと組み合わせた一種のバッファ膨張を経験しているようです。大きなファイルに書き込んで大きなディスクキャッシュがある場合は、同期書き込みを完了するために多くのデータを書き込む必要があります。 LWNにはこの問題を説明する良い記事があります。https://lwn.net/Articles/682582/
スケジューラはまだ進行中の作業であり、新しいカーネルバージョンが登場すると状況が改善される可能性があります。ただし、これまではLinuxのキャッシュ動作に影響を与える可能性があるいくつかのスイッチがあります(そしてより多くのスイッチがあります。以下を参照してください)。https://www.kernel.org/doc/Documentation/sysctl/vm.txt):
- 汚い割合:利用可能なページと回収可能ページを含む合計使用可能メモリの割合を含みます。ディスクを作成するプロセスが書き込むページ数はダーティデータの書き込みを開始します。使用可能な合計メモリーは、合計システム・メモリーと同じではありません。
- 汚れた背景比:バックグラウンドカーネルリフレッシュスレッドがダーティデータの書き込みを開始するページ数を含みます(使用可能ページと回収可能ページを含む合計空きメモリの割合)。
- dirty_writeback_centisecs:カーネルフラッシュスレッドは定期的に起動し、「古い」データをディスクに書き込みます。この調整可能項目は、これらのスリープモード解除の間隔を100分の1秒単位で表します。 0 に設定すると、周期的な書き込み保存は完全に無効になります。
- dirty_expire_centisecs:この調整可能アイテムは、ダーティデータがカーネルフラッシュスレッドによって書き込まれるのに十分な時間を定義します。 1/100秒単位で表現されます。この間隔よりも長い間、メモリにダーティされたデータは、次にリフレッシュスレッドが起きたときに書き込まれます。
この場合、最大レイテンシを減らす最も簡単な解決策は、ダーティディスクキャッシュの最大量を減らし、バックグラウンドジョブを早期に作成することです。もちろん、大容量キャッシュが同期書き込みを防ぐことができない場合、パフォーマンスが低下する可能性があります。たとえば、/etc/sysctl.conf で以下を設定できます。
vm.dirty_background_ratio = 1
vm.dirty_ratio = 5
システムに適した値は、使用可能なRAM容量とディスク速度によって異なります。極端な状況では、上記の汚れた配給量は依然として大きくなる可能性があります。たとえば、空きRAMが100GiBでディスク書き込み速度が約100MiBの場合、上記の設定により最大ダーティキャッシュは5GiBになり、書き込みに約50秒かかることがあります。を使用すると、dirty_bytes
キャッシュさdirty_background_bytes
れた値を絶対に設定することもできます。
試してみるもう1つの方法はioスケジューラを切り替えることです。現在、カーネルバージョンには noop、Deadline、cfq があります。古いカーネルを使用している場合は、cfqと比較してデッドラインスケジューラでより良い反応時間を体験できます。ただし、テストする必要があります。あなたの場合はNoopを避けるべきです。 CFQに比べて待ち時間を減らすと主張する非メインラインBFQスケジューラもあります(http://algo.ing.unimo.it/people/paolo/disk_sched/)。ただし、すべてのディストリビューションに含まれるわけではありません。以下を使用して、実行時にスケジューラを確認して切り替えることができます。
cat /sys/block/sdX/queue/scheduler
echo <SCHEDULER_NAME> > /sys/block/sdX/queue/scheduler
最初のコマンドは、使用可能なスケジューラーと正確な名前の要約も提供します。注:この設定は再起動すると失われます。スケジュールを永久に選択するには、カーネルパラメータを追加するだけです。
elevator=<SCHEDULER_NAME>
状況はNFSに似ていますが、追加の問題があります。次の 2 つのバグレポートは、NFS の統計処理と大量のファイルの書き込みによって統計が非常に遅くなる理由に関する内部情報を提供できます。
https://bugzilla.redhat.com/show_bug.cgi?id=688232 https://bugzilla.redhat.com/show_bug.cgi?id=469848
更新:(2017年8月14日)
カーネル4.10では、新しいカーネルオプションCONFIG_BLK_WBT
とそのサブオプションが導入されました。カーネルがサイズと優先順位を制御できないハードウェアバッファによるバッファの膨張を防ぎます。BLK_WBT_SQ
CONFIG_BLK_WBT_MQ
Enabling this option enables the block layer to throttle buffered
background writeback from the VM, making it more smooth and having
less impact on foreground operations. The throttling is done
dynamically on an algorithm loosely based on CoDel, factoring in
the realtime performance of the disk
さらに、BFQ-Schedulerはカーネル4.12に基づいています。