SSI(Server Side Include)のWebサーバへのパフォーマンスへの影響って実際どうなのよ?という興味から、簡単にベンチマークを行ってみました。
前提
- SSI は IncludesNOEXEC オプションで動かす(コマンド実行なし)。
- このベンチマークは、差が出るかどうかを見るため。
- 実環境での負荷を図るための方針決定の指標とする。
ベンチマークの方法
概要
約20KB のHTMLページを
A. 単一の静的HTMLファイル
B. 2か所をSSIでの組み込み表示をした場合
のレスポンス速度を ApacheBench で測定。
SSIの設定
WebサーバはApache2.2。
Bのみ同じディレクトリ内の .htaccess に 「+IncludesNOEXEC」と「XBitHack on」を指定。
測定
Webサーバ側(ホストX)
%CPUと%MEMを5秒おきに記録(psコマンド)。
クライアント側(ホストY)
Apache 1.3.x に添付の ApacheBench を利用。
「-n 1000 -c 10」(同時接続 10、トータル 1000回リクエスト)、「-n 2000 -c 20」、「-n 3000 -c 30」のオプションで続けて実行。
ハードウェア環境
ホストX (Webサーバ側)
FreeBSD 6.3-RELEASE on HP KAYAK
メモリ: 96MB
CPU: Pentium II 266MHz
HD: UDMA33 7200rpm(?)
※ 超ボロ。差を見るのが目的という事で…。
ホストY (クライアント側)
FreeBSD 4.8-RELEASE on IBM x205
メモリ: 512MB
CPU: Celeron 1.8GHz
ネットワーク
ローカルネットワーク内で極力他のトラフィックを排除したが、完璧ではない。100BASE-T。
結果概要
(SSIなしに比して、SSIありの状態を記載。)
- レスポンスは約2倍に遅くなるが、ミリ秒単位の違い。
- CPU負荷が極端に増大する事は無いが、レスポンスに時間がかかる分、CPU利用時間が増える。
- 各リクエストの処理に時間がかかるため、立ち上がるスペアサーバの数が増加している時間帯が長い。
結果の考察(導入を検討する時に考えるべきこと)
- SSI利用前のアクセス状況でApacheのスペアサーバ数の余裕があるかどうか。
- スペアサーバのためのCPU、メモリの余裕があるかどうか。
- SSI 有効化の方法による影響の違いも考慮が必要。
httpd.conf に設定した場合、Apaceh 1.3.xで全ての .html をSSI 対象とした場合など、設定方法に合わせて同様の負荷テストが必要かも。 - (予想)レスポンス速度については、ディスクのI/Oがボトルネックになるのではないか。
結果データ
ApacheBenchの測定結果
%CPUと%MEM の比較
テスト用スクリプト
リクエストを投げるスクリプト(ホストYで利用)
AB=/usr/local/apache/bin/ab
URL=http://192.168.253.10/ssi/
LOG=ssi.log
$AB -n 1000 -c 10 $URL >> $LOG;
$AB -n 2000 -c 20 $URL >> $LOG;
$AB -n 3000 -c 30 $URL >> $LOG;
%CPUと%MEMを記録するスクリプト(ホストXで利用)
#コマンドを繰り返し実行する
#起動と終了は手動
while true
do
ps -ax -o pid,ppid,user,ruser,start,pcpu,rss,vsz,pmem,args >> pslog.log
sleep 5
done
psのログを解析するPerlプログラム
=pod
# ps で取った記録から www の分のステータスを抜き出す。
ログ形式(5秒ごとに ps の出力を記録)
PID PPID USER RUSER STARTED %CPU RSS VSZ %MEM COMMAND
0 0 root root 2:10PM 0.0 0 0 0.0 [swapper]
1 0 root root 2:10PM 0.0 260 768 0.3 /sbin/init —
597 578 www www 2:10PM 0.0 3264 5424 3.6 /usr/local/sbin/httpd -DSSL
598 578 www www 2:10PM 0.0 3264 5424 3.6 /usr/local/sbin/httpd -DSSL
このうち www の %CPU, RSS, VSZ, %MEM を5秒ごとに累計する
cat ps.log | ps_stat.pl > log.csv
=cut
use strict;
use warnings;
my ($time, %stat);
while (<>){
m/^\s*PID/ and $time++ and next; #5秒ごとに1増える
s/^\s*|\s*$//g;
my @stat = split(/\s+/, $_, 10);
$stat[2] eq ‘www’ or next; #2 = USER
$stat{“$time”}->{thread}++; #立ちあがっているプロセス数
$stat{“$time”}->{pcpu} += $stat[5];
$stat{“$time”}->{rss} += $stat[6];
$stat{“$time”}->{vsz} += $stat[7];
$stat{“$time”}->{pmem} += $stat[8];
}
#ヘッダ
binmode STDOUT;
print “count,sec,pcpu,rss,vsz,pmem,thread,pcpu/thd,rss/thd,vsz/thd,pmem/thd\r\n”;
foreach (sort {$a <=> $b} keys %stat){ #カウント順に並ぶ
printf(
“%d,%d,%.1f,%d,%d,%.1f,%d,%.1f,%d,%d,%.1f\r\n”,
$_,
$_*5,
$stat{$_}->{pcpu},
$stat{$_}->{rss},
$stat{$_}->{vsz},
$stat{$_}->{pmem},
$stat{$_}->{thread},
$stat{$_}->{pcpu}/$stat{$_}->{thread},
$stat{$_}->{rss}/$stat{$_}->{thread},
$stat{$_}->{vsz}/$stat{$_}->{thread},
$stat{$_}->{pmem}/$stat{$_}->{thread},
);
}