読者です 読者をやめる 読者になる 読者になる

nginxとmemcachedのネタ話

インフラ
皆さんお久しぶりです、孟です。

今日紹介したいのはnginxとmemcachedのちょっと変わった使い方です。


業務上、動的内容を静的ファイルに書き出して配信する方法よく使われてます。
この伝統的なやり方は、アプリケーションサーバへの負荷軽減するメリットが大きいですね。

更新頻度低いファイルに対して、まぁ問題全くなさそうに見えますが、
更新回数増えるほど、ファイルシステムのバッファリング遅延とIO負荷どんどん増えて来ます。

アクセス数多い所で、ファイル更新される途中一部アクセスがエラーになってしまうことも存在します。

ここである方法を紹介したいと思います。

まず、nginxのインストールですね(ここでprefixを/usr/local/nginx-memcに設定します)

wget http://nginx.org/download/nginx-1.2.2.tar.gz
tar -xzf nginx-1.2.2.tar.gz
cd nginx-1.2.2

./configure --prefix=/usr/local/nginx-memc
make && make install

cd /usr/local/nginx-memc

confファイルを弄ります
# vim conf/nginx.conf

---------------------------------------------------
...省略...

        location / {
            set $memcached_key  $uri;
            memcached_pass      127.0.0.1:11211;
            default_type        text/html;
        }

...省略...
---------------------------------------------------


↑のように、locationらへんmemcached_passを正しく設定すればOKです。
流れとしては、アクセスの$uri部分をmemcachedのkeyとして自動的に設定されて、配信される模様です。
例: http://127.0.0.1/foo ← ここの /foo がキーとして使われそうです。

ほかもいろいろ細かく設定できそうです。
http://wiki.nginx.org/HttpMemcachedModule


さっそくabテストをしたいと思います。

適当でmemcachedに値を突っ込みます。

telnet localhost 11211
> set /foo 0 0 3
> bar


abテストをします~ (一応環境が会社のvmware playerでcentos 6 (cpu intel i7 870 2.93Ghzの4コア, mem 2G))

# ab -n 10000 -c 100 http://127.0.0.1:8080/foo

Server Software:        nginx/1.2.2
Server Hostname:        127.0.0.1
Server Port:            8080

Document Path:          /foo
Document Length:        168 bytes

Concurrency Level:      100
Time taken for tests:   1.063 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Non-2xx responses:      10000
Total transferred:      3170000 bytes
HTML transferred:       1680000 bytes
Requests per second:    9409.50 [#/sec] (mean)
Time per request:       10.628 [ms] (mean)
Time per request:       0.106 [ms] (mean, across all concurrent requests)
Transfer rate:          2912.90 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.7      0       5
Processing:     0   10   3.1     10      32
Waiting:        0   10   3.1     10      32
Total:          0   11   3.1     10      35

Percentage of the requests served within a certain time (ms)
  50%     10
  66%     11
  75%     11
  80%     11
  90%     13
  95%     17
  98%     18
  99%     21
 100%     35 (longest request)



はい、バーチャル環境でも9000 rps近くの成績出てますね。
チューニングしてworker数を増やして、本番だともっと爆速です。




せっかくだからapache 2.2.15静的ファイル配信のabテストもしてみました。

# ab -n 10000 -c 100 http://127.0.0.1:8081/index.html

Server Software:        Apache/2.2.15
Server Hostname:        127.0.0.1
Server Port:            8081

Document Path:          /index.html
Document Length:        4 bytes

Concurrency Level:      100
Time taken for tests:   0.966 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      2690538 bytes
HTML transferred:       40008 bytes
Requests per second:    10354.26 [#/sec] (mean)
Time per request:       9.658 [ms] (mean)
Time per request:       0.097 [ms] (mean, across all concurrent requests)
Transfer rate:          2720.56 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   0.5      0       6
Processing:     4    9   1.6      9      20
Waiting:        3    9   1.6      9      20
Total:          5   10   1.8      9      25
ERROR: The median and mean for the initial connection time are more than twice the standard
       deviation apart. These results are NOT reliable.

Percentage of the requests served within a certain time (ms)
  50%      9
  66%     10
  75%     10
  80%     10
  90%     12
  95%     12
  98%     14
  99%     16
 100%     25 (longest request)





まぁ、こんな感じですね。どうですか。
うちがperl使ってますので、catalystを通ってapacheで配信と比べたらまぁ恐らく100倍近く速いじゃないかな。
やってほしい部分が動的内容をアプリからmemcachedに書き込むだけです。

nginx + memcachedのメリットが速いだけではないです。
動的内容の配信負荷一気に下がります。

普段のやり方だと、複数webサーバでファイル配信する時、各サーバへ定期的にrsyncしないといけないです。
nginxからmemcached直で配信すれば、同期しなくても済むというメリットもありますね。

サーバのIO負荷やバッファリングの遅延などのボトルネックも無くなります。
そろそろ限界だと感じたら、どんどんmemcached鯖足せばOKです。


以上で、今日のネタ話でした。