最速最安WEB画像サーバ構築術 - nginx + ServersMan




先日、運営しているサイトcocoの画像サーバを構築しました。昨今はVPSが500円程度で借りられる様になり、一人WEBサービス屋には本当にいい時代になりました。今回、選定対象にしたのは、以下3つの業者です。
- ServersMan(初期0円 / 月額490円 / メモリ256M / HDD 10G)
- S@@Ses(初期3000円 / 月額450円 / メモリ512M / HDD 50G)
- SAKURA Internet(初期0円 / 月額980円 / メモリ512M / HDD 20G)
料金やスペックについて、2010/12/19時点のものを記載しました。キャンペーン適用や保障スペックなど細かい注意点がありますので、詳しくは各社サイトでご確認下さい。
シミュレーション
処理数値目標は、月間1億アクセスとしました。これは、1ページ当たり50画像掲載だったとすると、200万PV。ブラウザキャッシュやCSS Spliteの導入を考えると、もっと多くのPVに絶えられると言えるでしょう。月間の数値が決まったら、後は秒間アクセスを出すだけです。
1億 / 30日 / 24時間 / 60分 / 60秒 ≒ 39(per/sec)
更に、アクセスは1日を通して平均的である事は稀ですので、ピークタイムを平均の倍にすると「79(per/sec)」。今回はこれを目標数値とします。
Apache
まずは、使い慣れたApache(2.2.17)をインストールしてみました。Apacheは、標準モジュールによるオーバヘッドが大きいので、画像サーバに必要なモジュールのみとしました。以下、コンパイルオプション。
./configure --prefix=/usr/local/apache --with-mpm=worker --disable-option-checking --disable-FEATURE --disable-authn-file --disable-authn-default --disable-authz-host --disable-authz-groupfile --disable-authz-user --disable-authz-default --disable-auth-basic --disable-include --disable-filter --disable-charset-lite --disable-env --disable-setenvif --disable-version --disable-status --disable-autoindex --disable-asis --disable-cgid --disable-cgi --disable-negotiation --disable-dir --disable-actions --disable-userdir --disable-alias --disable-log-config
上記は「—disable-mime」以外の全標準モジュールを排除しています。Disk I/O軽減の為、アクセスログも吐きません(エラーログは、この設定で吐き出します)。Apacheの標準モジュールは、
./configure --help | grep disable
で確認できますので、viなりで必要な箇所を抽出すれば、簡単に「configure」オプションが作れます。後は一本道でインストールです。
$ make $ su # make install
httpd.conf は必要なもののみ書くようにしています。
Listen 80 ServerName example.com ServerRoot /usr/local/apache DocumentRoot /var/www/htdocs User nobody Group nobody ServerLimit 2 StartServers 2 MaxClients 32 MinSpareThreads 2 MaxSpareThreads 2 ThreadsPerChild 16 KeepAlive off <Directory /> Options FollowSymLinks AllowOverride None </Directory>
パフォーマンスに影響するポイントは、以下の通りです。
- SymLinkを許可する(許可しないとアクセス毎に通常ファイルかシンボリックリンクかの判断が入ってしまいます)
- AllowOverrideを無効(上に同じくアクセス毎に.htaccessらが使えるかの判断が入ってしまいます)
- KeepAliveはOff
何故、KeepAlive Offを推奨するかは、拙作「間違いだらけのWEBサーバ Keep-Alive」を御参照下さい。その他、MaxClients等のパラメータの説明は基本ですので省略します(と言いますか、この説明は無駄になる事がすぐ後で分かります)。
「さあ、モジュールも減量したし、まだまだApacheも現役でいけるでしょう」と思って、ベンチマークを取ってみたのですが。。。「allocate」エラー頻発。「おかしいなあ」と思って、Apacheを再起動しメモリ解放後、メモリ使用量を確認。
$ free -m
【Apache 起動前】
total used free shared buffers cached
Mem: 512 19 492 0 0 0
-/+ buffers/cache: 19 492
Swap: 0 0 0
【Apache 起動後】
total used free shared buffers cached
Mem: 512 202 309 0 0 0
-/+ buffers/cache: 202 309
Swap: 0 0 0
親プロセスを起動しただけでメモリ使用量がこんなに。そう。メモリが足りなかったのです。前述httpd.confのスレッド数が極端に少ないのも、実はメモリ使用率の切り分けの為に徐々に少なくしていったからなのでした。
nginx
256Mメモリ環境(ServersManの場合、256M保証/最大512M)においては、Apacheでは埒があかない事が分かりました。今度は、nginxをインストールしました(初体験)。
$ wget "http://www.nginx.org/download/nginx-0.8.53.tar.gz" $ tar zxvf nginx-0.8.53.tar.gz $ cd nginx-0.8.53 $ ./configure --prefix=/usr/local/nginx --without-pcre --without-http_rewrite_module --without-http-cache --without-http_gzip_module $ make $ su # make install
nginx.conf は、以下の通りです。
user nobody nobody;
worker_processes 5;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format null '';
access_log /dev/null null;
sendfile on;
keepalive_timeout 0;
server_tokens off;
server {
listen 80;
server_name localhost;
root /var/www/htdocs;
location / {
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
KeepAlive Off(keepalive_timeout 0;)と、アクセスログを吐かない様(access_log /dev/null null;)にしたぐらいで後は基本的な設定となっています。Apache同様、不要な機能を削除しようとマニュアルを熟読しようとも思ったのですが、まずは動かす事を優先しました。起動コマンドは以下。
# /usr/local/nginx/sbin/nginx
nginx 起動設定
起動スクリプトは簡単に以下の様なものにしました。
#!/bin/bash
#
# Startup script for the nginx
#
# chkconfig: 345 80 15
# description: Nginx web server.
# Source function library.
. /etc/rc.d/init.d/functions
start(){
/usr/local/nginx/sbin/nginx
}
stop(){
kill `cat /usr/local/nginx/logs/nginx.pid`
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 1
start
;;
*)
echo "Usage: $0 {start|stop|restart}"
esac
exit 0
後はLinuxの基本操作です。自動起動設定をした上で、OSを再起動し動作確認をします。
# chkconfig --add nginx # chkconfig nginx on # chkconfig --list | grep nginx # shutdown -r now
ベンチマーク
ベンチマークは、abを利用し、各VPSサーバ業者間のネットワーク経由で実行しました(正常アクセス程度に留めました。恐縮です!逮捕しないで下さい。)。
$ /usr/local/apache2/bin/ab -c 100 -n 1000 "http://example.com/logo.gif"
各社の数値の公開は差し控えますが、今回は、検証結果と料金・スペックなどの要素を元に総合判断し「ServersMan」を採用する事にしました。以下、ServersManでのabの結果参考値です。
Document Length: 3698 bytes Requests per second: 242.68 [#/sec] (mean)
「79(per/sec)」は軽くオーバーしています。 abでの負荷テスト中に、ブラウザでアクセスしても問題がない事も確認しました(ちなみに、ローカルホスト内でのabでは、Requests per second: 5811.32 [#/sec]といった具合)。
また、CPU/メモリ使用率共にほぼ未使用といった感じです。
$ free -m
total used free shared buffers cached
Mem: 512 23 488 0 0 0
-/+ buffers/cache: 23 488
Swap: 0 0 0
$ top -d1
Cpu(s): 1.0%us, 1.0%sy, 0.0%ni, 98.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
nginxは凄いですね。細かいチューニングも考える必要がありません。
最後に
後は、ネットワーク帯域や各社のF/Wなりの同時接続数制限をクリアしなければならない訳ですが、この辺りは、運用しながらレスポンス遅延が発生した段階で、VPS各社に増設&分散をさせていけばいいと思います(ちなみに、1億アクセスを目標数値にしましたが、そもそもこの規模のアクセスを発生させるWEBサービスを作る事が一番大変です^^;)。
それでは次回は、nginxでの画像サーバの構成案を含めた具体的な構築術を御紹介したいと思います。
- 251 http://b.hatena.ne.jp/hotentry
- 189 http://b.hatena.ne.jp/hotentry/it
- 184 http://reader.livedoor.com/reader/
- 126 http://www.ig.gmodules.com/gadgets/ifr?exp_rpc_js=1&exp_track_js=1&url=http://choichoi.sakura.ne.jp/hatena_bookmark.xml&container=ig&view=default&lang=ja&country=JP&v=dea496ad9b318fce&parent=http://www.google.co.jp&libs=core:core.io:core.iglegacy:
- 105 http://twitter.com/
- 63 http://www.google.co.jp/reader/view/
- 55 http://b.hatena.ne.jp/
- 55 http://www.google.com/reader/view/
- 43 http://d.hatena.ne.jp/
- 42 http://longurl.org
