I/OスケジューラでDBチューニング

DBのチューニングでI/Oスケジューラのチューニングは意外と重要らしいのでメモ

大半の Linux システムで一般的に利用される主なスケジューラは以下の4つ

●noop
●deadline
●anticipatory
●completely fair queuing


noop

最もシンプルなのがこのスケジューラで、これはリクエストをマージしてキューに入れ、それらがキューの先頭に到着した順番で処理を行う。

「noop」スケジューラは、I/O を OS よりうまくスケジュールできる最新のRAIDコントローラを利用するシステムで便利だ。また、これはデバイス上の格納位置にかかわらずデータのシーク時間がすべて一定になるフラッシュメモリドライブ(SSD) (RAM ディスクを含む)搭載システムでも便利だ。

deadline

「deadline」スケジューラは、ディスクの近い場所へのリクエストで、いつもキューの最後に回されるために離れた場所へのリードリクエストへの対応があまりに遅くなる、という問題を克服する設計になっている。

これは、途中階に断続的に停止して乗客を乗せるエレベータで、ビルの最上階に行こうとするのに似ている。これを克服するため、各リクエストには待ち時間、あるいは「(期限) deadline」が与えられる。期限が来る前にリクエストへの対応が行われない場合は、そのリクエストがキューの先頭に置かれ、ディスクの近くの位置に対するリクエストとマージされて即座に対応が行われる。

たいていの場合は待ち時間が短くなり、どのリクエストも deadline で決められた比較的短いタイムフレームで対応が行われるため、「deadline」スケジューラはリアルタイムアプリケーションで便利だ。

anticipatory

「anticipatory」スケジューラは、次に来るリクエストは対応が行われたばかりのディスクブロックの次の位置になると予想する、という仕組みになっている。リードもしくはライトを実行したあとで、スケジューラは若干のディレイを強制的に入れ、特定のアプリケーションが次のディスクブロックにリクエストを出す時間を与える。このようなリクエストが(予想通り)来ると、別のリクエストに対応すべく移動させられるのではなく、ディスクヘッドが適切な位置に移動してこちらのリクエストに対応する。

エレベータで言えば、ビジネスブロックに多数の企業があって、それぞれが2階分を専有している状況を想像されたい。1人の会社員がある階で乗ってきた場合は、この人物が自分の会社が入っている次の階で降りる可能性は非常に高い。したがって、エレベーターはこの乗客が目的階のボタンを押すまで急いで次の階を通り越すのを待ちたいと考える。

このようなわずかな遅れも積み上がればシステムの待ち時間が若干増えるが、状況によっては、次の行き先を予測することで得られる効率の改善分が容易にそれを上回る。

「anticipatory」スケジューラは、外部リクエストに定期的に中断されないような作業に適している。データにシーケンシャルにアクセスする Web サーバーやワークステーションには便利だが、データにランダムにアクセスするデータベースサーバーには向かないという傾向がある。

cfq

cfq は「completely fair queuing (完全公平な列)」の略。このシステムでは、スケジューラが多数の内部リクエストキューを維持し、システム上で動作するプロセスが1つずつこれらのキューに割り当てられる。すると、このスケジュールがそのリクエストを各キューの先頭から取り出してディスパッチキューの中に入れる。ここではシーク時間が最小限になるよう並べられ、対応が行われる。次に、スケジューラは内部リクエストキューに戻り、これらのキューの先頭からリクエストを持ってきてディスパッチキューを埋めていく。

これは、エレベーターが1基しかなく、そこにテナントになっているオフィスごとに列を作るようなビルに似ている。エレベーターが1階に到着するたびに、特定の会社がエレベーターを占有しないよう、それぞれの会社のキューの先頭から順番に乗っていく。Cfq は中規模から大規模のマルチプロセッサシステムでうまく機能し、Red Hat Enterprise Linux などの Linux ディストリビューションのデフォルトスケジューラになっている。


今のスケジューラは以下のコマンドで確認する

# cat /sys/block/sda/queue/scheduler

noop anticipatory deadline [cfq]

こんな感じで出力されて、[]で囲まれているものが現在の値だ。

この値は動的に変更可能で、変更するには設定したいスケジューラ文字列を上記のsysファイルシステムに書き込むだけ。

# echo deadline > /sys/block/sda/queue/scheduler
# cat /sys/block/sda/queue/scheduler

noop anticipatory [deadline] cfq

書き込んだ瞬間からスケジューラが切り替わる。

SSDやioDriveなどではnoopがおすすめ