
sudo dd if=/dev/sda of=/dev/null bs=1M iflag=direct
atopsar -d 5 # in a second terminal
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
このプロセスはdd
CPUの3%以下しか使用していません。システムCPUのハードウェアおよびソフトウェアの割り込み(および)使用量に関する完全なレポートも提供され、top
1%未満を示しています。 4つのCPU(それぞれ2つのスレッドを持つ2つのコア)があります。hi
si
/dev/sda
SATAハードディスクです。 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 -d
iostat -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=direct
約dd
10% の 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%でした。どちらの場合も、私の質問は有効です。512
1024
bs=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はdd
1〜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メール保護]>