発端
業務上の種々の都合から、IO一回あたりのスループットを明確にする必要に駆られた。
勘違いしてたこと
一回あたりのIOはアプリケーションごとに固定値だと考えていた。
例えばOSが行うread/writeであれば、64KB * IOPSでスループットが算出できると思っていた。
(なぜファイルシステムのブロックサイズである4KBではなく、64KBだと思っていたのかは不明)
勘違いに気づいた理由
iostat -dx 1の出力結果を見て、rKB/sをr/sで割ったらなぜか512KB近い値が出た。
いくつかサンプルをとったところ、どうも4KB〜512KBの間で一回のIOあたりのスループットが推移しているようだった。
今のところわかったこと
- Linuxの一回あたりのIOは、扱うデータサイズによって変動する。(TCP/IP通信のように、継続したIOの中でサイズが上下する)
- LinuxのIOはIO Schedulerなるモジュールが管理している。
- IO Schedulerにはいくつか種類がある。
- noop
- deadline scheduler
- cfq
- その他いろいろ
- RHEL7の場合、SATA以外のデバイスに対してはdeadline schedulerがIOの管理を行う。
- 現状どのIO schedulerを使っているかは以下ファイルをcatすることで確認可能。
/sys/block/sd*/queue/scheduler
- 1IOあたりの最大値である"512KB"という値は、"max_sectors_kb"というファイルで確認可能。
/sys/block/sd*/queue/max_sectors_kb
- 当初はIO schedulerにnoopを選んだときのみmax_sectors_kbが設定として有効になる認識だったが、更に調べたところ、当該設定はIO schedulerに何を選んだかに依存しないっぽい?
参考サイト
http://tfcenturion.hatenablog.com/entry/2015/11/07/091307
http://cromwell-intl.com/linux/performance-tuning/disks.html
http://longwhiteclouds.com/2016/03/06/default-io-size-change-in-linux-kernel/
https://martincarstenbach.wordpress.com/2013/07/03/increasing-the-maximum-io-size-in-linux/