HackToTech

Hack To Technology

BPF本を読みながら学ぶ9

9章、 ディスクI/Oについて

目次

blkparse

Trace Actions 説明
C Complete 以前に発行したリクエストが完了した
D Issued ブロックレイヤーのキューまたはI/Oスケジューラに存在していたリクエストがドライバへ発行された
I Inserted 内部キューへの追加とドライバによる後のサービスのためにI/Oスケジューラにリクエストを送信した
Q Queued I/Oをキューに入れようとしている
実際のリクエストはまだ存在しない
B Bounced データページがハードウェアから到達できないため、より低いメモリロケーションへバウンスする必要がある
これにより、データをカーネルバッファとの間でコピーする必要がある為、I/Oパフォーマンスが大幅に低下する
M Back merge I/Oの開始から終了までの間に以前にインサートされたリクエストが存在する為、I/Oスケジューラはそれらをマージできる
要するに順番通りにくっつけて処理する感じ
F Front merge バックマージと同じ
以前にインサートされたリクエストが開始されるところで、このI/Oが終了する点を除く
要するに順番を入れ替えてくっつけて処理する感じ
M Front or Back merge そのまま
G Get request 任意のタイプのリクエストをブロックデバイスに送信するには、初めに構造体のリクエストコンテナを割り当てる必要がある
S Sleep 利用可能なリクエストの構造体がなかった為、発行者はリクエストの構造体が解放されるのを待つ必要がある
P Plug 空のブロックデバイスキューにI/Oがキューイングされる前に、Linuxはデータが必要になって将来的にキューにI/Oが追加されることを予想してキューにプラグを差し込む
U Unplug デバイスにいくつかのリクエストデータがキューイングされていて、ドライバへリクエストの送信を開始する
タイムアウトの期間を経過した場合、もしくは多くのリクエストがキューに追加された際に自動的に発生する場合がある
T Unplug due to timer キューにプラグを差し込んだあとに、I/Oを要求するリクエストがない場合、Linuxは定義された期間が経過した後、自動的にプラグを取り外す
X Split RAIDもしくはデバイスマッパーの仕組みでは、インカミングI/Oがデバイスもしくは内部ゾーンにまたがるケースがあり、サービスのために細かく分割するひつようがある
RAID/デバイスマッパーの仕組みが不適切であるために、パフォーマンスの問題が発生していることを示す場合もあるが、通常の境界条件の一部にすぎない場合もある
A Remap スタックされたデバイスの場合、インカミングI/Oは、I/Oスタックでリマップされる
リマップアクションは、何が何にリマップされているかを詳細に示す

参考

rwbs

R Read
W Write
M Meta-data
S Synchronous
A Read-Ahead
F Flush or Force Unit Access
D Discard
E Erase
N No data

参考

I/Oスケジューラ

  • クラシックスケジューラ
    • Noop
      • スケジューリングを行わない(要するにリクエスト順に処理する)
    • Deadline
      • レイテンシのデッドライン(ミリ秒単位で指定)を強制しようとする(リアルタイムシステムで望ましい)
      • レイテンシの外れ値が防げる(スタベーション)
    • CFQ
      • CPUのスケジューリングと同様にI/Oタイムスライスを割り当てる
  • マルチキュースケジューラ
    • BFQ
      • 遅いI/Oデバイスでも良好なレスポンスを返せる
      • 遅いCPUもしくは、高スループットのデバイスには不向き
      • でかいアプリケーションをロードするときに有用
    • kyber
      • 高速なマルチキューデバイスように設計されている
      • 2つのリクエストキューが存在する
        • 同期リクエストキュー
        • 非同期リクエストキュー
    • none
      • スケジューリングを行わない
      • NVMEとかの高速ランダムI/Oデバイスに向いている
    • mq-deadline
      • マルチキューデバイス向けのデッドラインI/Oスケジューラ
      • CPUオーバーヘッドがかなり低いため、オールラウンダー

ディスクI/Oのパフォーマンス分析

  1. ディスクのパフォーマンス分析から始める
  2. 基本的なディスクメトリクスを確認する(リクエストタイム, IOS, Utilization)
  3. 正常な状態がわからない場合はfioとかで計測する
  4. I/Oのレイテンシの分布を確認し、マルチモーダル分析と外れ値を確認する
    biolatency
  5. 個々のI/Oをトレースし、パターンを探る
    biosnoop
  6. bpftraceを使用する

blktrace

ブロックデバイスのライブトレースを実行する

フィールド

デバイスのメジャー,マイナーバージョン
CPU ID
シーケンス番号
タイムスタンプ(秒)
プロセスID
トレースアクション(ID) blkparse
RWBS rwbs
アドレス/サイズ[デバイス]
❯ sudo btrace /dev/sda1
  8,0    1        1     0.000000000 14725  A  WS 15475728 + 8 <- (8,1) 15473680
  8,1    1        2     0.000000479 14725  Q  WS 15475728 + 8 [ThreadPoolForeg]
  8,1    1        3     0.000006639 14725  G  WS 15475728 + 8 [ThreadPoolForeg]
  8,1    1        4     0.000007478 14725  P   N [ThreadPoolForeg]
  8,1    1        5     0.000008846 14725  U   N [ThreadPoolForeg] 1
  8,1    1        6     0.000009364 14725  I  WS 15475728 + 8 [ThreadPoolForeg]
  8,1    1        7     0.000026680 14725  D  WS 15475728 + 8 [ThreadPoolForeg]
  8,1    1        8     0.000198604  4914  C  WS 15475728 + 8 [0]
  8,0    1        9     0.000237768   422  A  WS 17113736 + 8 <- (8,1) 17111688
  8,1    1       10     0.000238263   422  Q  WS 17113736 + 8 [jbd2/sda1-8]
  8,1    1       11     0.000240262   422  G  WS 17113736 + 8 [jbd2/sda1-8]
  8,1    1       12     0.000240623   422  P   N [jbd2/sda1-8]
  8,0    1       13     0.000240940   422  A  WS 17113744 + 8 <- (8,1) 17111696
  8,1    1       14     0.000241052   422  Q  WS 17113744 + 8 [jbd2/sda1-8]
  # 省略
  8,1    1       79     0.000250469   422  U   N [jbd2/sda1-8] 1
  8,1    1       80     0.000250716   422  I  WS 17113736 + 184 [jbd2/sda1-8]
  8,1    1       81     0.000252183   422  D  WS 17113736 + 184 [jbd2/sda1-8]
  8,1    1       82     0.000475940  4914  C  WS 17113736 + 184 [0]
  8,0    1       83     0.000501828   422  A FWFS 17113920 + 8 <- (8,1) 17111872
  8,1    1       84     0.000502301   422  Q  WS 17113920 + 8 [jbd2/sda1-8]
  8,1    1       85     0.000503486   422  G  WS 17113920 + 8 [jbd2/sda1-8]
  8,1    1       86     0.000504014   422  I  WS 17113920 + 8 [jbd2/sda1-8]
  8,1    1       87     0.000510367   370  D  WS 17113920 + 8 [kworker/1:1H]
  8,1    1       88     0.000614921  4914  C  WS 17113920 + 8 [0]
  8,0    1       89     0.196179477 14725  A  WS 411398904 + 8 <- (8,1) 411396856
  8,1    1       90     0.196180172 14725  Q  WS 411398904 + 8 [ThreadPoolForeg]
  8,1    1       91     0.196184976 14725  G  WS 411398904 + 8 [ThreadPoolForeg]
  8,0    3        1     0.615787407 15059  A  WS 15475728 + 8 <- (8,1) 15473680
  8,1    3        2     0.615788204 15059  Q  WS 15475728 + 8 [ThreadPoolForeg]
  8,1    3        3     0.615792400 15059  G  WS 15475728 + 8 [ThreadPoolForeg]
  8,1    3        4     0.615793068 15059  P   N [ThreadPoolForeg]
  8,0    3        5     0.615809324 15059  A  WS 15475736 + 8 <- (8,1) 15473688
  8,1    3        6     0.615809496 15059  Q  WS 15475736 + 8 [ThreadPoolForeg]
  8,1    3        7     0.615810115 15059  M  WS 15475736 + 8 [ThreadPoolForeg]
  8,1    3        8     0.615811006 15059  U   N [ThreadPoolForeg] 1
  8,1    3        9     0.615811499 15059  I  WS 15475728 + 16 [ThreadPoolForeg]
  8,1    3       10     0.615815352 15059  D  WS 15475728 + 16 [ThreadPoolForeg]
  8,1    3       11     0.616105591     0  C  WS 15475728 + 16 [0]
CPU1 (8,1):
 Reads Queued:           0,        0KiB     Writes Queued:          61,      252KiB
 Read Dispatches:        0,        0KiB     Write Dispatches:       14,      252KiB
 Reads Requeued:         0      Writes Requeued:         0
 Reads Completed:        0,        0KiB     Writes Completed:       14,      252KiB
 Read Merges:            0,        0KiB     Write Merges:           47,      188KiB
 Read depth:             0          Write depth:             2
 IO unplugs:             9          Timer unplugs:           0
CPU3 (8,1):
 Reads Queued:           0,        0KiB     Writes Queued:           2,        8KiB
 Read Dispatches:        0,        0KiB     Write Dispatches:        1,        8KiB
 Reads Requeued:         0      Writes Requeued:         0
 Reads Completed:        0,        0KiB     Writes Completed:        1,        8KiB
 Read Merges:            0,        0KiB     Write Merges:            1,        4KiB
 Read depth:             0          Write depth:             2
 IO unplugs:             1          Timer unplugs:           0

Total (8,1):
 Reads Queued:           0,        0KiB     Writes Queued:          63,      260KiB
 Read Dispatches:        0,        0KiB     Write Dispatches:       15,      260KiB
 Reads Requeued:         0      Writes Requeued:         0
 Reads Completed:        0,        0KiB     Writes Completed:       15,      260KiB
 Read Merges:            0,        0KiB     Write Merges:           48,      192KiB
 IO unplugs:            10          Timer unplugs:           0

Throughput (R/W): 0KiB/s / 337KiB/s
Events (8,1): 254 entries
Skips: 0 forward (0 -   0.0%)

biotop

プロセスtopによるブロックデバイス(ディスク)I/O
topのディスクI/O版

フィールド

loadavg /proc/loadavg
PID キャッシュされたプロセスID(存在する場合は)
基本的にはI/Oの原因となるプロセスを特定する(保証はされない)
COMM キャッシュされたプロセス名(存在する場合は)
基本的にはI/Oの原因となるプロセスを特定する(保証はされない)
D 方向(Direction)
R(Read)
W(Write)
MAJ メジャーデバイス番号
MIN マイナーデバイス番号
DISK ディスクデバイス名
I/O インターバル間のI/Oの数
Kbytes インターバル間のI/OのKbytesの合計
AVGms デバイスに発行されてから完了するまでのI/Oレイテンシの平均時間(ミリ秒)
16:50:00 loadavg: 0.14 0.04 0.01 1/756 30610

PID    COMM             D MAJ MIN DISK       I/O  Kbytes  AVGms
422    jbd2/sda1-8      W 8   0   sda          2     132   0.26
28892  kworker/u256:2   W 8   0   sda         11      44   0.32
30344  cp               W 8   0   sda          1       4   0.23
30345  cp               W 8   0   sda          1       4   0.17
30286  cat              W 8   0   sda          1       4   0.31
30513  npm              W 8   0   sda          1       4   0.30
30343  cp               W 8   0   sda          1       4   0.28
30567  cat              W 8   0   sda          1       4   0.30
0                       R 0   0   ?            2       0   0.18