apacheでサーバ負荷が高いときのリダイレクトについて実験

※ 2010/9/27 さらに実験してみた
http://d.hatena.ne.jp/toritori0318/20100927/1285591445




そもそもは「Twitterのくじらを実装するのはどういうのがスタンダードなのか?」という疑問。


軽くググってみると以下のようなページがヒット。

すると神の声が

http://twitter.com/fujiwara/status/24544644921
ですよねー。
とりあえずこういうときは
憶測するな、計測せよ!
ということで実験。

環境

os CentOS 5.3
apache 2.2.3
perl 5.8.8

apacheの環境はyumインストールからほぼデフォルト。
keepaliveをoffにしたくらい。

httpd.conf

下記のRewirteMapのコメントを付けたり外したりで
ベンチマーク取ってみました。

RewriteEngine on
#RewriteMap ldavg prg:/etc/httpd/loadaverage_uptime.pl
#RewriteMap ldavg prg:/etc/httpd/loadaverage_uptime.sh
#RewriteMap ldavg prg:/etc/httpd/loadaverage_pm.pl
RewriteMap ldavg prg:/etc/httpd/blank.pl
RewriteCond ${ldavg:} >3.00
RewriteRule ^/(.*)$ http://192.168.126.134/redirect.html [R,L]

RewriteMapのスクリプト

以下の4つのスクリプトを作成。

blank.pl

なにも処理しないスクリプト
RewriteMap自体にオーバーヘッドが発生しているかどうかの確認用。

#!/usr/bin/perl
use strict;
$| = 1;
while (<STDIN>) {
    print "0.00\n";
}
loadaverage_uptime.pl

参考URLのそのまま。外部コマンドとしてuptimeを実行している。

#!/usr/bin/perl
use strict;
$| = 1;

while (<STDIN>) {
    my ($ldavg1, $ldavg2, $ldavg3) = `uptime` =~ /load average:\s+([.0-9]+),\s+([.0-9]+),\s+([.0-9]+)/;
    print $ldavg1 + 0 . "\n";
}
loadaverage_uptime.sh

上記をshに置き換えたもの。

#!/bin/sh

while read i
do
 uptime | sed -e "s/.*load average: \([.0-9]*\), \+\([.0-9]*\), \+\([.0-9]*\)/\1/"
done
loadaverage_pm.pl

perlモジュールSys::Statistics::Linux::LoadAVGを利用したバージョン。

#!/usr/bin/perl

use strict;
use Sys::Statistics::Linux::LoadAVG;
$| = 1;

while (<STDIN>) {
    print Sys::Statistics::Linux::LoadAVG->new->get->{avg_1} . "\n";
}

abによるベンチマーク

「何も設定しない(RewriteEngine OFF)」+上記4パターンのabの結果を添付します。

ab -n 5000 -c 5 'http://192.168.126.136/'
何も設定しないバージョン
Requests per second:    1000 [#/sec] (mean)
blank.pl
Requests per second:    800 [#/sec] (mean)

topの様子

top - 03:44:55 up 36 min,  3 users,  load average: 1.51, 0.68, 0.42
Tasks: 134 total,   5 running, 129 sleeping,   0 stopped,   0 zombie
Cpu(s): 15.7%us, 47.1%sy,  0.0%ni,  1.0%id,  0.0%wa,  7.8%hi, 28.4%si,  0.0%st
Mem:    510552k total,   466104k used,    44448k free,    30056k buffers
Swap:  2064376k total,        0k used,  2064376k free,   300908k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 2386 root      18   0 22756 1512 1176 R  6.0  0.3   0:04.16 blank.pl
 2391 apache    15   0  180m 4028 1272 S  4.0  0.8   0:01.94 httpd
 2420 apache    15   0  180m 4028 1272 S  4.0  0.8   0:01.87 httpd
 2388 apache    15   0  180m 4028 1272 S  3.0  0.8   0:01.88 httpd
 2392 apache    15   0  180m 4032 1272 S  3.0  0.8   0:01.86 httpd
 2397 apache    15   0  180m 4032 1272 S  3.0  0.8   0:01.84 httpd
 2398 apache    15   0  180m 4020 1268 S  3.0  0.8   0:01.87 httpd
 2399 apache    15   0  180m 4020 1268 S  3.0  0.8   0:01.87 httpd
 2400 apache    15   0  180m 4032 1272 S  3.0  0.8   0:01.87 httpd
 2405 apache    15   0  180m 4028 1272 S  3.0  0.8   0:01.88 httpd
 2409 apache    15   0  180m 4028 1272 S  3.0  0.8   0:01.87 httpd
 2412 apache    15   0  180m 4020 1268 R  3.0  0.8   0:01.87 httpd
...
loadaverage_uptime.pl
Requests per second:    105 [#/sec] (mean)

topの様子

top - 04:02:33 up 37 min,  1 user,  load average: 2.41, 1.88, 1.54
Tasks: 130 total,   5 running, 125 sleeping,   0 stopped,   0 zombie
Cpu(s): 32.6%us, 59.5%sy,  0.0%ni,  0.0%id,  0.0%wa,  4.3%hi,  3.6%si,  0.0%st
Mem:    510552k total,   501928k used,     8624k free,    33244k buffers
Swap:  2064376k total,        0k used,  2064376k free,   322044k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
16838 root      25   0 22756 1648 1300 R 24.0  0.3   0:02.10 loadaverage_upt
17576 apache    18   0  208m  10m 1176 S  1.0  2.1   0:00.04 httpd
16851 apache    15   0  208m  10m 1268 S  0.7  2.1   0:00.02 httpd
17577 apache    18   0  208m  10m 1176 S  0.7  2.1   0:00.04 httpd
16842 apache    15   0  208m  10m 1268 S  0.3  2.1   0:00.02 httpd
16852 apache    15   0  208m  10m 1268 S  0.3  2.1   0:00.02 httpd
16855 apache    15   0  208m  10m 1268 S  0.3  2.1   0:00.03 httpd
16858 apache    15   0  208m  10m 1268 S  0.3  2.1   0:00.02 httpd
16859 apache    15   0  208m  10m 1268 S  0.3  2.1   0:00.02 httpd
16861 apache    15   0  208m  10m 1268 S  0.3  2.1   0:00.02 httpd
...
loadaverage_uptime.sh
Time per request:       80 [ms] (mean)

topの様子

top - 04:06:15 up 41 min,  1 user,  load average: 2.45, 2.25, 1.75
Tasks: 128 total,   3 running, 124 sleeping,   0 stopped,   1 zombie
Cpu(s): 35.0%us, 61.7%sy,  0.0%ni,  0.0%id,  0.0%wa,  1.3%hi,  2.0%si,  0.0%st
Mem:    510552k total,   463728k used,    46824k free,    64112k buffers
Swap:  2064376k total,        0k used,  2064376k free,   203792k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
21326 root      25   0 10792 1084  892 R 16.3  0.2   0:15.96 loadaverage_upt
21327 apache    15   0  208m  10m 1284 S  0.7  2.1   0:00.13 httpd
21330 apache    15   0  208m  10m 1284 S  0.7  2.1   0:00.12 httpd
21337 apache    15   0  208m  10m 1284 S  0.7  2.1   0:00.14 httpd
21345 apache    15   0  208m  10m 1284 S  0.7  2.1   0:00.12 httpd
loadaverage_pm.pl
Requests per second:    700 [#/sec] (mean)

topの様子

top - 03:51:08 up 26 min,  1 user,  load average: 2.90, 2.58, 1.34
Tasks: 123 total,   7 running, 116 sleeping,   0 stopped,   0 zombie
Cpu(s): 12.2%us, 53.8%sy,  0.0%ni,  0.0%id,  0.0%wa,  8.9%hi, 25.1%si,  0.0%st
Mem:    510552k total,   473728k used,    36824k free,    29644k buffers
Swap:  2064376k total,        0k used,  2064376k free,   307492k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 2753 root      18   0 23020 1952 1304 R  6.3  0.4   0:02.28 loadaverage_pm.
 2754 apache    15   0  207m  10m 1280 S  2.7  2.1   0:00.78 httpd
 2755 apache    15   0  207m  10m 1276 S  2.7  2.1   0:00.80 httpd
 2758 apache    15   0  207m  10m 1276 S  2.7  2.1   0:00.76 httpd
 2759 apache    15   0  207m  10m 1280 S  2.7  2.1   0:00.75 httpd
 2761 apache    15   0  207m  10m 1276 S  2.7  2.1   0:00.77 httpd
 2770 apache    15   0  207m  10m 1280 S  2.7  2.1   0:00.80 httpd
 2789 apache    15   0  207m  10m 1276 S  2.7  2.1   0:00.78 httpd
 2791 apache    15   0  207m  10m 1276 S  2.7  2.1   0:00.78 httpd
 2796 apache    15   0  207m  10m 1276 S  2.7  2.1   0:00.67 httpd
...

まとめ

- Requests per second(avg)
何も設定しない(RewriteEngine OFF) 1000
blank.pl 800
loadaverage_pm.pl 700
loadaverage_uptime.pl 105
loadaverage_uptime.sh 80

考察

外部コマンド叩く方式は予想通りというか約1/10の性能しか出ていません。
これはない。
topには出てきませんが、utimeのプロセスがぽこぽこ生成がされているのを確認しました。*1

しかしloadaverage_pm.plのバージョンではそこまで顕著なオーバーヘッドはありませんので
perlスクリプトperlモジュール使ったバージョンであれば普通に使える!かもしれませんね


ただし、この方法がスタンダードかどうかはわかりません><
ロードバランサ側でやるのがスマートな気がするけど
そういうロードバランサあるのかな?

*1:fork