naoyaさんが公開されてるInside Hatena Bookmark’s Backend の資料などを読むと、mod_perlなサーバーやMySQLサーバーの選び方の参考になったりするわけですが、世の中を見渡してみても、静的コンテンツ(画像とか)を配信するサーバーの指南書らしきものはなかなか見あたりませんでした。
なので、経験を元に書いてみることにします。
弊社の画像配信サーバーには、平均10kbぐらい(たぶん)の画像が30万個ぐらいあって、それをDell PowerEdge 1750+lighttpdを使って配信してます。
以前は搭載メモリ1GBのサーバーを使っていたのですが、その時のvmstatがこのような感じ。
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 0 1 31368 55072 598708 119256 0 0 946 0 1573 1577 0 1 71 27 0 3 31368 54580 600728 119576 0 0 1184 682 1600 1521 0 1 71 27 0 2 31368 51168 603412 120012 0 0 1472 0 1646 1634 0 1 74 25 0 1 31368 48764 606928 120136 0 0 1794 0 1567 1299 0 1 75 25 0 1 31368 47280 608764 120120 0 0 1014 684 1608 1618 0 1 74 25 0 3 31368 47252 611056 120428 0 0 1212 6 1504 1283 0 1 74 25 0 1 31368 47656 613236 120328 0 0 1138 720 1487 1125 0 1 74 25 0 2 31368 46288 615728 120436 0 0 1286 0 1534 1382 0 1 73 26
見て分かるのが、CPUのディスクI/O待ち(wa)が大きいこと。実際、画像が配信されてくるまで一呼吸置くぐらいあって、これはディスクI/Oがやばいんだろうなと思ってました。なので、ディスクを高速化しないといけないのかなぁ、と思っていたのですが、すでにSCSIでRAID5だしどうしたものかと思っていたのです。
しかし、Linuxにあるファイルキャッシュを使えばいいんじゃないと気付いたのです。Linuxは、『一度読み込んだファイルは再び読み込まれる可能性が高い』という前提の元、読み込んだファイルをメモリー上にキャッシュしておくのです(memory欄のcacheがファイルキャッシュに使われてるメモリー量)。ファイルキャッシュは空きメモリーの中からLinuxが勝手に確保してくれるので、メモリーを2GBに増設してみました。増設後のvmstatがこんな感じ。
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 0 0 696 46956 235932 1457628 0 0 48 1512 2938 5197 1 4 94 1 2 0 696 47020 235932 1457628 0 0 0 0 3077 5451 1 5 94 0 0 1 696 46956 235932 1457628 0 0 68 756 3457 6351 2 6 91 1 1 0 696 46764 235932 1457628 0 0 28 6404 5446 7418 2 8 81 9 0 0 696 46828 235936 1457624 0 0 20 0 3653 6699 2 6 91 0 0 0 696 46636 235944 1457616 0 0 92 1504 3644 6701 2 7 89 2 0 0 696 46636 235948 1457872 0 0 48 0 3469 6373 2 7 91 1 0 0 696 46572 235964 1457856 0 0 32 0 3837 7359 2 7 90 1 0 0 696 46508 235980 1457840 0 0 48 0 3513 6718 2 7 90 1 0 0 696 46572 235980 1457840 0 0 0 0 3058 5742 1 5 93 0 0 0 696 46508 235980 1457840 0 0 36 1592 2834 4880 1 4 93 2 0 0 696 46508 235980 1457840 0 0 12 0 3379 6077 1 5 93 0 0 0 696 46508 235980 1457840 0 0 0 0 3159 5850 1 5 94 0
ほとんどI/O待ちが発生していないことが分かります。つまり、よく読み込まれる画像はほとんどファイルキャッシュに入ってしまって、キャッシュから読み込んでいると言うことです(上に比べてbi(ディスクからの読み込み量)が少ないことからも分かります)。この対策をしたことで、サーバーから出て行く秒間のデータ量が約3倍ぐらいになりました(つまりディスクI/Oのボトルネックが解消し、画像配信速度が向上したと言うこと)。
そこで、導き出されるサーバーの選び方は以下のようになるのではないでしょうか。
| CPU | そこそこのもの 弊社では3.0GHz*2で500req/sこなしてるときのロードアベレージが1.6とか |
|---|---|
| メモリ |
配信すべきコンテンツ1つあたりの平均ファイルサイズ*よく読み込まれるコンテンツの数+500MB 500MBはカーネルとかHTTPDとかが消費するメモリ(おおよそです) |
| ディスク | SCSIでRAID1かRAID5(かな) |
ところで、なぜこのボトルネックに気付かなかったかというと、abやJMeterで負荷テストをしていたからです。つまり、これらのベンチマークツールでは数十万個のファイルのランダムリクエストを擬似的に発生させることができなかったのであり(JMeterとかだとできるのかもしれないですけど調べてないです…)、リクエストしていたせいぜい数十個のファイルはファイルキャッシュに入ってしまっていたので、負荷テスト時にはディスクI/Oのボトルネックが表面化しなかったのです。
もしかするとまだまだ改善できるかもしれないので、つっこみとかお待ちしてます。
画像配信の負荷分散も比較的簡単?(その1)
[http://www.onflow.jp/blog/archives/2006/04/30.html:title=30万個ぐらいの静的ファイルを配信する…
大量の静的ファイルを扱うサーバー
30万個ぐらいの静的ファイルを配信するサーバーの選び方
昔、インターネットプロバイダーでホームページサーバーの開発を担当していました。
アダルトコ…
ファイルシステムはext3ですよね?
xfsにしてみるのはどうでしょう?
こんな話があります。
http://lwn.net/Articles/216948/