FIOによるストレージ性能評価の自動化
Linux環境において、ディスクのI/O性能を詳細に測定するためにはfio(Flexible I/O Tester)が標準的に利用されます。以下は、基本的なランダムおよびシーケンシャル性能を測定するための自動化スクリプトの構成例です。
#!/bin/bash
# 実行例: sudo ./storage_test.sh sda
TARGET_DEV="/dev/$1"
LOG_DIR="benchmark_results_$(date +%Y%m%d)"
mkdir -p "$LOG_DIR"
# 4K ランダムリード性能の測定
fio --ioengine=libaio --direct=1 --thread --group_reporting \
--name=rand_read_4k --filename=$TARGET_DEV --rw=randread --bs=4k \
--numjobs=8 --iodepth=256 --runtime=300 --time_based \
--output="${LOG_DIR}/4k_random_read.log"
# 4K ランダムライト性能の測定
fio --ioengine=libaio --direct=1 --thread --group_reporting \
--name=rand_write_4k --filename=$TARGET_DEV --rw=randwrite --bs=4k \
--numjobs=1 --iodepth=2 --runtime=300 --time_based \
--output="${LOG_DIR}/4k_random_write.log"
# 128K シーケンシャルリード性能の測定
fio --ioengine=libaio --direct=1 --thread --group_reporting \
--name=seq_read_128k --filename=$TARGET_DEV --rw=read --bs=128k \
--numjobs=1 --iodepth=128 --runtime=300 --time_based \
--output="${LOG_DIR}/128k_seq_read.log"
# 128K シーケンシャルライト性能の測定
fio --ioengine=libaio --direct=1 --thread --group_reporting \
--name=seq_write_128k --filename=$TARGET_DEV --rw=write --bs=128k \
--numjobs=1 --iodepth=128 --runtime=300 --time_based \
--output="${LOG_DIR}/128k_seq_write.log"
性能を最大限に引き出すための最適化手法
理論値に近いパフォーマンスを得るためには、実行環境やハードウェア設定の調整が不可欠です。
1. プリコンディショニング(事前書き込み)
SSDなどのフラッシュストレージでは、未使用状態と使用中の状態(Steady State)で性能が大きく異なります。正確な数値を出すために、テスト前に一定時間ランダム書き込みを行い、ドライブを安定した状態にします。
2. CPUアフィニティの設定
I/O処理のオーバーヘッドを削減するため、tasksetコマンドを使用して特定のCPUコアにジョブを固定します。これによりコンテキストスイッチによる性能低下を防ぎます。
# 0番から15番のコアを使用するように指定
taskset -c 0-15 fio --ioengine=libaio --thread --direct=1 ...
3. BIOSおよびシステム設定
- IOMMU: 有効にするとシーケンシャル性能が向上し、無効にするとランダム性能が改善される傾向があります(CPUアーキテクチャに依存)。
- CPU Prefetch: シーケンシャルな読み書きを向上させるために有効化を検討します。
- ハイパースレッディング: 通常は有効で問題ありませんが、極端な低レイテンシを求める場合は無効化が有利に働くことがあります。
RAID構成における性能理論値
RAIDレベルによって、構成ディスク数(N)に対するパフォーマンスのスケール効率が異なります。以下は一般的な期待値です(キャッシュ効果を除く)。
| RAIDレベル | シーケンシャルリード | シーケンシャルライト | ランダムリード | ランダムライト |
|---|---|---|---|---|
| RAID 0 | N倍 | N倍 | N倍 | N倍 |
| RAID 1 | N倍 | 1倍 | N倍 | 1倍 |
| RAID 5 | N倍 | (N-1)倍 | N倍 | N/4倍 |
| RAID 10 | N倍 | (N/2)倍 | N倍 | (N/2)倍 |
FIO主要パラメータの解説
テストの目的に応じて以下のフラグを調整します。
--ioengine=libaio: Linuxのネイティブ非同期I/Oを使用。--direct=1: OSのページキャッシュをバイパスし、デバイスに直接I/Oを発行。--bs: データ転送のブロックサイズを指定(4K, 128Kなど)。--iodepth: キューに貯めるI/Oリクエストの数。--numjobs: 並列実行するプロセスの数。--group_reporting: 複数ジョブの結果をまとめて表示。
データ集計の自動化
測定後のログから必要な数値(IOPSやスループット)を抽出し、CSV形式で保存する処理を組み込むことで、大量のテスト結果を効率的に管理できます。
#!/bin/bash
# IOPS表記(kなど)を数値に正規化する関数
normalize_iops() {
local raw_val=$1
if [[ $raw_val =~ ([0-9]+\.?[0-9]*)[kK] ]]; then
echo "${BASH_REMATCH[1]}" | awk '{print $1 * 1000}'
else
echo "$raw_val"
fi
}
# ログからBW(帯域幅)とIOPSを抽出
log_file="128k_seq_read.log"
throughput=$(grep -oP 'BW=\K\d+' "$log_file")
iops_raw=$(grep -oP 'IOPS=\K[0-9]+\.?[0-9]*[kK]?' "$log_file")
iops_final=$(normalize_iops $iops_raw)
echo "Throughput: ${throughput} MB/s, IOPS: ${iops_final}"