雑多なインフラエンジニア日記

技術ブログでっす~

EBS IOPSのベンチマークスクリプト

最近流行っている(?)EBSのベンチマーク用スクリプトを作ってみました。

そもそものきっかけは、OS起動直後&初回の読み書き用のファイル
作成時は、極端にIOPSが悪いように見受けられたので、ベンチマーク
を簡素化するために作成しました。
何度も試行するのは面倒だったので。

# 需要があるかは定かではありません・・・。

IOPSについての前提知識 (P34以降)

http://www.slideshare.net/AmazonWebServicesJapan/aws-16148274

fio導入 (AmazonLinuxの場合)

レポジトリはepelになります。

yum --enablerepo=epel list|grep fio
yum --enablerepo=epel -y install fio.x86_64


ベンチマークスクリプトの使用方法

・スクリプトに渡す引数は、6つ必要です。
./fiop.sh [試行回数] [read/write/randread/randwrite] [BlockSize] [FileSize] [Threds数] [IOPS or Bandwidth]

・実行例

$ ./fiop.sh 10 read 4k 1GB 4 IOPS

上記ですと、シーケンシャルreadを10回試行し、IOPS平均値を取得、
BlockSizeは4k、FileSizeは1GB、Threds数は4、となります。

書き込み対象のディレクトリは/tmpになります。
試行時のログは、カレントディレクトリに出力されます。

ベンチマークスクリプト (fiop.sh)
#!/bin/bash

# Maximum number of runs
MAX_CNT=$1

# read , write , randread , randwrite
IO=$2

# Block Size (ex) 4k , 32m
BS=$3

# File Size (ex) 1G
FSIZE=$4

# Threads (ex) 4
JOBS=$5

# IOPS or Bandwidth
PROC=$6

# Initialize Counter
CNT=0
TOTAL=0
SCA=3
FLG=0

# Set Env
FNAME=/tmp/io-test


#-------------------------------------
# MAIN
#-------------------------------------
printf "\n<<fio $IO start>>\n\n"
printf "COUNT\t$PROC\n"

while [ $CNT -lt $MAX_CNT ] ; do

        CNT=`expr $CNT + 1`
        IO_PERF=`fio -filename=$FNAME -direct=1 -rw=$IO -bs=$BS -size=$FSIZE -numjobs=$JOBS -runtime=10 -group_reporting -name=file1 -output=./$IO-$CNT.log`

        if [ $PROC == "IOPS" ] ; then
                STAT=`grep iops ./$IO-$CNT.log | awk -F"iops=" '{print $2}' | awk -F" ," '{print $1}'`
        elif [ $PROC == "Bandwidth" ] ; then
                STAT=`grep aggrb ./$IO-$CNT.log | awk -F"aggrb=" '{print $2}' | awk -F"/s," '{print $1}'`
                FLG=1
        else
                printf "\nargument error\n"
                exit 1
        fi

        printf "$CNT\t$STAT\n"


        # Only Badwidth (KB)
        if [ $FLG -eq 1 ] ; then
                if `echo "$STAT" | grep KB > /dev/null 2>&1` ; then
                        STAT=`echo "$STAT" | sed 's/KB//g'`
                elif `echo "${STAT}" | grep MB > /dev/null 2>&1` ; then
                        STAT=`echo "$STAT" | sed 's/MB//g'`
                        STAT=`expr $STAT * 1024`
                elif `echo "${STAT}" | grep GB > /dev/null 2>&1` ; then
                        STAT=`echo "$STAT" | sed 's/GB//g'`
                        STAT=`expr $STAT * 1024`
                fi
        fi


        TOTAL=`scale=$SCA ; echo "$TOTAL + $STAT" | bc`

        if [ $CNT -eq $MAX_CNT ] ; then
                AVG=`scale=$SCA ; echo "$TOTAL / $CNT" | bc`
                if [ $FLG -eq 0 ] ; then
                        printf "\n\e[36mAverage $AVG iops\e[m\n"
                elif [ $FLG -eq 1 ] ; then
                        printf "\n\e[36mAverage $AVG KB/s\e[m\n"
                fi
        fi

done

exit 0
 


実行例
$ ./fiop.sh 10 read 4k 2G 4 IOPS

<<fio read start>>

COUNT   IOPS
1       9435
2       9665
3       9542
4       9166
5       8523
6       8303
7       9779
8       9797
9       8889
10      9568

Average 9266 iops

$ ./fiop.sh 10 read 32m 2G 4 Bandwidth

<<fio read start>>

COUNT   Bandwidth
1       108145KB
2       112452KB
3       113075KB
4       112676KB
5       109522KB
6       108736KB
7       109010KB
8       104252KB
9       105288KB
10      109079KB

Average 109223 KB/s



実際にインスタンスタイプ、EBSOptimized ON/OFF、PIOPSあり/なし
などで試行した結果は後日ということで・・・。

実際やってみて感じたこと


・PIOPSを指定しないほうがIOPSの性能が高いが、バーストのばらつきはある。

・前段でキャッシュ機構が働いていそう。

・安定化を求めるなら、PIOPS指定をしたほうが良い。
何故なら、PIOPSは指定したIOPS数を保証(確保)することが目的の為。
(バーストはほぼせず、指定値でキャップされる。)

・EBSOptimized は、ストレージ用通信を分離するのが目的なので、
IO性能には影響がほぼなかった。
しかし、PIOPSはEBSOptimizedを使用するのが前提なので、使用するのが吉。
PIOPSのみを使用するのは非推奨とされている。

インスタンスタイプにIO性能が左右される。
→ IO性能ではなく、インスタンス間の通信帯域の間違いでした。