mod_mrubyとngx_mrubyにファイル単位でのキャッシュオプション追加

mod_mrubyngx_mrubyにRubyコードファイル単位でのキャッシュオプションを追加しました。

これまではRubyコードファイル単位でキャッシュ化する事はできていませんでしたが、これからはキャッシュ化したいファイルを選択する事ができます。キャッシュといっても、キャッシュ指定されたRubyコードファイルはサーバプロセス起動時にコンパイルまで行っておくという機能で、キャッシュ化するとサーバプロセス起動後はファイルの内容を変更しても反映されません。一方でキャッシュ化していないファイルは、リクエスト単位でコンパイルするのでファイルの変更がリクエスト単位で反映されます。

設定例を見た方が理解がはやいと思うので以下に示します。

設定例

  • Apache httpdの場合

[program lang=’apache’ escaped=’true’]

<Location /hello-cached>
    mrubyHandlerMiddle /usr/local/apache/htdocs/hello.rb cache
</Location>
<Location /hello>
    mrubyHandlerMiddle /usr/local/apache/htdocs/hello.rb
</Location>

[/program]

  • nginxの場合

[program lang=’apache’ escaped=’true’]

location /hello-cached {
    mruby_content_handler /usr/local/nginx/html/hello.rb cache;
}
location /hello {
    mruby_content_handler /usr/local/nginx/html/hello.rb;
}

[/program]

ほぼ同じような記述でかけるようにしています。第二引数のcacheを渡すとキャッシュ化されます。

パフォーマンス

一応、例の如くhelloworldパフォーマンス比較をしておきましょう。同時接続数100、総接続数10万でlocalhost向けにabコマンドでkeepalive有りでベンチマークをかけ、一秒間のリクエスト処理数を計測しました。。サーバスペックはコア1(i7-4770K CPU @ 3.50GHz)、メモリ1GのVMです。Apache2.4.6(event mpm)やnginx1.4.2の設定はデフォルトです。

hello.rbは以下のようにApacheもnginxも同じものを使いました。

[program lang=’ruby’ escaped=’true’]

if server_name == "NGINX"
    Server = Nginx
elsif server_name == "Apache"
    Server = Apache
end

Server::rputs "hello"

[/program]

結果は以下になります。

mod_mruby mod_mruby(キャッシュ化) ngx_mruby ngx_mruby(キャッシュ化) 参考までにnginxの静的コンテンツ(hello.html)
request/sec 9182.31 13304.21 16918.70 45544.18 16920.55

nginxはやいなー、というのは今回の趣旨ではないのでおいておいて(設定もデフォルトですし)、キャッシュの有無でこの程度の差がでる事がわかりました。

まとめ

このように、mod_mrubyngx_mrubyでRubyファイル単位でキャッシュ化できるようにしました。サーバプロセス起動後に、変更が頻繁にかかるようなファイルはキャッシュ化せず、ほとんど変更のないようなファイルはキャッシュ化してしまえば良いでしょう。