SSブログ
エステ

まだファイルサーバのパフォーマンス向上の余地あり?? [他パフォーマンス改善]

各種ベンチマークを取ってきましたが、
ローカルのディスクアクセスが

Sequential Write: 210 MB/sec くらい
Sequential Read: 240 MB/sec くらい

という結果に対して、

ネットワーク越しのディスクアクセスが

Sequential Write: 70~90 MB/sec くらい
Sequential Read: 85~110 MB/sec くらい

ですので、もうちょっとパフォーマンス向上の余地はあるのでは?
と思う次第なのです。

ネットワークが1000Mbbsですので、125MB/secです。
これで頭打ちになっている感があります。

そこで。

Boding

NICを複数束ねて、冗長化と負荷分散に備える方法です。

しかーし、これには、スイッチングハブがポートトランキングに
対応している必要があります。

ですが、ものは試しです(^ ^;)

早速ですが、コマンドが足りないので、追加します。
ifenslaveなるbondデバイスにNICを登録するコマンドが入っていません。

# apt-get install ifenslave

次に設定。

# vi /etc/modprobe.d/bonding
と新たに、ファイルを作り、下記の設定を書き込みます。

options bonding mode=0 miimon=100

さらに、

#vi /etc/modules

で、

loop
lp

となっているところに、

bonding

を追記します。

あとはbondインターフェースの定義を行うだけです。

# vi /etc/network/interfaces

--
auto eth1
iface eth1 inet static

address 192.168.1.10
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
gateway 192.168.1.1
dns-nameservers 192.168.1.1
--

などとなっている箇所を

--
auto bond0
iface bond0 inet static

address 192.168.1.10
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
gateway 192.168.1.1
dns-nameservers 192.168.1.1
slaves eth1 eth2
--

こんな感じに書き換えます。

# ifconfig -a

で、eth2が認識されていることを確認します。

そして、再起動します。

これでOKです♪

ifconfigすると、bondインターフェースに続き、eth1,eth2インターフェースが
表示されます。



ところで、モジュールだけ再読み込みするってできないのかしら??
少し調べてみましたが、わかりませんでした。。


そういえば、この、eth1とかeth2とかってなんか気持ち悪いですね。
数字が1から始まっているあたり。。
・・しらべてみると、このファイルで定義されているようです。

/etc/udev/rules.d/70-persistent-net.rule

ここのNAME="eth1"を書き換えるといいみたいです。
早速書き換えます。二度手間ですが、/etc/network/interfacesも再度書き換え。

そして、再起動。

よかった(*^_^*)ちゃんと書き換わっていました[揺れるハート]

さて、これでベンチマークしてみます。

結果はまた次回。

そういえば、単体ベンチマークやっていなかったです。CG-HDC4EU3500 [CG-HDC4EU3500]

ネットワーク越しのベンチマークはやっていたのですが、
あまり興味がなかったのか、
CG-HDC4EU3500+HDS722020ALA330×4本 でRAID10構成とした際の
ローカルでの読み書きのベンチマークをやっていなかったので、ちょっと
やってみます♪

まずはbonnei++で。

Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
ss               4G   515  98 222622  44 94591  24  1934  94 240480  27 201.8   4
Latency             21513us     258ms     450ms   23564us   66941us    2159ms
Version  1.96       ------Sequential Create------ --------Random Create--------
ss                  -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16 13549  25 254904  99 54590  71 41479  75 310027  98 54502  71
Latency              5360us    1344us     835us     287us      77us      51us

⇒ Sequential Write: 222.622 MB/sec
⇒ Sequential Read: 240.480 MB/sec

ということでしょうか。

なんとなく怪しいので、ddコマンドでも確認してみます。

■dd if=$DISK of=/dev/null bs=$BS count=$COUNT iflag=direct
$BS,$COUNTを変えて、Readスピード測定
10回測定平均
Sequential Read (Block size:4KBytes) 23.18 MB/sec
Sequential Read (Block size:16KBytes) 74.65 MB/sec
Sequential Read (Block size:64KBytes) 160.26 MB/sec
Sequential Read (Block size:256KBytes) 233.38 MB/sec
Sequential Read (Block size:1024KBytes) 246.55 MB/sec

■dd if=/dev/zero of=$DIR/writetest_${BS}_$i bs=$BS count=$COUNT oflag=direct
$BS,$COUNTを変えて、Writeスピード測定
10回測定平均
Sequential Write (Block size:4KBytes) 9.13 MB/sec
Sequential Write (Block size:16KBytes) 40.06 MB/sec
Sequential Write (Block size:64KBytes) 125.36 MB/sec
Sequential Write (Block size:256KBytes) 198.75 MB/sec
Sequential Write (Block size:1024KBytes) 208.98 MB/sec

# $DISK,$DIRはそれぞれ、ターゲットのパーティションとディレクトリを指定します。

bonnie++でも、ddでもだいたい同じですか。

ちなみに、bonnie++の1.03系は適切なオプションをつけて実行しないと
キャッシュが効いて数値が大きく出るので注意が必要です[あせあせ(飛び散る汗)]



何度もやってるとさすがに疲れてきたので、スクリプト書きました。
見よう見まねで、しかも、かなーりテキトーに書きましたので、参考程度に。。
ながーいです[たらーっ(汗)]

もっとスマートに書けるんだろうなぁ(^^;)



------------ddコマンドでベンチマークするスクリプト ここから

#!/bin/bash
# HDD Benchmark Test 
# ver. 0.01
# Copyright (R) nao
#

# 文字列から小数へ変換する関数の定義
text2float()
{
# 整数部分と小数部分に分解
INT_TXT=`echo "$1" | cut -d'.' -f1` # 整数部分のテキスト
FLO_TXT=`echo "$1" | cut -d'.' -f2` # 小数部分のテキスト

# 初期化
M=0 # 小数桁数
INT=0 # 整数部分
FLO=0 # 小数部分
NUM=0 # 浮動小数点数化した$1

# INT_TXTからINTを生成
INT=`expr $INT_TXT + 0`

# FLO_TXTからFLOを生成
while :
do
# FLO_TXTの一文字目を取得
FIRST_TXT=`echo "${FLO_TXT}" | cut -c1`
# FIRST_TXTが""でない場合を小数化
if [ "$FIRST_TXT" = "" ]; then
break
else
FIRST=`expr $FIRST_TXT + 0`
FLO=`expr $FLO \* 10 + $FIRST`
M=`expr $M + 1`
FLO_TXT=`echo "${FLO_TXT}" | cut -c2-`
fi
done

while :
do
if [ $M -eq 0 ]; then
break
else
FLO=`echo "scale=6; ${FLO} / 10" | bc`
M=`expr $M - 1`
fi
done

NUM=`echo "scale=6; ${INT} + ${FLO}" | bc`
echo $NUM
}


# 読み取りベンチマークを実行する関数の定義
rbench()
{
# 一時ファイルの初期化
cat /dev/null >"${DIR}/HDDBench_Tmp.txt"

# 読み書き速度の初期化
SPEED=0
# 読み書き速度のN回和の初期化
SUM=0

# N1回のテスト実行
for i in `seq 1 $N1`
do
echo -n "="
RESULT=`dd if=$DISK of=/dev/null bs=$BS count=$COUNT iflag=direct 2>&1`
echo "$RESULT" >"$DIR/HDDBench_Tmp.txt" # 値取得用一時ファイルへ書き込み
echo "$RESULT" >>"$DIR/HDDBench_Tmp2.txt" # デバッグ用一時ファイルへ書き込み
VOL=`awk '(NR == 3){ print $1 }' $DIR/HDDBench_Tmp.txt` # 読み書き量(テキスト)
TIME=`awk '(NR == 3){ print $6 }' $DIR/HDDBench_Tmp.txt` # 読み書き時間(テキスト)
VOL=`expr $VOL + 0` # 読み書き量(数値)
TIME=`text2float $TIME` # 読み書き時間(数値)
SPEED=`echo "$VOL / $TIME" | bc` # 読み書き速度
echo "$SPEED" >>"$DIR/HDDBench_Tmp2.txt" # デバッグ用一時ファイルへ書き込み
SUM=`expr $SUM + $SPEED` # 読み書き速度のN回和
sleep 5
echo -n "+"
done

echo -n "  Done.      "

# 平均の読み書き速度の計算
SPEED=`expr $SUM / $N1`

# 適切な単位の計算への置き換え
if [ $SPEED -ge 1000000 ]; then
SPEED=`echo "scale=2; $SPEED / 1000000" |  bc`
SPEED=`echo "$SPEED" MB/sec`
elif [ $SPEED -lt 1000000 -a $SPEED -ge 1000 ]; then
SPEED=`echo "scale=2; $SPEED / 1000" | bc`
SPEED=`echo "$SPEED" KB/sec`
else
SPEED=`echo "$SPEED" B/sec`
fi
echo  $SPEED
}



# 書き込みベンチマークを実行する関数の定義
wbench()
{
# 一時ファイルの初期化
cat /dev/null >"${DIR}/HDDBench_Tmp.txt"

# 読み書き速度の初期化
SPEED=0
# 読み書き速度のN回和の初期化
SUM=0

# N1回のテスト実行
for i in `seq 1 $N1`
do
echo -n "="
RESULT=`dd if=/dev/zero of=$DIR/writetest_${BS}_$i bs=$BS count=$COUNT oflag=direct 2>&1`
echo "$RESULT" >"$DIR/HDDBench_Tmp.txt" # 値取得用一時ファイルへ書き込み
echo "$RESULT" >>"$DIR/HDDBench_Tmp2.txt" # デバッグ用一時ファイルへ書き込み
VOL=`awk '(NR == 3){ print $1 }' $DIR/HDDBench_Tmp.txt` # 読み書き量(テキスト)
TIME=`awk '(NR == 3){ print $6 }' $DIR/HDDBench_Tmp.txt` # 読み書き時間(テキスト)
VOL=`expr $VOL + 0` # 読み書き量(数値)
TIME=`text2float $TIME` # 読み書き時間(数値)
SPEED=`echo "$VOL / $TIME" | bc` # 読み書き速度
echo "$SPEED" >>"$DIR/HDDBench_Tmp2.txt" # デバッグ用一時ファイルへ書き込み
SUM=`expr $SUM + $SPEED` # 読み書き速度のN回和
sleep 5
echo -n "+"
done

echo -n "  Done.      "

# 平均の読み書き速度の計算
SPEED=`expr $SUM / $N1`

# 適切な単位の計算への置き換え
if [ $SPEED -ge 1000000 ]; then
SPEED=`echo "scale=2; $SPEED / 1000000" |  bc`
SPEED=`echo "$SPEED" MB/sec`
elif [ $SPEED -lt 1000000 -a $SPEED -ge 1000 ]; then
SPEED=`echo "scale=2; $SPEED / 1000" | bc`
SPEED=`echo "$SPEED" KB/sec`
else
SPEED=`echo "$SPEED" B/sec`
fi
echo  $SPEED
}



################ ベンチマーク処理の前処理 #################

# 実行オプションの取得
while getopts vn:p:d: opt
do
case $opt in
"n" ) N1=$OPTARG;; # ベンチマークで平均をとる実行回数
"p" ) DISK=$OPTARG;; # ターゲットパーティション 例 /dev/sda1
"d" ) DIR=$OPTARG;; # ターゲットディレクトリ 例 /st1/nao/tmp
"v" ) V=1;; # デバッグモード:一時ファイルを消さない
* ) echo "Usage: $hb [-v] [-n VALUE] [-t partition] [-d directory]" 1>&2
exit 1 ;;
esac
done

# オプション未指定の場合
if [ -z $N1 ]; then
N1=5
fi

if [ -z $DISK ]; then
DISK=/dev/sda1
fi

if [ -z $DIR ]; then
DIR=/tmp
fi


# 古い一時ファイルの削除
if [ -e $DIR/writetest* ]; then
rm -rf $DIR/writetest*
fi

# 一時ファイルの作成
touch "$DIR/HDDBench_Tmp2.txt"

# 一時ファイルの初期化
cat /dev/null >"$DIR/HDDBench_Tmp.txt"
cat /dev/null >"$DIR/HDDBench_Tmp2.txt"

# ベンチマークテスト結果ファイルの作成
touch "$DIR/HDDBench_TestResult.txt"




################ ベンチマークシーケンス #################
echo $'\n'
echo Starting HDD Bench Mark Test ver. 0.01
echo Start : `date`

echo HDD Bench Mark Test ver. 0.01 >"$DIR/HDDBench_TestResult.txt"
echo `date` $'\n' >>"$DIR/HDDBench_TestResult.txt"



###### 読み取りテスト
# ブロックサイズと読み書き回数の定義

SET=("4K" "25000" "16K" "6250" "64K" "1563" "256K" "3907" "1024K" "977")

for i in 0 2 4 6 8

do
BS=${SET[$i]}
COUNT=${SET[$i+1]}

# 画面への表示
echo $'\n'
echo Testing Sequential Read \(Block size:${BS}Bytes\)
rbench

# ベンチマークテスト結果ファイルへの保存
echo Sequential Read \(Block size:${BS}Bytes\) $SPEED >>"$DIR/HDDBench_TestResult.txt"
done



###### 書き込みテスト

for i in 0 2 4 6 8

do
BS=${SET[$i]}
COUNT=${SET[$i+1]}

# 画面への表示
echo $'\n'
echo Testing Sequential Write \(Block size:${BS}Bytes\)
wbench

# ベンチマークテスト結果ファイルへの保存
echo Sequential Write \(Block size:${BS}Bytes\) $SPEED >>"$DIR/HDDBench_TestResult.txt"
done


#################################



# すべての作業終了表示
echo $'\n' 
echo "All Bench Mark Test Finished."
echo Finished : `date`
echo $'\n' 

# デバッグモードでない場合は一時ファイルを消さない
if [ "$V" = "1" ]; then
exit 0
fi

# 一時ファイルの削除
rm -rf $DIR/HDDBench_Tmp.txt*
rm -rf $DIR/HDDBench_Tmp2.txt*
rm -rf $DIR/writetest*

exit 0

------------ここまで

ddコマンドを調べていると、oflag/iflagでsync,directの指定している箇所が
よくわかりませんでしたが、比較的まともな値のでるdirectの方を使っています。
syncにすると何かがキャッシュされているのか、3GB/secとかはじき出しちゃいます[たらーっ(汗)]
syncの意味よくわかりません。。

このスクリプトを適当なファイル名bench.shとかで保存して
chmod 755とかして実行権限を与えてると使えます。
あ、保存した時の改行コードに注意して下さい。LFで。
あと、シェルスクリプトで小数計算するためのbcが必要です。
# apt-get install bc
してください。
Write Testのために2.3GBほどのディスクスペースが必要です。

使い方は、こんな感じです。

$./bench.sh -n 10 -p /dev/sda1 -d /st1/nao/tmp

とするとブロックサイズを4KB,16KB,64KB,256KB,1024KBで100MBまたは
1GBぶん読み書きを、

-p フラグで指定したパーティションの
-d フラグで指定したディレクトリで
-n フラグで指定した回数実施し、その平均を計算して、
-d フラグで指定したディレクトリに
HDDBench_TestResult.txt というファイル名で実行結果を保存します。

これを使って何が起こっても知りません(^ ^;)



この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。