mod_ruby で画像変換
動機
mod_ktai等でちと話題にあがっているapacheレベルでの動的な動画作成。ゆめみさんがなかなか出してくれなさそう(残念ながらソース非公開っぽいし)&Cなんて書けないし書く気もしない。のでmod_rubyの検証も兼ねつつ、ちゃらっといけそうかどうかをテストがてらに確認してみる。
問題点
RMagickにはメモリリークがある(らしい)。
試行錯誤。
http://www.kaeruspoon.net/articles/402
こちらのページを参考にテストしてみるが1リクエスト毎に子プロセスを立ち上げることのオーバーヘッドが大きすぎ。
http://rubyforge.org/forum/forum.php?thread_id=1374&forum_id=1618
こちらの情報だともうライブラリレベルで対応ができてるっぽいので実装してみる。いい感じで動きそう。
テストコード
mod_rubyのソースです
require "cgi" require "rubygems" require "RMagick" r = Apache.request r.content_type = "image/jpeg" r.headers_out.add("Expires",CGI.rfc1123_date(Time.now + 3600)) r.send_http_header() img = Magick::ImageList.new("/cluster/wdc/test/92/164/202/210.qvga.jpg") r.puts(img.resize(320, 240).to_blob) img.destroy! img = nil fDisabled = GC.enable GC.start GC.disable if fDisabled
テスト
私の開発環境のメモリが非常に寂しいものなので同時アクセスは控えめにテストを行う。いちおうRMagickのメモリリークがテストのポイントなんでまぁよしとしよう。
テストコマンド
ab -c 10 -n 20000 http://***/***.rbx
テスト結果
Server Software: Apache/2.2.9 Server Hostname: 192.168.100.78 Server Port: 80 Document Path: /cgi-bin/test.rbx Document Length: 18222 bytes Concurrency Level: 10 Time taken for tests: 1643.192533 seconds Complete requests: 20000 Failed requests: 0 Write errors: 0 Total transferred: 368600000 bytes HTML transferred: 364440000 bytes Requests per second: 12.17 [#/sec] (mean) Time per request: 821.596 [ms] (mean) Time per request: 82.160 [ms] (mean, across all concurrent requests) Transfer rate: 219.06 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 7.6 1 917 Processing: 69 819 1263.9 412 44342 Waiting: 67 796 1225.6 408 44341 Total: 70 820 1264.0 413 44343 Percentage of the requests served within a certain time (ms) 50% 413 66% 490 75% 565 80% 798 90% 2221 95% 3246 98% 4651 99% 5970 100% 44343 (longest request)
TOPで眺めている分にはメモリリークは発生していなさそう。
longest request はちと気になる・・・・。
結果
速くはないねぇ。。。ちなみに、同一環境でRailsの2.1のDB接続ありなシンプルなページをproductionモードでパフォーマンステストしてみると30req/secぐらいでるのかな。
でも、apacheのfilter等を使ってCで実装したところでImageMagickの画像変換のオーバーヘッドは避けられないんじゃないかな。と考えると、Cでがんばって書くだけのメリットは見いだせなさそう。実際はmod_cacheと組み合わせて使うんでこの結果で何とかなると思うし。将来的によりけちくさい(高尚な)レベルでパフォーマンスを云々するときはうちの偉い人に書き直してもらえばいいんだしまずはこの方向でOKかな(投げっぱなし結論)。
蛇足
変換前画像のチョイスと、変換後サイズ指定をもうちょっと考えてテストすればよかった。。。。もう面倒なんでやらんけど。