― Web Technology and Life ―

WebサーバーをNginxのReverse proxy+cacheに変えたときのチューニングメモ

2013-10-13
このブログのバックエンドApacheからNginxに乗り換えたので、それまでの流れをメモとして公開します。Nginxをわざわざ使う上でやっておいたほうがいい基本的な設定とリバースプロクシキャッシュの動く設定からベンチマークツールの賛否両論まで。

次世代WebサーバーのNginxという未来へ!

「Nginxがすごい!!!」みたいな話を聞いて、はや4年。なんだかよくわからず、Apacheを使い続けていましたが、やっとNginxのすごさがわかったので、乗り換えました。そのあたりのより入門的な内容やApacheでよくやる設定をNginxでどうやろうかもつらつら調べているので、そのあたりは別記事としてたぶん公開するとして、まず手っ取り早く導入しないとそのあたりをやる気力もなくなるので、個別のカスタマイズはさておき、導入内容ついて記事にしておきます。とりあえず、Nginxの公式サイトでも見てみるといい気もしますが、カタカナ多すぎてよくわからんというのが正直なところですねw

ubuntu10.04に最新のnginxをインストール

Ubuntu 12.04 LTS に最新の Nginx をインストールするという記事を参考にさせてもらいました。とりあえず、ubuntuの場合aptでいれてもよいのですが、できれば最新の安定板を使いたいですよね。

sudo vi /etc/apt/sources.list.d/nginx.list
#以下を追加 12.04ならlucidじゃなくてpreciseという感じ
deb http://nginx.org/packages/ubuntu/ lucid nginx 
deb-src http://nginx.org/packages/ubuntu/ lucid nginx

curl http://nginx.org/keys/nginx_signing.key | sudo apt-key add -

sudo apt-get update

sudo apt-get install nginx

nginx -V

この記事時点では以下のように表示されます。aptのsourceリスト更新しないと、0.7なんとかってバージョンが入るんですが、最新版は1.4とかそれ以降になっていると思います。

nginx version: nginx/1.4.3
built by gcc 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1)
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-mail --with-mail_ssl_module --with-file-aio --with-cc-opt= --with-ld-opt= --with-ipv6

Nginxはモジュールとかはmake前のconfigureでやるっぽいですが、これで設定一覧見れるのは結構いいですね。

このブログのリーバスプロクシとキャッシュ設定

とりあえず、設定ファイルは1枚ですので全部載せます。その後、いろいろ実際に試したチューニングポイントをまとめます。

設定

user nginx;
worker_processes  2;#CPUのコア数設定
worker_cpu_affinity 0101 1010;#worker_processesの数に合わせて設定

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;#だいたい1024がmax,ulimit -aで確認
    accept_mutex_delay 100ms;
    use epoll;
}

http {
    include       /etc/nginx/mime.types;
    sendfile      on;
    tcp_nopush    on;
    tcp_nodelay   off;

    keepalive_timeout   65;
    types_hash_max_size 2048;


   log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"';

    gzip  on;
    # gzipを無効化するブラウザ
    gzip_disable “MSIE [1-6].(?!.*SV1)”;

    #cache
    proxy_cache_path /tmp/nginx/cache levels=1:2 keys_zone=cache-space:4m max_size=50m inactive=120m;

   server {
       listen   81;
       server_name  hirobanex.net;

       access_log  /var/log/nginx/hirobanex.access.log main;

       #cache
       proxy_cache cache-space;
       proxy_cache_valid  200 302  60m;
       proxy_cache_valid  404 20m;

       location / {
            proxy_temp_path /tmp/nginx/tmp;

      #リバースプロクシのいい感じにする設定
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Server $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      #リバースプロクシの設定
            proxy_pass http://app; 
        }
    }
    upstream app {#ロードバランシング的プロクシやFCGI設定
        server 127.0.0.1:5999;
    }
}

改めてチューイングポイント

Nginxの恩恵をあずかるためのポイントは以下の通りです。

  • worker_processesにはCPUのコア数を指定(それ以上指定してもperformanceでない)
  • worker_connectionsはだいたい最大1024(ulimit -aとコマンドに打ち込むとサーバー別の上限が分かる)
  • gzip on, keepalive_timeout(画像とかの配信、複数ファイルをまとめて配信用)
  • sendfile on; tcp_nopush on;(圧倒的に静的ファイル配信速度が変わる。Commetの時は限りではないみたい)
  • リバースプロクシはlocation内にproxy_pass以下に設定
  • http内のupstreamはserverをいくつも書いてロードバランシングする用

ファイルオープン数が上限値に達したとかみながらworker_rlimit_nofileの上限上げてworker_connectionsを5000とかにしてみたけどreq/secもtimeout数もたいしてかわらなかった、よくわからん。なお、Apacheの場合、cacheはmod_cacheでディスクやメモリを選べたんですが、Nginxの場合は、基本ディスクキャッシュでしかも、リバースプロクシの場合とFastCGIの場合はちがうようです。

cache関連はコピペが多いので、詳しくわかりません。また、以下の設定も参考記事に効果がありそうに載っていましたが、ベンチとったところこのブログのシステムではそれほど影響がありませんでした。

  • accept_mutex_delay 100ms;
  • use epoll;

keepalive_timeoutに1以上を入れることで、keepaliveが設定されます。数字は環境によって変えるのが無難みたい。イベント駆動じゃないApacheほどKeepAliveはセンシティブにならなくていいのかな?と思っています。

  • keepalive_requests 65
  • keepalive_timeout 100#ブログでは設定もしていないけどデフォルトは100らしい

設定における参考記事

以下とても参考になりました、大変感謝です - G-WANはなぜ速いのか?をnginxと比べながら検証してみた - nginxの設定例 - yanchaでuzullaさんにいろいろ聞く→timeout多かったのwifi環境からベンチとっていたからでしたw - nginxを使った簡単快速reverse proxy+cacheサーバ構築法

ベンチマークツールによるこのブログのApacheとNginxとの比較

ベンチマークツールはkazeburoさんの記事にあるwrkを使いました。これについては後述します。ちなみに、このブログはさくらVPS980のむかしの512MB時代のスライドの1GBサーバーで、ベンチもとは同じ大阪か北海道の同じくさくらVPSです。

Apacheの場合の設定とベンチ結果

Apacheは、PreforkのMPMでパフォーマンスに関係ありそうな設定だと以下のようになっています。MPMの設定以外は、基本的にubuntuでaptでつっこんだapacheの設定のままです。preforkはだいぶ頑張った数字ですね。Apacheとかforkしたプロセスのメモリチューニングに関するメモとスクリプトって記事に書いた通り、リバースプロクシだけのApacheなんで子プロセスの実メモリが250KB程度なので結構がんばれます。

Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15


    StartServers       700
    MinSpareServers    700
    MaxSpareServers    700
    ServerLimit        700
    MaxClients         700
    MaxRequestsPerChild   10000



    #LoadModule disk_cache_module modules/mod_disk_cache.so
    # If you want to use mod_disk_cache instead of mod_mem_cache,
    # uncomment the line above and comment out the LoadModule line below.
    
    CacheRoot /usr/local/apache2/cache
    CacheEnable disk /
    CacheDirLevels 5
    CacheDirLength 3
    

    LoadModule mem_cache_module modules/mod_mem_cache.so
    
    CacheEnable mem /
    MCacheSize 4096
    MCacheMaxObjectCount 100
    MCacheMinObjectSize 1
    MCacheMaxObjectSize 2048
    

    # When acting as a proxy, don't cache the list of security updates

測定結果は以下の通り。

$ ./wrk -c 500 -t 3 -d 10 http://hirobanex.net/
Running 10s test @ http://hirobanex.net/
  3 threads and 500 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.08s   610.91ms   6.21s    89.18%
    Req/Sec   153.92     59.21   279.00     76.00%
  4075 requests in 9.98s, 112.54MB read
  Socket errors: connect 0, read 0, write 0, timeout 98
Requests/sec:    408.40
Transfer/sec:     11.28MB

Nginxのベンチ結果と総括

$ ./wrk -c 500 -t 3 -d 10 http://hirobanex.net:81/
Running 10s test @ http://hirobanex.net:81/
  3 threads and 500 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.38s   769.79ms   3.21s    78.82%
    Req/Sec   136.37     69.62   362.00     71.43%
  4123 requests in 9.82s, 111.50MB read
  Socket errors: connect 0, read 0, write 0, timeout 7
Requests/sec:    419.84
Transfer/sec:     11.35MB

timeoutに注目して、比較したいのですが、

  • Apache:98
  • Nginx:7

となっています。正直、誤差の範囲ですが、まぁApacheもかなり頑張ったpreforkしているんでいい感じかなとw実際、これで700プロセスApache消しただけで約500MBメモリが解放されましたし。

おそらく、Nginxのリーバスプロクシは「max clients = worker_processes * worker_connections/4」となる点がreq/secに大差が出ない大きな原因ではないかと思っています。

さくらVPS980円の場合、「2コアなので、2 * 1024 / 4 = 512」がMaxClientsになる。 一方で、preforkのApache2を使う場合、ただキャッシュのリバースプロクシ用途なら200~300kb程度が実質の子プロセスの使用メモリで、300MB今日をApacheに割り当てる場合、約1000プロセス立ち上げられるので、Nginxより場合によって有利なパフォーマンスを出すことが可能でかもしれません。ただ、イベント駆動とpreforkオンリーのアーキテクチャの差がtimeoutという数字に表れているのではないかというのがぼくの雑感です。

ベンチマークツールについて ~ab VS wrk~

ベンチマークツールをwrk使ってますが、その理由とかのメモです。

王道のベンチマークツールabはtimeoutがわかりづらい

yusukebeeさんのWebアプリのパフォーマンスアップ作戦とかいろいろなところでウェブサーバーのベンチマークといったら、apache付属のabが紹介されているので、まぁ一般的な慣例に則ってab使っていたんですが、実際にこのブログのベンチマークをab -c 100 - n 1000 http://hirobanex.net/とかやると、両方ともエラーで途中とまるんですね。

で、ab -c 100 -t http://hirobanex.net/ってやってもこれ、リクエストに失敗した数がどこにかいてあるのかよくわからないんですよね。今回は、req/secの数的には結構競っていたので、リクエストに失敗した数とかわからないとNginxした成果がメモリ使用量減っただけで、場合によってパフォーマンス落ちているんじゃないかという懸念すらあったので、「リクエストに失敗した数を知ること」が死活問題でした。

そんで、kazeburoさんなんかよくわからんツールでベンチとっていたなーと思って、調べたらwrkのインストールって記事がでてきたので、このwrk使うことにしたわけです。

なんか、このあたりのウェブサーバーのベンチマークツールの比較とか見方の解説とかのトーク聞きたいですね!

おわりに ~おわりなき設定の意味をもとめて~

本とか雑誌とかブログ記事とかいろいろ見ますが、結構設定の内容はわかるんですが、それがどういう効果があるかは最終的には、実際に設定してみてベンチマークとったり、ログファイルみたいしながら、実践するしかないので、なかなか手間暇かかりますよね。

今回、これだけの内容をやるだけでも、一日半~三日くらいかかっています(私がなんちゃってエンジニアってのもあるでしょうが、苦笑)。個人的には、Nginxが何かもよくわからず、またApacheについてもパフォーマンスまわりはよくわかっていなかったので、そのあたりいろいろ調べてので、かなり時間かかりました。

それでも、それらをブログにまとめたり実践した痕跡を残すことで、次は一瞬でできるようになるのは大変な価値だと思っています。そういうものを増やすために、また明日もきっといろいろ調べて、このブログのサーバーに実践したり、別のサーバーに実践したりするでしょう。

検証作業は、なかなか面白いですが、ホントに終わりなき旅ですねw

Nginx update_at : 2013-10-13T15:08:49
hirobanex.netの更新情報の取得
 RSSリーダーで購読する   
blog comments powered by Disqus