30万個ぐらいの静的ファイルを配信するサーバーの選び方

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(かな)

ところで、なぜこのボトルネックに気付かなかったかというと、abJMeterで負荷テストをしていたからです。つまり、これらのベンチマークツールでは数十万個のファイルのランダムリクエストを擬似的に発生させることができなかったのであり(JMeterとかだとできるのかもしれないですけど調べてないです…)、リクエストしていたせいぜい数十個のファイルはファイルキャッシュに入ってしまっていたので、負荷テスト時にはディスクI/Oのボトルネックが表面化しなかったのです。

もしかするとまだまだ改善できるかもしれないので、つっこみとかお待ちしてます。

3 thoughts on “30万個ぐらいの静的ファイルを配信するサーバーの選び方

  1. 大量の静的ファイルを扱うサーバー

    30万個ぐらいの静的ファイルを配信するサーバーの選び方

    昔、インターネットプロバイダーでホームページサーバーの開発を担当していました。
    アダルトコ…

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>