一般的にオペレーティングシステムはどのプロセスがどのタイミングで処理するのか入力と出力(I/O input / output)のスケジューリングを行います。
I/Oスケジューラはそれぞれものによって重視してる要素が違いますが、リクエストを入れ替えることでスループット(読み書き速度)や応答速度の向上を目的としています。これはハードドライブディスクなど低速な記憶装置ほど有効に働きます
昨今ではハードウェアの高速化によりこのI/Oスケジューラの役割はかなり限定的になっていると思います。リクエストの入れ替えを行わなくとも十分に高パフォーマンスを発揮できるようになってきました。スケジューリングをするとかえってシステム(CPU)に負担かかるケースが増えてきています。
スケジューラの種類
none
文字通りスケジューリングを全く行わない設定です。NVMe などの高速な記憶装置に適しています。また処理を全く行わなわずストレージデバイスのコントローラに任せるのでシステムへの負担はないです。
mq-deadline
(Multi-Queue-Deadline) はI/O処理にタイムリミットを設けているスケジューラです。タイムリミットに達したリクエストを優先的に実行していきます。
一つの処理が長い時間放置されたりスタックするのを防ぐことができます。
読み込みI/Oリクエストが多いユースケースに適していると言われています。
bfq(Budget Fair Queueing)
BFQ は帯域や時間をI/Oリクエストに応じて相応に分配する機能を持った低遅延を実現する目的のスケジューラです。バックグラウンドで進行中のタスクにも適切に帯域を配分します。音声や動画の再生など反応速度が重要なアプリケーションと相性が良いです。
デフォルトの設定だと転送速度よりも応答速度を重視しています。カーネルレベルで設定を変更することでスループットを重視することもできます。
柔軟性の高いスケジューラと言えますが、他と比べて複雑な処理を行うため、少々システムへの負荷は多めです。
CPUの処理速度が低いと IOPS に制限がかかってくるので高スループットを実現したい場合はそれなりに高性能なCPUが必要になります。このため低速なストレージでのマルチタスキングを得意としています。複雑なスケジューラのため物理的に回転するドライブや低速な SSD に適している。
kyber
読み込み開始までの待ち時間(read_lat_nsec)と同期までの時間(write_lat_nsec)の2つのターゲットのみで構成されているシンプルなスケジューラです。
シンプルなスケジューラなので高速なデバイスに向いています。旧Facebook(元Meta)が開発しました。
廃止されたスケジューラ
マルチキューに対応していないI/Oスケジューラは軒並みサポートされなくなりました。
deadline
I/O処理にタイムリミットを設定するスケジューラです。制限時間に達したリクエストを優先的に処理します。
単一キュー処理を前提とした設計であったため、マルチキュー処理に対応したmq-deadlineが開発され、こちらは廃止されました。
cfq (Completely fair quere)
CFQ はI/Oリクエストの種類ごとに優先順位付けを行うリストが用意されており、それに則って処理順や待ち時間を設定し、リクエストの入れ替えを行っています。また、deadline 同様に最低
VALinuxさんで仔細な解説を行っているので原理を詳しく知りたい下のURLをご覧になられるのが良いでしよう。
noop
ブロックの統合などは行いますがリクエストの入れ替えなどは行わず、最低限の処理しか行わないスケジューラです。
none と同じものだと勘違いされがちですが noop は最低限のブロック統合などを行うため別物です。
各ディストリの採用スケジューラ
主要なディストリビューションがデフォルトで採用しているI/Oスケジューラを見ていきましよう。
各ディストリビューションを仮想マシン(Qemu)にインストールし、初期状態のスケジューラを確認しました。
以下のコマンドで現在のデバイスに使われているスケジューラを確認することができます
$ cat /sys/block/*/queue/scheduler
- Debian 12
[none] mq-deadline
- Ubuntu 23.04
[none] mq-deadline
- Fedora 38
none [mq-deadline] kyber bfq
・Arch
[none] mq-deadline kyber bfq
興味深いことに Debian 系は SSD のスケジューラを無効にしたようです。
mq-deadline を採用している Fedora に比べ、読み書き性能が大きく上回っています。最近妙に Ubuntu がキビキビ動くと思ったのですがこの影響なのかもしれません。
特に NVMe プロトコルの SSD は旧来の I/O スケジューラをバイパスされますのでその必要性がないと考えるようになったのではないでしようか。
また、Debian 系は kyber と bfq をカーネルレベルで無効化している点にも注目したいです。高速なドライブは none 、それ以外は mq-deadline でええやろ。みたいに割り切っているのだと思います。
まあ実際 none 以外は劇的なパフォーマンスの変化というのは感じられない印象なのでこれが正解なのかもしれません。
仮想マシンでの最適なスケジューラ
Red Hat は、仮想環境のRHELホストマシンではデフォルトの設定である cfq がどんなタスクも万能にこなす無難なスケジューラとしており、ゲストは遅延を最小化するためには deadline が良いとしています。が、この情報はかなり古いと言えます。
仮想マシンにはハイパーバイザーから仮想I/Oデバイスが提供されます。このためゲストシステムはI/Oリクエストをハイパーバイザーにすべて受け渡し、実際のスケジューリングはハイパーバイザーのカーネルが行います。
最適なスケジューラは?
- SSD
NVMe SSDなどの高速なデバイスには none が有用です。また最低限の安定性を保証したい場合は kyber、一部の低速なDRAM非搭載のSSDなどはリクエストがスタックする危険性があるので bfq か mq-deadline いずれも有効だと思います。
- HDD
HDDのような読み書きが低速なデバイスには none に設定しない方が良いでしよう。処理がスタックしてしまう可能性があります。mq-deadline と bfq いずれでも良いと思いますが、デスクトップ用途だと低遅延を優先する bfq がストレスが少ないと思います。
おわり
コメント