本記事は、特定の環境下における特定の書き込みパターンを測定した結果であり、 I/O スケジューラの優劣を決めるものではない。
関連記事
概要
本記事では、I/Oスケジューラの違いによって、次のようなストレージへの書き込み特性について確認した。
- スループット
- BIO毎のレイテンシ
- CPU使用率
今回の環境(Raspberry Pi 4 と SSD/SDカード) と測定方法では、それぞれのI/Oスケジューラ (パラメータはデフォルト値) による大きな違いは見られなかった。
はじめに
汎用的なストレージデバイスは、その特性からまとまったデータ量のI/Oであるほうが効率が良いとされている。
しかし実際には、アプリケーションがそういったI/Oが発行されるとは限らない。
Linuxカーネルには、I/Oスケジューラと呼ばれるI/Oリクエストの処理順番を入れ替えたり、まとめたりすることで応答速度やスループットを向上を目的とした機能である。
I/Oスケジューラにはそれぞれ異なる特性があり、システム環境やストレージデバイスなどによって、I/O性能が変わってくる。
ここでは、OSの機能の一機能 "I/Oスケジューラ"に注目して、それぞれの書き込みの違いを確認する。
Linux Kernel v5.15 では、mq-deadline、bfq (Budget Fair Queuing)、kyber がサポートしている。
mq-deadline の概要
mq-deadlineは、デッドラインを設けることでリクエストの処理開始時間を保障する I/Oスケジューラの一つである。
Linux Kernel v5.15 のデフォルト値では、書き込みリクエストの有効期限は 5秒 、読み込みリクエストの有効期限は 500 ミリ秒 となる。
bfq の概要
bfq は、単一のアプリケーションがすべての帯域幅を使用しないようスケジュールする I/Oスケジューラの一つである。
Linux Kernel 5.15 のデフォルト値では、スループットの最大化よりもレイテンシの最小化を達成することを目的とする。
そのため、低速のCPUに対して高速なストレージデバイスに対しては、bfq I/Oスケジューラは不向きとなることがある。
kyber の概要
mq-deadlineは、ブロックレイヤに渡されたI/O要求のレイテンシを計算し、目標とするレイテンシを達成するような I/Oスケジューラの一つである。
Linux Kernel v5.15 のデフォルト値では、目標とする読み込みレイテンシは 2ミリ秒 、同期書き込みのレイテンシは 10 ミリ秒 となる。
目的
I/Oスケジューラの違いによって、次のような書き込み特性がどのように変化するかを調査する。
- スループットの計測
- BIO毎のレイテンシ計測
- CPU使用率の計測
実行環境
Raspberry Pi 4 Model B (Raspberry Pi 4) は microSDカード経由でRaspberry Pi OSを起動させる。 また、Raspbery Pi 4 の USB3.0ポートにポータブルSSDを接続する。
ここで使用する実験環境について下記に示す。
項目 | 概要 |
---|---|
Board | Raspberry Pi 4 |
CPU | Cortex-A72 (ARM v8) 1.5GHz |
メモリ | 4GB LPDDR4-3200 |
OS | Raspberry Pi OS (64 bit) (Feb 21st 2023) |
kernel | v5.15.92 |
ファイルシステム | ext4 |
BCC Utilities | bpfcc-tools version 0.18.0+ds-2 |
ext4 Utilities | E2fsprogs version 1.46.2 |
fio | fio-3.25-2 |
OS格納先ストレージ | microSDHC 16GB Class10 UHS-1 |
計測用ストレージ(外付けSSD) | SL-MG5 |
計測用ストレージ(SDカード) | SF-E64 |
この実験では、 外付け SSD/SDカードに対する書き込みを計測する。
計測方法
ストレージへの書き込みをする負荷プログラムとして fio を実行し、次のような情報を取得することでI/Oスケジューラの比較する。
- スループットの計測
- BIO毎のレイテンシ計測
- CPU使用率の計測
毎計測時、デフォルトパラメータでmkfs
コマンドの実行と、 echo 3 > /proc/sys/vm/drop_caches
によるキャッシュ解放を実施する。
biosnoop
とmpstat
による計測は、ファイルシステムをマウント(mount
)してからアンマウント(umount
)までとする。
その区間に負荷プログラム(fio
)を実行し、そのときのIO要求のデータを使用する。
計測の流れを図にすると下記のようになる。
ここで、白色の丸は "非同期処理"であり、黒色の丸は "同期処理" を表している。
また、各実験は3回ずつ施行する。
スループットの計測
fioでは、合計 32GB となるような 次の4パターンを2つのアクセス手法 (sequential/random) のジョブとして実行する。
write パターン1 |
write パターン2 |
write パターン3 |
write パターン4 |
|
---|---|---|---|---|
bs | 1M | 1M | 1M | 1M |
size | 32G | 8G | 8G | 8G |
numjobs | 1 | 4 | 1 | 4 |
iodepth | 1 | 1 | 4 | 4 |
この実験では、異なる計測用ストレージとI/Oスケジューラに対して、これらを実行する。
BIO毎のレイテンシ計測
BPF Compiler Collection (BCC) を利用することで、ユーザプログラムから IO要求発行に任意の処理を追加し、IO要求の内容を確認する。
今回の計測では、BCCのサンプルスクリプトとして提供されている biosnoop を利用する。
biosnoop は、IO要求発行(blk_mq_start_request
)と IO完了(blk_account_io_done
) における BIO のステータスを確認することができる。
このスクリプトを実行することで下記のような結果を得ることができる。
TIME(s) COMM PID DISK T SECTOR BYTES QUE(ms) LAT(ms)
0.000000 mount 4349 sda R 2050 1024 0.06 0.46
0.000396 mount 4349 sda R 2048 4096 0.05 0.19
0.000713 mount 4349 sda R 2056 4096 0.05 0.18
0.000826 mount 4349 sda R 2064 4096 0.05 0.18
0.000968 mount 4349 sda R 2072 4096 0.05 0.16
0.001165 mount 4349 sda R 2080 4096 0.09 0.17
ここから書き込み先デバイス (DISK
) と アクセス方向 (T
) でフィルターをかける。
ここから、タイムスタンプ (TIME
), オフセット (SECTOR
)とサイズ (SIZE
)を抽出する。
CPU使用率の計測
mpstatを利用することで、次のようなプロセッサ関連の統計情報を表示することができる。
Linux 5.15.92-v8 (raspberrypi) 09/09/2023 _aarch64_ (4 CPU)
10:59:25 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
10:59:26 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
10:59:27 PM all 0.00 0.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 99.75
10:59:28 PM all 0.25 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 99.75
10:59:29 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
10:59:30 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
今回は、CPU使用率を確認するために mpstat をバックグラウンドで実行する。
準備
Linuxカーネルの再構築
BCCは、特定のカーネルコンフィグに依存しているが、Raspberry pi OS のデフォルトで無効となっている。
そこで、公式手順に基に、独自にカーネルのビルド・インストールを実施する。
カーネルコンフィグは、デフォルトのカーネルコンフィグから次のように修正する。
user@hostname:~/linux$ ./scripts/diffconfig .config.old .config
IKHEADERS n -> y
また、Kyber と BFQ はデフォルトで無効となっているため、カーネルコンフィグを更新しておく。
user@hostname:~/linux$ ./scripts/diffconfig .config.old .config
MQ_IOSCHED_KYBER=y
IOSCHED_BFQ=y
必要なパッケージのインストール
今回の計測するにあたって、Raspberry Pi OS にプリインストールされているパッケージのみでは不足している。
そこで、計測用にdebianパッケージを追加でインストールする。
pi@raspberrypi:~$ sudo apt install bpfcc-tools
BPFスクリプトの修正
debian (bullseye) が提供する bpfcc-toolsパッケージは、upstreamより古いバージョンとなっている。
今回使用しているバージョンには、BYTES
の値で不適切となる不具合があったため、次のコミットをcherry-pickした。
また、今回の計測では短時間に多くのBIO情報が出力されるため、リングバッファ (page_cnt
) のサイズも拡張しておく。
実験結果
スループット
I/Oスケジューラの違いによるパフォーマンスを比較する。
パフォーマンス測定には fio
の実行結果からbw
を抽出した。
(Raspberry Pi 4と比較して) 高速なSSDの場合には、bfq I/Oスケジューラが他と比較してスループットが低めとなっているように見える。
特に、numjobs=1, iodepth=4 のシーケンシャルな書き込みでは、mq-deadline I/Oスケジューラと比較しても 5%程の低下がみられた。
これは、bfq I/Oスケジューラのデフォルト値における特性では、"低速のCPUに対して高速なストレージデバイスに対しては、bfq I/Oスケジューラは不向きとなることがある" ことが関係しているのかもしれない。
一方で、SDカードの場合には、mq-deadline I/Oスケジューラが他と比較してスループットが低めとなっているように見える。
mq-deadline I/Oスケジューラのスループットが none と同様であることを考えると、mq-deadlineによるスケジューリングが有効に動作していないと見える。
そのため、書き込みの有効期限などスケジューラのパラメータをチューニングすることで、パフォーマンスは変わるかもしれない。
レイテンシ
I/Oスケジューラの違いによるレイテンシ(IO要求発行時から完了までの時間) を比較する。
ここでは、最も複雑なパターン4 (numjobs=4, iodepth=4) の結果のみ注目する。
各I/Oスケジューラにおいて、biosnoop で得られたレイテンシでヒストグラムでプロットした。 (左から I/Oスケジューラが"mq-deadlie", "kyber", "bfq", "none"の順で表示)
これらのグラフは、横軸がレイテンシで縦軸が発生頻度を表しているため、左上にプロットが集中しているほど平均レイテンシが小さいことを意味する。
外付けSSDに対するシーケンシャルな書き込みによるレイテンシには、次のような傾向が見られた。
- mq-deadline と kyberの I/Oスケジューラは、bfq I/Oスケジューラと比較して、低レイテンシの頻度は少ないが、高レイテンシの頻度も少ない
- mq-deadline と kyberの I/Oスケジューラは、bfq I/Oスケジューラと比較して、高レイテンシの頻度も少ない
一方で、ランダムな書き込みによるレイテンシには、次のような傾向が見られた。
- mq-deadline I/Oスケジューラは、kyber と bfq I/Oスケジューラと比較して、結果のばらつきが小さい
- ただし、それぞれの I/Oスケジューラでのレイテンシの違いに大きな差分はない
SDカードに対する書き込みによるレイテンシについては、それぞれの I/Oスケジューラでのレイテンシの違いに大きな差分はなかった。
CPU使用率
I/Oスケジューラの違いによるCPU使用率(すべてのコアの合算値)を比較する。
レイテンシと同様に、最も複雑なパターン4 (numjobs=4, iodepth=4) の結果のみ注目する。
各I/Oスケジューラにおいて、mpstat で得られたCPU利用状況を内訳によって積み上げグラフとしてプロットした。 (左から I/Oスケジューラが"mq-deadlie", "kyber", "bfq", "none"の順で表示)
これらのグラフは、赤色がカーネルで実行されたCPU利用の割合を表しているため、赤色の割合が大きいほどI/Oスケジューラによるオーバーヘッドが大きいことを意味する。
CPU使用率の観点では、それぞれのケースにおいてI/Oスケジューラによるオーバーヘッド (赤色がグラフを占める割合) に大きな差分はなかった。
ただし、mq-deadline I/Oスケジューラでは、 カーネルで実行されたCPU利用にばらつきが大きい。
おわりに
本記事では、ファイルシステムの違いによるストレージへの書き込みについて以下の3点に着目して計測した。
- スループット
- BIO毎のレイテンシ
- CPU使用率
今回はI/Oスケジューラのパラメータをチューニングしていないため、参考値ではあるが I/Oスケジューラによる大きな違いは見られなかった。
また、この実験は利用的な環境 (ユーザからこのプロセスしか動かしておらず、負荷が大きいプロセスもこのプロセスのみである) であるため、実際には結果が大きく異なることが予想される。
そのため、それぞれのユースケースに沿って環境を選定することが必要となってくる。
変更履歴
- 2023/10/01: 記事公開
- 2023/11/19: 関連記事を追加
参考
- IOスケジューラごとにスループットを計測
- 2023年における I/O スケジューラのまとめ
- I/Oスケジューラの概要