6.4. 設定
最初に必要となる決定の 1 つは、どの I/O スケジューラーを使用するかというものです。このセクションでは、個々のワークロードに最適なスケジューラーを決定できるように、主要スケジューラーの概要を提供します。
6.4.1. Completely Fair Queuing (CFQ)
Red Hat Enterprise Linux 6 のデフォルトの I/O スケジューラーです。CFQ は、I/O を開始したプロセスに基づいて I/O スケジューリングの決定に公平さをもたらすようにします。以下の 3 つのスケジューリングクラスが提供されています:リアルタイム (RT)、ベストエフォート (BE)、アイドル。スケジューリングのクラスは、
ionice
コマンドを使って手動で割り当てるか、ioprio_set
システムコール経由でプログラムで割り当てることができます。デフォルトでは、プロセスはベストエフォート型のスケジューリングクラスに置かれます。リアルタイムとベストエフォートのスケジューリングクラスはさらに各クラス内で 8 つの I/O 優先順位に分けられます。このうち、0 の優先順位が一番高く、7 が一番低くなります。リアルタイムのスケジューリングクラスのプロセスは、ベストエフォートやアイドルにあるプロセスよりも積極的なスケジュールになるので、スケジュールされたリアルタイムの I/O は常にベストエフォートやアイドルの I/O よりも先に実行されます。つまり、リアルタイムの優先順位が付けられている I/O は、ベストエフォートとアイドルクラスの両方に悪影響を与える可能性があることになります。ベストエフォートスケジューリングはデフォルトのスケジューリングクラスで、このクラス内のデフォルトの優先順位は 4 になります。アイドルのスケジューリングクラス内のプロセスは、システム内に実行されていない他の I/O がない場合にのみ、実行されます。つまり、プロセスの I/O スケジューリングクラスをアイドルに設定するのは、そのプロセスからの I/O が進行に全く必要ない場合だけにします。
CFQ は、I/O 実行中の各プロセスにタイムスライスを割り当てることで公平性をもたらします。このタイムスライスの間、プロセスは (デフォルトで) 最大 8 つの要求を同時にフライト状態で保持することが可能です。スケジューラーは履歴データに基づいて、アプリケーションがさらに I/O を近いうちに発行するかどうかの予測を試みます。プロセスがさらなる I/O を発行することが予想されると、他のプロセスからの I/O の発行を待っている状態でも CFQ はアイドルになり、その I/O を待機します。
CFQ によるアイドリングのために、高速の外部ストレージアレイやソリッドステートディスクなど、大型のシークペナルティーから損害を受けないハードウェアには適さない場合が多くあります。そのようなストレージで CFQ の使用が必要な場合 (例えば、cgroup 比例加重 I/O スケジューラーも使いたい場合)、CFQ パフォーマンスの改善には設定のチューニングも必要になります。
/sys/block/device/queue/iosched/
にある同一名のファイルで以下のパラメーターを設定します。
slice_idle = 0 quantum = 64 group_idle = 1
group_idle
が 1 に設定されても、I/O ストールの可能性は残ります (これにより、バックエンドのストレージはアイドリングのためにビジーではありません)。しかし、これらのストールの頻度は、システムの各キューでのアイドリングよりも少なくなります。
CFQ は、作業を維持しない I/O スケジューラーです。つまり、(上記で説明したように) 保留中の要求がある時でもアイドルになる場合があります。作業を維持しないスケジューラーのスタッキングは、I/O パスに大幅な待ち時間をもたらす可能性があります。その一例は、ホストベースのハードウェア RAID コントローラーに加えて CFQ を使用することです。つまり、スタックで 2 つのレベルの遅延を引き起こすことになります。作業を維持しないスケジューラーは、決定の基となるデータができるだけ多くあるときに最も優れた作動となります。アルゴリズムのスケジューリングのようなスタッキングの場合、一番下のスケジューラーは上位のスケジューラーが送信したものしか見れません。つまり、下位の層でみられる I/O パターンは、実際のワークロードとはかけはなれたものになってしまいます。
チューニング可能なパラメーター
back_seek_max
- 後方シークは、ヘッドの位置変更で前方シークよりも大幅な遅延を発生させる可能性があるので、パフォーマンスには通常マイナスとなります。しかし、大きくない場合は、CFQ はそれらを実行します。このパラメーターは、I/O が後方シークに許可する最大の距離を KB で制御します。デフォルト値は、
16
KB です。 back_seek_penalty
- 後方シークはその非効率性のために、それぞれにペナルティーが関連付けられます。ペナルティーは乗数で、例えば 1024KB のディスクヘッド位置を考えてみましょう。キューに 2 つの要求があるとします。ひとつは 1008KB にあり、もうひとつは 1040KB にあります。これら 2 つの要求は、現在のヘッド位置から等距離にあります。しかし、後方シークペナルティー (デフォルトでは 2) を適用すると、ディスク上で後ろの位置にある要求の位置は、前の位置にあるものよりも 2 倍の距離になってしまいます。このため、ヘッドは前に移動します。
fifo_expire_async
- このパラメーターは、async (バッファリングされた書き込み) 要求が実行されない時間を制御します。有効時間 (ミリ秒) の後に、単一のリソース不足となっている非同期要求は、ディスパッチリストに移動されます。デフォルト値は、
250
ミリ秒です。 fifo_expire_sync
- 同期 (読み取りおよび O_DIRECT 書き込み) 要求では、これは fifo_expire_async と同じです。デフォルト値は、
125
ミリ秒です。 group_idle
- これが設定されると、CFQ は cgroup で I/O を発行している最後のプロセスでアイドルになります。比例加重 I/O cgroup の使用時にはこれを
1
に設定し、slice_idle
を0
に設定 (通常は高速ストレージで実行) することが推奨されます。 group_isolation
- グループ分離 (
1
に設定) が有効な場合、これはスループットを代償にして、グループ間の分離を強化します。通常は、グループ分離が無効になっていると、公平性が提供されるのは連続するワークロードのみです。グループ分離を有効にすると、連続するワークロードランダムなワークロードの両方の公平性が提供されます。デフォルト値は0
(無効) です。詳細はDocumentation/cgroups/blkio-controller.txt
を参照してください。 low_latency
- low latency を有効にすると (
1
に設定)、CFQ はデバイス上で I/O を発行している各プロセスに最大 300 ミリ秒の待ち時間を与えようとします。これにより、スループットよりも公平性が優先されます。low latency を無効にすると (0
に設定)、ターゲットの待ち時間が無視され、システムの各プロセスが完全なタイムスライスを取得します。low latency はデフォルトでは有効になっています。 quantum
- quantum は、CFQ が一度にストレージに送信する I/O 数を制御し、実質上はデバイスキューの深さを制限します。デフォルトでは、
8
に設定されています。ストレージはより深いキューをサポートする可能性がありますが、quantum
を高めると待ち時間にマイナスの影響を与え、特に大量の連続する書き込みワークロードがある場合はマイナスの影響があります。 slice_async
- このパラメーターは、非同期 (バッファリングされた書き込み) I/O を発行する各プロセスに割り当てられるタイムスライスを制御します。デフォルト値は
40
ミリ秒に設定されています。 slice_idle
- これは、CFQ が新たな要求を待っている間にアイドルになる時間を指定します。Red Hat Enterprise Linux 6.1 およびそれ以前でのデフォルト値は、
8
ミリ秒です。Red Hat Enterprise Linux 6.2 およびそれ以降のデフォルト値は、0
です。値が 0 だとキューおよびサービスツリーレベルのアイドリングをすべて削除するので、外部 RAID ストレージのスループットが改善されます。ただし、これは全体のシーク回数を増やすので、内部の非 RAID ストレージのスループットを低下させる場合があります。非 RAID ストレージでのslice_idle
の値は、0 よりも大きくすることが推奨されます。 slice_sync
- このパラメーターは、同期 (読み取りおよび直接書き込み) I/O を発行するプロセスに割り当てられるタイムスライスを規定します。デフォルト値は
100
ミリ秒です。