I/Oスケジューリング

はじめに

第15章はじめに

多くの場合、システムのパフォーマンスには、I/Oのスケジューリングの最適化が大きく関わっています。多くの（しばしば競合する）要因が、動作に影響を与えます。これには、ハードウェア アクセス時間の最小化、ストレージ メディアの消耗の回避、データの整合性の確保、I/Oを行う必要があるアプリケーションへのタイムリーなアクセスの許可、重要なタスクの優先順位付けなどが含まれます。Linuxは、選択可能なさまざまなI/Oスケジューラを提供します。各スケジューラには、調整可能なパラメータと、I/Oパフォーマンスのレポートと分析を行う多数のユーティリティがあります。


学習目標
この章の終わりまでに、次のことができるようになります。

I/Oスケジューリングの重要性と満たす必要がある競合要件を説明できます。
Linuxで使用可能なオプションを明示して対比できます。
CFQ（Completely Fair Queue）とDeadlineのアルゴリズムを理解できます。


I/Oスケジューリング

ディスクのボトルネックとI/Oスケジューリング
I/Oスケジューラは、汎用ブロック レイヤーと低レベルの物理デバイス ドライバ間のインターフェイスを提供します。VM（仮想メモリ）レイヤーと VFS（仮想ファイルシステム）レイヤーの両方が、ブロック デバイスにI/O要求を送ります。これらの要求をブロック デバイスに渡す前に優先順位を付けて順序付けるのが、I/Oスケジューリング レイヤーの仕事です。ハードウェアのアクセス時間、レイテンシ、デッドライン、公平性、効率のバランスを取る必要があります。最新のSSDでは要件が根本的に変わる可能性があります。

I/O スケジューリング アルゴリズムは、特定の（場合によっては競合する）要件を満たす必要があります。

ハードウェアのアクセス時間を最小限に抑える必要があります。つまり、ディスク上の物理的な場所に応じてリクエストを並べる必要があります。このことは、要求が物理的な順番でペンディング キューに挿入されるエレベータ方式につながります。
できる限り連続した領域を確保するために、可能な限りリクエストをマージする必要があります。これにより、ディスク アクセス時間が最小限に抑えられます。
要求は可能な限り低いレイテンシで行われる必要があります。実際、場合によっては、（デッドラインという意味で）決定論の考え方が重要になる場合があります。
通常、書き込み操作は、プロセスを停止することなく、キャッシュからディスクへの移動を待つことができます。しかし、読み取り操作ではほとんどの場合、プロセスがその完了を待ってから先に進む必要があります。書き込みより読み取りを優先すると、並列性とシステムの応答性が向上します。
プロセスは、公平に、もしくは少なくとも意識的に優先順位を付けて、I/O帯域幅を共有する必要があります。I/Oレイヤーの全体的なパフォーマンスが低下する場合でも、プロセスのスループットが過度に低下することはありません。


I/Oスケジューラの選択
要求同士が競合する可能性があるため、ワークロードごとに異なるI/Oスケジューラを使用する場合があります。たとえば、大規模なデータベース サーバーとデスクトップ システムが良い例です。さらに、ハードウェアが異なると違う戦略を要求する場合があります。柔軟性を提供するために、Linuxカーネルはオブジェクト指向のスキームを採用しており、さまざまな必要機能へのポインタがデータ構造で提供されます。次のように、カーネル コマンド ラインで選択できるものもあります。

linux ... elevator=[bfq|deadline-mq|kyber|none]

少なくとも1つのI/Oスケジューリング アルゴリズムをカーネルでコンパイルする必要があります。有用なものは時代とともに変化し、Linuxカーネルのバージョン 5.0では大幅な見直しが行われています。

デフォルトの選択は、コンパイル構成オプションで行います。カーネル 2.6.18より前のカーネルでは、ASであり、その後CFQになり、現在はdeadline-mqですが、ディストリビューションごとに設定が異なる場合があります。デバイスごとに異なるI/Oスケジューラを使用することも可能です。

以下のコマンドで使用可能なI/Oスケジューラを確認できます（ディスクが/dev/sdaの場合）。

$ cat /sys/block/sda/queue/scheduler
noop [deadline] cfq           # Before kernel version 5.0
none bfq kyber [mq-deadline]  # After kernel version 5.0

（スーパーユーザーとして）設定を変更する場合：

# echo bfq > /sys/block/sda/queue/scheduler
$ cat /sys/block/sda/queue/sheduler
none [bfq] kyber mq-deadline

スケジューラ固有の調整パラメータは、/sys/block/sda/queue/ioschedにあります。


I/OスケジューリングとSSDデバイス
フラッシュ メモリを使用してハードディスクをエミュレートするSSD（Solid State Drive）デバイスを段階的に導入することは、I/Oスケジューリングにとって重要な意味があります。

このようなデバイスは、エレベータ スキームを必要とせず、ウェアレベリング機能によって、書き込み／消去のサイクルが制限されているデバイスで特定のブロックに利用が偏らないようにI/Oを分散します。

以下のように/sys/block/<device>/queue/rotationalを調べることで、デバイスがSSDであるかどうかを確認できます。

$ cat /sys/block/sda/queue/rotational
1

$ cat /sys/block/sdb/queue/rotational
0


デモ：I/O スケジューラ

このビデオは、I/Oスケジューラの簡単なデモを提供します。


CFQ（Completely Fair Queue）スケジューラ
CFQ（Completely Fair Queue）メソッドの目的は、要求を送るすべてのプロセス間でI/O帯域幅を均等に分散させることです。

理論的には、各プロセスには独自のI/Oキューがあり、デバイスへの途中で実際のリクエストを受信するディスパッチ キューと連携して動作しています。キューの数は（64で）固定されており、プロセスIDに基づいたハッシュ プロセスを使用して、要求の送信時にキューを選択します。 

リクエスト キューからの取り出しは、すべてのキューにおけるラウンドロビン スタイルで行われ、各キューはFIFO（(First In First Out）の順序で機能します。このため、処理は分散されます。過度のシーク操作を回避するため、ラウンド全体を選択し、実際のI/O要求がデバイスに発行される前にディスパッチ キューでソートします。

以下の例では、パラメータHZはカーネルが設定する数量であり、1秒あたりのjiffiesの数に対応します。カーネルはこのHZを時間の大まかな尺度として使用します。詳細には説明しませんが、時間単位HZ/2は0.5秒、5*HZは5秒などになります。

クリックして各ボックスを展開し、提供されている例の詳細を確認してください。

CFQの調整可能パラメータの例

quantum
サービスの1ラウンドでの最大キュー長。(Default = 4)

queued
キューごとのリクエストの最小割り当て。(Default = 8)

fifo_expire_sync
同期要求が処理されずFIFOで保留される時間。(Default = HZ/2)

fifo_expire_async
非同期要求が処理されずFIFOで保留される時間。(Default = 5 * HZ)

fifo_batch_expire
FIFOが時間切れになる比率。(Default = HZ/8)

back_seek_max
最大後方シークで単位はKB 。(Default = 16K)

back_seek_penalty
後方シークのペナルティ。(Default = 2)


Deadline スケジューラ
Deadline I/Oスケジューラは、全体的なパフォーマンスを改善し、個々のリクエストの大きなレイテンシを防ぐという2つの目的を持ち、リクエストを積極的に並べ替えます。すなわち、スタベーションを制限します。

リクエストごとに、カーネルは期限を付けます。読み取り要求は、書き込み要求よりも優先されます。

次の5つの個別のI/Oキューを持ちます。

開始するブロックを並べ換えるため、読み取り用と書き込み用の2つのソート キューを持ちます。
読み取り用と書き込み用の2つのFIFOキューを持ちます。これらのリストは、サブミットされた時間でソートされています。
5番目のキューは、デバイス ドライバ自体に渡す要求を含んでいます。これは、ディスパッチ キューと呼ばれます。
リクエストが最初の4つのキューから出され5番目（ディスパッチ キュー）に配置される方法は、まさにアルゴリズムの芸術と言えます。

Deadlineスケジューラで利用可能な調整可能パラメータの詳細については、クリックして各カードを反転して見てください。

read_expire
読み取りリクエストの実行が保証される時間（ミリ秒単位）。(Default = HZ/2 = 500)

write_expire
書き込みリクエストの実行が保証される時間（ミリ秒単位）。(Default = 5 * HZ = 5000)

writes_starved
書き込みよりも読み取りを優先するリクエスト数。(Default = 2)

fifo_batch
処理期限になったときに、ソートされたスケジューラ リストからディスパッチ キューに移動するリクエストの数。(Default = 16)

front_merges
通常、連続するリクエストは次のブロックに続くため、バック マージはフロント マージよりも一般的です。必要になる可能性が低いことがわかっている場合には、このパラメーターを0に設定するとフロント マージが無効になり、性能を上げることができます。(Default = 1)


演習

課題 15.1: I/Oスケジューラの比較

🚩
以下のPDFドキュメントに埋め込まれた外部URLにアクセスする場合は、常に右クリックして新しいタブまたはウィンドウで開いてください。直接クリックしてURLを開こうとすると、コース ウィンドウ／タブが閉じます。

Exercise 15.1: Comparing I/O Schedulers

We provide a script which is to be used to compare I/O schedulers which can be extracted from your downloaded SOLUTIONS file as labiosched.sh.

lab iosched.sh
#!/bin/bash
NMAX=8
NMEGS=100
[[ -n $1 ]] && NMAX=$1
[[ -n $2 ]]  && NMEGS=$2

echo Doing: $NMAX parallel read/writes on: $NMEGS MB size Files

TIMEFORMAT="%R   %U  %S"

##############################################################
# simple test of parallel reads
do_read_test(){
for n in$(seq1$NMAX);do
cat file$n > /dev/null &
done
# wait for previous jobs to finish
wait
}

# simple test of parallel writes
do_write_test(){
for n in$(seq1$NMAX);do
[[ -f fileout$n ]] && rm -f fileout$n
(cp file1 fileout$n && sync) &
done
# wait for previous jobs to finish
wait
}

# create some files for reading, ok if they are the same
create_input_files(){
[[ -f file1 ]] || ddif=/dev/urandom of=file1 bs=1M count=$NMEGS
for n in$(seq1$NMAX);do
[[ -f file$n ]] || cp file1 file$n
done
}

echo -e"\ncreating as needed random input files"
create_input_files

##############################################################
# begin the actual work

# do parallel read test
echo -e"\ndoing timings of parallel reads\n"
echo -e" REAL    USER    SYS\n"
#for iosched in noop deadline cfq ; do
for iosched in\
$(cat /sys/block/sda/queue/scheduler | sed -e s/'\['//g -e /'\]'//g);do
echo testing IOSCHED = $iosched
echo $iosched > /sys/block/sda/queue/scheduler 
cat /sys/block/sda/queue/scheduler
#    echo -e "\nclearing the memory caches\n"
echo 3> /proc/sys/vm/drop_caches
time do_read_test
done

##############################################################
# do parallel write test
echo -e"\ndoing timings of parallel writes\n"
echo -e" REAL    USER    SYS\n"
forviosched in\
$(cat /sys/block/sda/queue/scheduler | sed -e s/'\['//g -e s/'\]'//g);do
echo testing IOSCHED = $iosched
echo $iosched > /sys/block/sda/queue/scheduler
cat /sys/block/sda/queue/scheduler
time  do_write_test
done
##############################################################

If you are taking the online self-paced version of this course, the script is available for download from your Lab screen.Because changing the I/O scheduler is a privileged operation, you will have to run it as:

$ sudo ./lab_iosched.h [# reads/writes (NMAX)] [file size in MB (NMEGS)]

How it works

The script:
•  Cycles through the available I/O schedulers on a hard disk while doing a configurable number of parallel readsand writes of files of a configurable size.  (Note that exactly which schedulers are available will depend on the kernel has been configured and compiled and may vary quite a bit from machine to machine.)
•  Tests reads and writes as separate steps.
•  Makes sure, when testing reads, it is actually reading from disk and not from cached pages of memory; the cacheis flushed out by doing (as root):
echo 3 > /proc/sys/vm/drop_caches
before doing the reads. The script does a cat into /dev/null to avoid writing to disk.
•  Makes sure all reads are complete before obtaining timing information; this is done by issuing a wait command under the shell.
•  Tests writes by simply copying a file (which will be in cached memory after the first read) multiple times simulta-neously. To make sure it has waited for all writes to complete before getting timing information, it issues a synccall.

The provided script takes two arguments. The first is the number of simultaneous reads and writes to perform. The second isthe size (in MB) of each file.

This script must be run as root as it echoes values into the/procand/sysdirectory trees.

Compare the results you obtain using different I/O schedulers.

Extra Credit
For additional exploring you might try changing some of the tunable parameters and see how results vary.


知識チェック

「第15章 - I/Oスケジューリング」を完遂しました。おめでとうございます。このクイズに答えて、これまでに学んだ概念の理解度をチェックしてください。

クイズ開始

問題 15.1
LinuxのデフォルトのI/Oスケジューラは何ですか？ 当てはまるものをすべて選択してください。

A. Completely Fair Queuing (CFQ)
B. Elevator
C. Deadline Scheduling
D. noop

問題 15.2
エレベータのスケジュール設定が不要なデバイスのカテゴリはどれですか？

A. SATA
B. ISE
C. SCSI
D. SAS
E. SSD

