I/O スケジュールはストレージに対して、入出力操作をどのように送信するのかを
決めるための仕組みです。 openSUSE では様々な I/O アルゴリズムに対応
しています。それらのアルゴリズムは エレベータ
と呼ばれ、
それぞれ異なる処理用に用意されています。エレベータはストレージへの要求回数
を減らすための手助けになるほか、 I/O 要求に優先順位を付けたり、 I/O 要求が
指定された期限内に処理されるようにしたりすることもできます。
適切な I/O エレベータを選択する際は、処理内容だけでなくハードウエアについて も注意しておく必要があります。 ATA ディスクが 1 台だけの環境や SSD, RAID アレイやネットワークストレージシステムでは、それぞれ異なるチューニング戦略 を立てる必要があります。
openSUSE では、システムの起動時に既定の I/O スケジューラが設定されて いて、これらはブロックデバイスごとに即時に変更することができます。これに より、システムパーティションを提供するデバイスとデータベースを提供する デバイスなどで、異なるアルゴリズムを設定できるようになっています。
既定では、 CFQ
(Completely
Fair Queuing; 完全公平型キューイング) が使用されます。起動パラメータで変更
を行ないたい場合は、下記のように指定します:
elevator=SCHEDULER
ここで SCHEDULER
には
cfq
, noop
, deadline
のいずれかを指定します。詳しくは 13.2項 「利用可能な I/O エレベータ」
をお読みください。
また、稼働中のシステムで特定のデバイスに対してエレベータを設定するには、 下記のように実行します:
echoSCHEDULER
> /sys/block/DEVICE
/queue/scheduler
ここで SCHEDULER
には
cfq
, noop
, deadline
のいずれかを指定します。また、 DEVICE
にはブロックデバイス名 (sda
など) を指定します。
openSUSE では、下記のエレベータを使用することができます。それぞれの エレベータにはチューニング可能なパラメータが存在していて、これらは下記の コマンドで設定することができます:
echoVALUE
> /sys/block/DEVICE
/queue/iosched/TUNABLE
ここで DEVICE
にはブロックデバイス名、
TUNABLE
にはパラメータ名称、
VALUE
にはパラメータの値をそれぞれ指定します。
どのエレベータが現在の既定値であるのかを調べるには、下記のコマンドを 実行します。現在選択されているエレベータは大括弧で括られて表示されます:
jupiter:~ # cat /sys/block/sda/queue/scheduler noop deadline [cfq]
CFQ
(Completely Fair Queuing; 完全公平型キューイング)¶
CFQ
は公平性を目指したスケジューラ
で、 openSUSE では既定値になっています。このアルゴリズムは各スレッドに対し、
I/O リクエストを送信できる時間間隔 (タイムスライス) を付与します。この方法
により、各スレッドは I/O スループットを公平に共有することができるようになって
います。また、スケジューリングの決定に際して I/O 優先順位を割り当てることも
できます (詳しくは man 1 ionice をお読みください) 。
CFQ
スケジューラでは、下記の
パラメータを設定することができます:
/sys/block/<デバイス>
/queue/iosched/slice_idle
特定のタスクに対して割り当てられた時間 (タイムスライス) 内に処理したい
I/O 要求が存在しなくなった場合、 I/O スケジューラは I/O の遅延を
考慮して、次のスレッドにスケジュールを割り当てるまでにしばらく
待機を行ないます。大きく遅延しないようなメディア (SSD や多数のディスクが
搭載された SAN など) の場合は、
/sys/block/
を <デバイス>
/queue/iosched/slice_idle0
に設定することで、全体のスループットを高めることが
できます。
/sys/block/<デバイス>
/queue/iosched/quantum
このオプションは、デバイスが一度に処理する要求について、その最大数を
制限します。既定値は 4
に設定されています。何台かの
ディスクが搭載されたストレージシステムの場合は、要求を並行処理すること
から、制限を行なう必要はありません。また、この値を大きくすると性能を
改善することができますが、場合によってはストレージ内に多くの要求を貯め
こむことになるため、 I/O の遅延が大きくなることがあります。この値を
変更する場合は、
/sys/block/
(既定値は <デバイス>
/queue/iosched/slice_async_rq2
) についても修正を行ない、タイムスライス
内に処理する非同期要求 (通常は書き込み要求) について、その最大数を設定
しておくことをお勧めします。
/sys/block/<デバイス>
/queue/iosched/low_latency
I/O の遅延が許されないような負荷を処理する場合は、
/sys/block/
を <デバイス>
/queue/iosched/low_latency1
に設定してください。
NOOP
¶スケジューラに到達した I/O 要求を、単純にそのまま流すだけのものです。 複雑な I/O スケジューラを利用する際、何もしない場合と比べて性能が落ちて いたりしていないかどうかを確認する際に便利なスケジューラです。
I/O のスケジューリングを自分自身で行なうようなデバイス (たとえば
インテリジェント型ストレージ) や、 SSD のように機械的な動作を必要と
しないストレージシステムを利用している場合にも有効です。通常、
これらのデバイスには DEADLINE
I/O スケジューラが有効ですが、オーバーヘットが少ないという理由から、
NOOP
のほうが
よりよい性能を発揮できる場合もあります。
DEADLINE
¶
DEADLINE
は遅延回避を重視する
I/O スケジューラです。それぞれの I/O 要求には期限が設定され、通常は
セクタ番号を基準にしてキュー (読み込みおよび書き込み) 内の並べ替えが
行なわれます。要求が期限切れにならない限り、このような 「sector」
キューを使用します。期限切れになるものが発生すると、期限切れの要求が
なくなるまで 「deadline」 キューからの処理を実施します。
また一般に、このアルゴリズムでは、書き込みよりも読み込みを優先して処理します。
また、この I/O スケジューラは、複数のスレッドが読み書きを行なう種類の処理で、
公平性が必要とされない処理の場合に、 CFQ
よりも優れた性能を提供します。たとえば SAN から変更処理で読み出しを行なうような
場合や、データベース (特に 「TCQ」 と呼ばれる機能を使用するディスク)
などで有効です。なお、 DEADLINE
スケジューラには、下記のようなチューニングパラメータが存在しています:
/sys/block/<デバイス>
/queue/iosched/writes_starved
書き込み要求を送信できるようになるまでに、どれだけの読み込み要求を送信
することができるのかを制御します。たとえば 3
の場合、
1 階の書き込み処理を実施する前に、 3 回の読み込み処理を実施します。
/sys/block/<デバイス>
/queue/iosched/read_expire
読み込み処理に対する期限をミリ秒単位で指定します。現在の時刻に read_expire を足した値がその 期限となります。既定値は 500 です。
/sys/block/<デバイス>
/queue/iosched/write_expire
/sys/block/
と同じ仕組みで、こちらは書き込み処理に対する設定です。既定値は 500 です。
<デバイス>
/queue/iosched/read_expire
多くのファイルシステム (XFS, ext3, ext4, reiserfs) では、 fsync や トランザクションコミットの際に書き込みバリアと呼ばれるものをディスクに送信 します。書き込みバリアは書き込みの順序を守らせるための仕組みで (いくらか 性能面への影響があります) 、ディスクの書き込みキャッシュを安全に利用できる ようにするためのものです。お使いのディスクにバッテリーが搭載されている ような場合は、バリアを無効化することで性能を改善できる場合があります。
書き込みバリアの送信は、マウントオプションに barrier=0
(ext3, ext4, reiserfs の場合) や nobarrier
(XFS)
を設定することで無効化できます。
バリアを無効化した場合、電源が失われたような場合に書き込みキャッシュの 内容の書き込みについて、保証がされなくなります。これにより、ファイル システムの破壊やデータ損失が発生する場合があることにご注意ください。 |