kledgeb UbuntuやLinuxの最新情報を紹介

Ubuntu 19.04 その6 - UbuntuとLinux I/Oスケジューラー(後編)

UbuntuとLinux I/Oスケジューラー(後編)

「UbuntuとLinux I/Oスケジューラー(前編)」の続きです。

I/Oスケジューラーはストレージアクセスへのリクエスト(要求)を、データの論理アドレスに基づき線形順序でリクエストを並び替えたり、リクエストを一纏めにグルーピングすることで、スループットの改善を試みます。


これにより全体のスループット向上に期待できますが、リクエストの中に長い間待たされてしまうリクエストが発生する可能性があり、遅延の問題に繋がります。

  • IOSchedulers

異なる手法で実装された様々なI/Oスケジューラーが存在しますが、それぞれ特性が異なり一長一短があります。
これらのI/Oスケジューラーを大別すると、「シングルキューI/Oスケジューラー(非マルチキューI/Oスケジューラー)」と「マルチキューI/Oスケジューラー」に分類されます。

シングルキューI/Oスケジューラー

1.Deadline

「Deadline」は、他のI/Oスケジューラーで見られるような一部リクエストの長い遅延の発生を抑えることができます。
「Deadline」ではI/Oリクエストに3つのキューを使用します。

  1. Sorted queue(読み書きリクエスト/セクター番号で並び替え)
  2. Read queue(読み取りリクエスト/期限で並び替え)
  3. Write queue(書き込みリクエスト/期限で並び替え)

リクエストは「Sorted queue」から発行されます。
「Deadline」は「Read queue」及び「Write queue」の先頭にあるリクエストが期限切れになっていないかチェックし、期限切れのリクエストを優先的に処理します。
この時「Write queue」よりも「Read queue」が優先されます。
読み取りリクエストには500msの期限が設定され、書き込みリクエストには5秒の期限が設定されます。

このI/Oスケジューラーに関する設定は、以下を参照してください。

  • deadline-iosched.txt

2.CFQ(Completely Fair Queueing)

「CFQ」は、プロセスごとに同期I/Oリクエストを保持する「Sorted queue」を持ちます。
各キューの均衡を図るためタイムスライスが割り当てられ、ディスクへのアクセスが行われます。
各キューに割り当てられるタイムスライスの長さや、キューから発行可能なリクエストの数は、「ionice」の優先度が考慮されます。

またすべてのプロセスの非同期I/Oリクエストを優先度毎に保持する少数の「Queue」を持ちます。

ただしタイムスライスが期限切れになる前に余計な待機時間が発生する可能性があります。
このI/Oスケジューラーに関する設定は、以下を参照してください。

  • cfq-iosched.txt

3.Noop(No-operation)

「Noop」は、I/Oリクエストのマージは行いますが、I/Oリクエストの並び替えを行いません。
セクター番号による並び替えが性能に影響を与えないストレージ向けのI/Oスケジューラーです。

FlashストレージやSSD、RAMディスクなどランダムアクセスが高速なストレージを利用している場合に有用なI/Oスケジューラーです。
またI/Oリクエストを並び替える高度なストレージコントローラーを利用している場合にも有用です。

マルチキューI/Oスケジューラー

マルチキューI/Oスケジューラーは、マルチキューデバイス向けに設計されているI/Oスケジューラーです。
I/Oリクエストを複数のキューに割り当て(マップ/マッピング)、複数のCPUに横断的に分散させたカーネルスレッドにより処理が行われます。

1.BFQ(Budget Fair Queueing)

「BFQ」は「CFQ」を拡張・改良した実装であり、特にI/Oが遅いストレージでより良い応答性を提供するように設計されています。

「BFQ」は複雑なI/Oスケジューラーであり、他のI/Oスケジューラーに比べて各処理毎に高い処理コストがかかります。
そのため低速なCPUや高速なI/Oを提供するストレージには向いていません。

リクエストの均衡は、要求されたセクター数及びタイムスライスよりもヒューリスティクスに基づき処理されます。
このI/Oスケジューラーに関する設定は、以下を参照してください。

  • bfq-iosched.txt

2.Kyber

「Kyber」は、高速なマルチキューデバイス向けに設計され、他のI/Oスケジューラーに比べてシンプルな実装になっています。
「Kyber」は以下の2種類のキューを持ちます。

  1. 同期リクエストキュー(ブロックの読み込みなど)
  2. 非同期リクエストキュー(書き込みなど)

キューに送られるリクエスト操作の数には、厳格な制限があります。
理論的にはこの制限により、発行されるリクエストの待ち時間を制限することができます。
そのため優先度の高いリクエストを早く完了させることができます。
このI/Oスケジューラーに関する設定は、以下を参照してください。

  • kyber-iosched.txt

3.None

「None」は、マルチキュー向けNo-operation I/Oスケジューラーです。
リクエストの並び替えを行わず、処理コストは最低限で済みます。

「NVME」のような高速なランダムアクセスを提供するストレージに有用です。

4.MQ Deadline(mq-deadline)

「MQ Deadline」は、「Deadline」をマルチキュー向けに適合させたI/Oスケジューラーです。
このI/Oスケジューラーに関する設定は、以下を参照してください。

  • deadline-iosched.txt

Ubuntuで利用可能なI/Oスケジューラー

「Ubuntu」では「Ubuntu」のバージョンにより、デフォルトで利用可能なI/Oスケジューラーが異なります。

1.Ubuntu 19.10(Linux kernel 4.20)より前

「Ubuntu 19.10(Linux kernel 4.20)」より前のバージョンでは、マルチキューI/Oスケジューラーはデフォルトで有効になっていません。
シングルキューI/Oスケジューラーはデフォルトで有効になっており、以下のI/Oスケジューラーを利用できます。

  1. Deadline
  2. CFQ
  3. Noop

2.Ubuntu 19.10(Linux kernel 4.20)以降

「Ubuntu 19.10(Linux kernel 4.20)」以降のバージョンでは、デフォルトでマルチキューI/Oスケジューラーが有効になっており、以下のI/Oスケジューラーを利用できます。

  1. BFQ
  2. Kyber
  3. None
  4. MQ Deadline

注意と捕捉 

「Linux kernel 4.20」は現在開発中のバージョンであり、2018年12月16日に「Linux kernel 4.20 RC7」がリリースされています。
「Ubuntu 19.04」は2019年4月にリリース予定であり、「Ubuntu 19.04」のリリースに「Linux kernel 4.20」が間に合います。

上記ではドキュメントに従い「Ubuntu 19.10」と表記していますが、「Ubuntu 19.04」のことを指している可能性もあります。

I/Oスケジューラーの利用と選択

マルチキューI/Oスケジューラーの無効化

カーネルパラメーターにより、マルチキューI/Oスケジューラーを無効化しシングルキューI/Oスケジューラーに切り替えることも可能です。

例えばSCSIデバイスで「blk-mq(Multi-Queue Block IO Queueing Mechanism)」を無効化するには、以下の作業を行います。

  1. 「/etc/default/grub」を開く
  2. 「GRUB_CMDLINE_LINUX_DEFAULT」に「scsi_mod.use_blk_mq=0」を追記する
  3. 「sudo update-grub」を実行してPCを再起動する

I/Oスケジューラーを変更する

I/Oスケジューラーの変更は、ブロックデバイスごとに適用されます。

シングルキューデバイスの場合

「/dev/sda」がシングルキューデバイスだとします。
以下のコマンドを実行すると「/dev/sda」で利用可能なI/Oスケジューラーを調べることができます。

cat /sys/block/sda/queue/scheduler


「/dev/sda」のI/Oスケジューラーを「Deadline」に変更するには、以下のコマンドを実行します。

echo "deadline" | sudo tee /sys/block/sda/queue/scheduler

マルチキューデバイスの場合

「/dev/sda」がマルチキューデバイスだとします。
以下のコマンドを実行すると「/dev/sda」で利用可能なI/Oスケジューラーを調べることができます。

cat /sys/block/sda/queue/scheduler
[mq-deadline] none

I/Oスケジューラーを「Kyber」に変更するには、まず以下のコマンドを実行し「Kyber」モジュールを読み込みます。

sudo modprobe kyber-iosched

利用可能なI/Oスケジューラーに「Kyber」が追加されています。

cat /sys/block/sda/queue/scheduler
[mq-deadline] kyber none

そしてI/Oスケジューラーを「Kyber」に変更するには、以下のコマンドを実行します。

echo "kyber" | sudo tee /sys/block/sda/queue/scheduler

最善のI/Oスケジューラーを選ぶために

最善のI/Oスケジューラーは、環境により異なります。
最善のI/Oスケジューラーを選ぶためには、ストレージの特性やストレージの使われ方を想定したテストが必要です。

テストの一例とテスト環境

テストの一例の紹介です。
本テストのテスト結果は、25種の異なるI/Oパターンを組み合わせ、以下のファイルシステムで「fio」を使用しテストが行われています。

  • ext2
  • ext3
  • ext4
  • xfs
  • btrfs 

また「Linux kernel 4.19」上でテストされています。

SSD

SSDを対象にしたテスト結果です。

I/Oパターン 第1候補 第2候補 非推奨
ランダムI/O CFQ/Deadline ー BFQ
シーケンシャルI/O Deadline Noop BFQ
データベースI/O Deadline Noop BFQ
一般的なI/O Deadline Noop BFQ

捕捉

「Deadline」は、マルチキューデバイスでは「MQ Deadline」を使用しています。
「Noop」は、マルチキューデバイスでは「None」を使用しています。

総評

高速なSSD/NVMEデバイスでは、「CFQ」/「Deadline」/「MQ Deadline」/「Kyber」間のスループットの差は小さな差しかなく、有意な差は見られませんでした。
このテスト結果からお勧めのI/Oスケジューラーは、CPUの使用量を抑える「Noop」もしくは「None」でしょう。

HDD

HDDを対象にしたテスト結果です。

I/Oパターン 第1候補 第2候補 非推奨
ランダムI/O Deadline BFQ/CFQ BFQ/Noop
シーケンシャルI/O Deadline BFQ Noop
データベースI/O Deadline ー BFQ/Noop
一般的なI/O Deadline BFQ Noop

捕捉

「Deadline」は、マルチキューデバイスでは「MQ Deadline」を使用しています。
「Noop」は、マルチキューデバイスでは「None」を使用しています。

総評

HDDでは「Noop」及び「None」の使用は推奨しません。

ブロックアドレスに基づきI/Oリクエストの並び替え(最適化)を行うことで、ヘッドのシーク時間(ヘッドのシーク待ち)を減らすことができ、リクエストの処理にかかる時間を減らすことができます。
しかし「Noop」及び「None」は、I/Oリクエストの並び替えを行いません。
Ubuntu
スポンサー
コメント
コメントポリシー
コメントをする前に UbuntuのCode of Conduct(CoC/行動規範) を確認し、CoCに沿ったコメントをお願いします。
コメントの使い方は、コメントの使い方を参照してください。
同一カテゴリーの記事
SNS
人気の記事
  • Ubuntu 22.04 LTSのインストール その5 - UEFI環境でパーティションの作成と構成 〜 ブートローダーのインストール先の選択
    UEFI環境でパーティションの作成と構成を行う UEFI環境でパーティションの作成と構成を行います。
  • Ubuntu 22.04 その120 - UbuntuのブートローダーをBoot Repairで修復するには・Ubuntuが起動しないトラブルを解決
    UbuntuのブートローダーをBoot Repairで修復するには 「Boot Repair」はOSのブートローダーに起因するOSが起動しない問題を簡単に解決してくれるアプリです。
  • Ubuntu 22.04 その98 - 入力ソースとキーボートレイアウトと日本語入力のカスタマイズ
    入力ソースとキーボートレイアウトと日本語入力 「Ubuntu」ではユーザーが利用しているキーボードレイアウトや日本語入力のカスタマイズが可能です。
  • VirtualBox その125 - ゲストOSのUbuntuにLinux Guest Additionsをインストールするには
    ゲストOSのUbuntuにLinux Guest Additionsをインストールするには 仮想マシンにインストールしたゲストOSの「Ubuntu」に、「Linux Guest Additions」をインストールする方法です。
  • Ubuntu 22.04 その79 - 画面ロックの有効・無効を設定するには・画面ロック時の設定をカスタマイズするには
    画面ロックの有効・無効を設定するには 一定時間ユーザーによる操作がない時に、自動的に画面をロックしパスワードで保護したり、画面をブランク状態にできます。
  • Ubuntu 22.04 その95 - ディスプレイサーバーを切り替えるには・XorgとWayland
    ディスプレイサーバーを切り替えるには 「Ubuntu」はデフォルトで2種類のディスプレイサーバーを提供しています。
  • Ubuntu 22.04 その64 - Windows/Linux/macOSでUbuntu 22.04 LTSのライブUSBメモリーを作るには
    Ubuntu 22.04 LTSのライブUSBメモリーを作る方法 Windows/Linux/macOSでPC向け「Ubuntu 22.04 LTS」のライブUSBメモリーを作る方法を紹介します。
  • Ubuntuのバージョンと開発コードの対応表
    UbuntuのバージョンとUbuntuの開発コード 「Ubuntu」には各バージョンごとに開発コードが設定されます。
  • Linux その215 - GNOME 48 リリース・GNOME 48 の新機能と変更点
    GNOME 48 の新機能と変更点 2025年3月19日、GNOME 48(コードネーム:Bengaluru) がリリースされました。 リリースノートから GNOME 48 の新機能と変更点を紹介します。
  • Ubuntu 22.04 LTSのインストール その1 - インストールの準備 〜 ライブメディアの作成とUbuntuの起動
    Ubuntu 22.04 LTSのインストールの準備 ここではPCに「Ubuntu 22.04 LTS(Ubuntu Desktop)」をインストール方法を紹介します。 まずはインストールの準備からです。
記事のピックアップ
オプション