これらの結果を再現する方法 - 重要な詳細

これらの結果を再現する方法 - 重要な詳細
  1. sudo dd if=/dev/sda of=/dev/null bs=1M iflag=direct
  2. atopsar -d 5 # in a second terminal
  3. top # in a third terminal

なぜなら。 。 。結果atopsar:

19:18:32  disk           busy read/s KB/read  writ/s KB/writ avque avserv _dsk_
...
19:16:50  sda             18%  156.5  1024.0     0.0     0.0   5.0   1.15 ms
19:16:55  sda             18%  156.3  1024.0     0.0     0.0   4.9   1.15 ms
...

報告されたディスク使用率(「使用中」)が100%よりはるかに低いのはなぜですか?

topこのプロセスはddCPUの3%以下しか使用していません。システムCPUのハードウェアおよびソフトウェアの割り込み(および)使用量に関する完全なレポートも提供され、top1%未満を示しています。 4つのCPU(それぞれ2つのスレッドを持つ2つのコア)があります。hisi

/dev/sdaSATAハードディスクです。 SSDでも、ハイブリッドSSHDドライブでもありません。読み取り速度は毎秒150MBを超えることはできません :-)。したがって、結果のこの部分は意味があります。 156 読み取り/秒 * 1024KB/読み取り = 156MB/秒

カーネルバージョンは5.0.9-200.fc29.x86_64(Fedora Workstation 29)です。 IOスケジューラはmq-deadlineカーネルバージョン5.0から始まり、マルチキューブロック層を使用します。単一のキューブロックレイヤが削除されたためです:-).

ディスク使用率の数値は、次のいずれかに基づいて計算atopsar -dされます。atopカーネル iostat フィールド。リンクされた文書には、「フィールド10 - I / Oの実行に費やされたミリ秒数」が記載されています。より詳細な定義がありますが、言及された機能がマルチキューブロック層にまだ存在するかどうかはわかりません。私が知る限り、atopsar -d両方をatop使うユニバーサルコードsar -diostat -xこのフィールドを読んでください10.( //このフィールドも使用すると思いますmxiostat.py

追加テスト

バリアント 2: に変更しbs=512k続けますiflag=direct

dd if=/dev/sda of=/dev/null bs=512k iflag=direct

19:18:32  disk           busy read/s KB/read  writ/s KB/writ avque avserv _dsk_
...
19:18:00  sda             35%  314.0   512.0     0.0     0.0   2.1   1.12 ms
19:18:05  sda             35%  313.6   512.0     0.2     4.0   2.1   1.11 ms

バリエーション 3: を使用しますbs=1Mが、取り外しはiflag=directdd10% の CPU と 35% のディスクを使用します。

dd if=/dev/sda of=/dev/null bs=1M

19:18:32  disk           busy read/s KB/read  writ/s KB/writ avque avserv _dsk_
...
19:21:47  sda             35%  242.3   660.2     0.0     0.0   5.4   1.44 ms
19:21:52  sda             31%  232.3   667.8     0.0     0.0   9.5   1.33 ms

これらの結果を再現する方法 - 重要な詳細

実行される最後のテストを参照してください。dd いいえ iflag=direct

ちょっと豚みたいですね。システム(マウスカーソル)が10秒以上停止するのを見たことがあります。スワップを無効にしても。 (RAM フィルテストゲイン/キャッシュ。非アクティブLRUのリストを入力しています。処理が完了すると、キャッシュされた非アクティブページは比較的迅速に削除されると思います。同時に、ディスクはシーケンシャル読み取りのためにページを処理する必要がある場合に時間がかかります。この状況がどれほど悪いかは、カーネルが最終的にアクティブなLRUリストを反転させるのか、それともあまりにも縮小するのかによって異なります。つまり、現在の状況はどうですか?「最先端のケースとさまざまな最適化を捉えるために、いくつかの修正とさまざまなアルゴリズムの組み合わせ」あなたの場合は動作します)。

これ精密最初のテスト結果は再現するのが難しいです。

時には代わりKB/readにマークされます。この場合、他の結果はの結果と似ています。とりわけ、ディスク使用率は約20%ではなく、約35%でした。どちらの場合も、私の質問は有効です。5121024bs=512k

この動作を理解するには、こちらをご覧ください。私のIOリクエストサイズが約512Kに制限されているのはなぜですか?

ベストアンサー1

これはカーネルバージョン5.0の変更の結果です。

ブロック:part_round_statsを削除してあまり正確でない計算に切り替える

私たちはこれをCPUごとにin_flightカウンタに変換したいと思います。

part_round_stats 関数には jiffy ごとに in_flight カウンタが必要で、 jiffy ごとにすべての CPU 変数を合計するコストが高すぎるため、削除する必要があります。 part_round_statsは、time_in_queueとio_ticksという2つのカウンタを計算するために使用されます。

time_in_queue は、I/O 終了時に I/O 持続時間を追加することで、 part_round_stats なしで計算できます。 (この値は、進行中のI / Oの時間が計算されないことを除いて、以前に計算された値とほぼ同じです。)。

io_ticks は、I/O が開始または終了し、 jiffies 値が変更されたときに値を増やしておおよその計算できます。 I / Oに1秒未満がかかる場合、この値は以前に計算された値と同じくらい正確です。 I / Oが1秒以上かかる場合、io_ticksは以前に計算された値より遅れることがあります。

(io_ticksのため部分統計の表示()、供給カーネルIO統計「フィールド10 - I / Oの実行に費やされたミリ秒数」の場合。 )

これは私の結果をよく説明します。 Fedora カーネル構成では、瞬間「1msです。コミットする大規模読​​み取りIOはdd1〜2秒以上待つことができると予想されます。特に古い機械式HDDを使用するシステムではさらにそうです。

以前のカーネルシリーズ4.20.xに戻ると、正しいディスク使用率が表示されます。

$ uname -r
4.20.15-200.fc29.x86_64
$ atopsar -d 5
...
13:27:19  disk           busy read/s KB/read  writ/s KB/writ avque avserv _dsk_
13:28:49  sda             98%  149.4  1024.0    13.0     5.3   2.2   6.04 ms
13:28:54  sda             98%  146.0  1024.0     7.2     5.7   1.5   6.38 ms

cfqこの古いカーネルは、デフォルトで既存のシングルキューブロック層とIOスケジューラを使用します。 IOスケジューラを使用した場合の結果は同じですdeadline


アップデート:カーネル5.7以降、この近似が調整されました。質問のコマンドは、再びディスク使用率を100%として表示します。より複雑なワークロードでは、新しい近似がクラッシュすると予想されます(まだ気付いていませんでしたが)。

block / diskstats:遅いディスクのio_ticksのより正確な近似

現在の jiffies カウンタが変更されている場合、io_ticks のおおよその値はリクエストの開始と終了ごとに 1 ずつ増加します。これは、1秒より短い要求、または1秒ごとに1つの要求が開始/終了する場合に便利です。

ディスクが一度に 1 つの要求のみを実行し、その要求が 2 桁よりも長い場合、最初と最後の紙幣のみが計算されます。

修正は簡単です。要求が終わったら、1つのjiffyの代わりにio_ticksの最後の更新以降に渡されたio_ticks jiffyを追加します。

例:通常のハードディスクがランダム読み取り4k要求を実行するのにかかる時間は約12msです。

fio --name=test --filename=/dev/sdb --rw=randread --direct=1 --runtime=30 & iostat -x 10 sdb

パッチの前後に iostat の "%util" が 8,43% -> 99,99% に変更されたことに注意してください。

今後:

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdb               0,00     0,00   82,60    0,00   330,40     0,00     8,00     0,96   12,09   12,09    0,00   1,02   8,43

後ろに:

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdb               0,00     0,00   82,50    0,00   330,00     0,00     8,00     1,00   12,10   12,10    0,00  12,12  99,99

io_ticksは要求の開始と終了の間の時間を短縮しませんが、キューの深さが1より大きい場合、隣接する開始間の一部のI / O時間が失われる可能性があります。

負荷推定の場合、「%util」は平均キュー長ほど有用ではありませんが、ディスクキューが完全に空である頻度を明確に示しています。

修正:5b18b5a(「ブロック:part_round_statsを削除し、正確な計算に切り替える」)
承認:Konstantin Khlebnikov <[Eメール保護]>
レビュー担当者:レイミング<[Eメール保護]>
署名者:Jens Axboe <[Eメール保護]>

おすすめ記事