Linux:昨今のI/Oスケジューラ事情 2020

Linux
この記事は約6分で読めます。
スポンサーリンク

Photo by Marc PEZIN on Unsplash

HDD や SSD はシステムの中でもボトルネックとなる一番データの転送速度が遅い記憶媒体だ。 オペレーティング・システムにはキャッシュを利用するなど I/Oアクセスを最小限に留める工夫が施されている。そんな中でも I/Oスケジューラは I/Oリクエストの処理順を入れ替えたりリクエストを一つにまとめたりことによりスループットを向上させる機能だ。ディスク・スケジューリングとも呼ばれることがある。

数年前までは Linux カーネルは CFQ noop deadline と言った I/Oスケジューラを搭載していたが、昨今のスケジューラはだいぶ変わっているようだ。

Linux 3.13 から CPU の多コア化、 SSD や PCIe などの高速な記憶媒体の普及に対応するために旧来の単一キュー処理からマルチキュー処理をする Blk-mq(Multi-Queue Block IO Queueing Mechanism) という新しい API が 採用された。これにより 150,000 IOPS 以上のストレージに対応した。I/Oスケジューラもこれに応じて刷新された。Linux 4.12 から BFQ(Budget Fair Queuing)や Kyber が組み込まれた。

昨今の Linux ディストリビューションがどのような I/Oスケジューラを採用しているのか見ていこう。

以下のコマンドでシステムに搭載されている I/O スケジューラを調べる。

$ cat /sys/block/sd*/queue/scheduler

Debian 10.4 のI/Oスケジューラ

[mq-deadline] none

Arch Linux 2020.6 のI/Oスケジューラ

mq-deadline kyber [bfq] none

Fedora 32 のI/Oスケジューラ

mq-deadline kyber [bfq] none

Linux のカーネルバージョンによって使えるスケジューラは決まってくる。 Arch Linux や Fedora といった Linux カーネルの更新が早いディストリビューションでは Debian にはないスケジューラが新たに追加されているのがわかる。

MQ-Deadline 、 Kyber 、BFQ 、 None についてみていこう。

スポンサーリンク

MQ-deadline I/O スケジューラ

deadline をマルチキュー向けに作り直した I/O スケジューラ。文字通りデッドライン(時間制限)を設けリクエストの処理開始時間を保証するのが目的。特定の処理がスタックすることを回避できる。

Kyber I/O スケジューラ

Kyber は Facebook によって開発されたスケジューラ。Kyber スケジューラは読み込み開始までの待ち時間(ナノ秒)read_lat_nsecと同期までの時間(ナノ秒)write_lat_nsecの2つのパラメータのみで構成されているシンプルなスケジューラ。Kyber は設定されたレイテンシーに間に合うよう各リクエストの調整を行う。

BFQ I/O スケジューラ

BFQ (Budget Fair Queueing)は CFQ (Completely Fair Queueing) をマルチキュー機構向けに改良したスケジューラ。BFQ はデフォルト設定だとスループットよりもデバイスによるレイテンシーをできるだけ少なくするようリクエストの整理を行う。音声や動画を扱うアプリケーションに向いているとされている。

CPUの処理速度の低さに比例して IOPS に制限がかかるので高スループットを実現したい場合はそれなりに高性能なCPUが必要になる。逆にストレージの転送速度があまりよくないデバイスでのマルチタスキングに有効だろう。

None (Noop)

None は名前の通りスケジューリングを全く行わない。リクエストの調整を全く行わないので CPU に対する負荷はほとんどない。NVMe プロトコルのSSDなど、ランダムアクセスが高速な記憶媒体に向いている。

逆に低速なドライブで I/Oスケジューラを無効にすると高負荷状態で特定の I/O リクエストがスタックし、システムがフリーズしてしまう可能性もある。高速な SSD ドライブが主流になりつつあるがシステムの安定性を考慮して MQ-Deadline や BFQ を採用してるディストリビューションが多いのはこのためであろう。

廃止されたスケジューラ

CFQ (Completely Fair Queuing)

CFQ の頭字語で Linux カーネルのデフォルトスケジューラ。I/O 優先度をサポートし、その優先度に応じて処理を行う。スケジューラが多数の内部キューを維持しシステム上で動作するプロセス間での I/O リクエストを公平に処理する。システムへの負荷は他のスケジューラに比べ大きい。待ち時間に限界値がある。

Deadline

正確には Deadline は廃止されていないが現在はマルチキューに対応した MQ-Deadline が主流となっている。記憶メディアのディスク上でディスクヘッドの位置から一番近い I/O リクエストから処理していく。ディスクヘッドから遠い I/O 要求は後回しにされるが待ち時間に上限が設けられており、タイムリミットに達した要求が出た際にはそちらを優先する。

どのスケジューラが良いのか

どのスケジューラが良いのかは自身の使っているシステムとアプリケーションによる。

HDD には BFQ を選ぶのが無難だ。

M.2 NVMe などの高速ドライブでは None (Noop)が最もドライブの性能を引き出せるが、SATA 接続の SSD などは処理がもたつく可能性がある。安定性を重視するならば MQ-Deadline が良いだろう。

Linux 5.6 I/O Scheduler Benchmarks: None, Kyber, BFQ, MQ-Deadline - Phoronix
Phoronix is the leading technology website for Linux hardware reviews, open-source news, Linux benchmarks, open-source benchmarks, and computer hardware tests.

スケジューラの変更方法

sda ドライブを BFQ I/O スケジューラに変更するには以下のようにコマンドを使用すれば良い。

# echo bfq > /sys/block/sda/queue/scheduler

SSD と HDD が混在するシステムではそれぞれ違うスケジューラを割り当てたい。こんなときに udev でルールを設定することでシステムに自動的に設定させることができる。

# sudo nano /etc/udev/rules.d/60-ioschedulers.rules
# 無回転デバイス用のスケジューラ設定
ACTION=="add|change", KERNEL=="sd[a-z]|mmcblk[0-9]*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="mq-deadline"
# 回転デバイス用のスケジューラ設定
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"

コメント

タイトルとURLをコピーしました