チューニンガソン #4に参加してきました

ロスタートさんの公式のブログの方でまとめられてましたので追記 【2012年7月4日】

【レポート】いろいろチューニングしてパフォーマンスを競うバトルイベント!「Tuningathon」第4弾! #tuningathon


チューニンガソンとは

http://www.zusaar.com/event/312053

FBファンページ

アプリ以外のインフラ部分だけをチューニングしまくってとにかく速くするというバトルです。

前回参加した時のエントリーはTuningathon 2!に出てきましたです。この時はMediaWikiでいかに速くレスポンスを返すかという回だったのですが、nginxのプロキシの設定を間違え測定不可という結果に終わってしまいました(´・ω・`)・・・

今回はRuby on RailsRefineryというOSSCMSが対象でした。

  • RoR refineryのコメントPOST/GET回数
  • 10並列で一定秒数間測定
  • 秒間平均POST/GET回数がスコア
  • エラー返却は単純に除外
  • POSTはGETの10倍のスコア
  • POST後のGETによる反映チェック
  • 反映チェックの成功率の二乗をスコアに乗算

がバトル条件でした。

サーバは

であり、スペック的には少々厳しい感じです。

チューニング開始

まず最初に行ったのはtmuxをyumでインストールして、自鯖からconfファイルを持ってきてペイン分割してとtmuxがないとダメな子なので最初にやりました。使い方は前のエントリーから


メインウィンドウを3ペインで分割し、1つをtop -d 1を実行し、1つをperf topでベンチマークを実行した時に何が起こるかを確認しました。LL言語はさすがというか、とにかく重いんです。第2回の時もPHPが重すぎて・・・
今回はRoRと全くの未経験ゾーンだったのでとにかくベンチマークを実行・眺めるをやってました。
実は最初の時はベンチマークがうまく走らず、エラー箇所をベンチマークスクリプトの中身から確認したらtry〜catch部分でExceptionが発生していました。おかしいな、おかしいなと半ば諦めも若干入りつつ一旦Google先生RoR関連のチューニングを調べていました。

実はrailsの実行をrootで実行しなきゃいけないのに一般ユーザで実行していて問題になっていたようですw

これに気づいたのが13:30頃。まだScoreは2.7くらいのデフォルト状態。

いろいろ試してみるも対して変わらない時にTLに

とか流れてきて、@netmarkjpが強すぎて泣きたくなりましたw

更に15時頃1100という謎な値を叩きだす@netmarkjpさん。
自分はこの時3とかをさまよってました


16時手前にRubyのEnterprise Editionのインストールが終了して、PATHの設定を書き換えて計測したら5を超えました。
でも@netmarkjpの200分の1というもう絶望的な値でした。この時にはもう20を超えるような人も出始めていました。

16:30にPassengerのインストールが終わりapacheのデフォルトポートを3000に、DocumentRootをrailsに当てるという無理やりな構成にして10手前まできました。


Passengerの設定をいろいろ変更してみて再度ベンチマークを何度か走らせた時に自己最高の16が出て喜びました。

間に公式の測定が走っており、そのタイミングでtop10が10超えくらいだったのでもしかしたらと思ったのですが、この時には結構時間も立っていたのでもうみんな20くらいなのかな〜っと諦めモードも若干入りつつ。Passengerの設定を何度も変えてベンチマークを走らせるということをしていました。多分最後1時間くらいほとんどPassengerいじってましたね。

最後30分くらいになってmysqlinnodb関連をチューニングかけるかと思いつき、自鯖の設定を丸々コピーして貼っつけましたwww時間がなかったのでコピペで何か変わればいいかな〜くらいにしか思ってませんでしたが、何も変わらず。

自分が一番の失敗だったのはapacheの再起動をした時にScoreが一回急激に下るという現象が何かを本当の意味で理解していなかったことだと思います。単純に何度か行うとキャッシュが聞いてScoreが上がるんです。なので今回トップ2の2組はvarnishでひたすらキャッシュするというので1000を超えるScoreを出していたようです。
自分は気づかずずっとRubyだけ触ってました。CPUバウンドするRubyをどうにかして軽くしたいとしか思ってなかった時点で上位は厳しかったようです。

結果発表

なぜか9位に入賞してしまいました(^^)
呼ばれた時にびっくりし過ぎて、前でしゃべってもテンパってて何を喋ったかも覚えてませんwすいませんでしたw

nginxは使用せず、apacheを利用しました。

Passengerは以下の様な設定にしました。


LoadModule passenger_module /usr/local/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/passenger-3.0.13/ext/apache2/mod_passenger.so
PassengerRoot /usr/local/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/passenger-3.0.13
PassengerRuby /usr/local/ruby-enterprise-1.8.7/bin/ruby

Header always unset "X-Powered-By"
Header always unset "X-Rack-Cache"
Header always unset "X-Content-Digest"
Header always unset "X-Runtime"

PassengerMaxPoolSize 40
PassengerMaxInstancesPerApp 2
PassengerPoolIdleTime 3600
PassengerUseGlobalQueue on
PassengerHighPerformance on
PassengerStatThrottleRate 20
RailsSpawnMethod smart
RailsAppSpawnerIdleTime 86400
RailsFrameworkSpawnerIdleTime 0

ギリギリまでいじったのは

  • PassengerMaxPoolSize 40
  • PassengerMaxInstancesPerApp 2

の2項目だと思います。メモリが余っていたのでPoolSizeを上げてみてもっとキャッシュできないかと試したり、インスタンス数をCPU*2にしたりなどして調整しながら一番いい値の時の設定を採用しました。

my.cnfは


max_connections = 500
bulk_insert_buffer_size = 8M
nice=5
query_cache_size = 16M
query_cache_limit = 1M
thread_cache_size = 1
innodb_buffer_pool_size = 512M
innodb_additional_mem_pool_size = 4M
innodb_log_buffer_size = 8M
innodb_log_file_size = 64M
innodb_log_files_in_group = 2
と本当に何も考えずコピペしただけでした。

今回このようなチューニング方法を採用した理由はrx-7乗りのnamikawaさんのブログを見つけたところからこのようにしました。

3年前のエントリーですが、基本は変わらないので採用してみました。

当日はアルバイト時代にインフラコンビを組んでいたYosuke Yamamotoさんにわからないところをちょいちょい聞いて教えてもらったりしたので1人で結果を出したわけではないので次回は本当に1人で結果が出せるようにしたいです。

今回の1位2位の上位者たち。

VOYAGE GROUPさんのアジトを会場で懇親会が行われました。いつもいつも会場提供とお酒の提供をありがとうございます。
AWSの提供をして頂いているAmazonさん、取材にいらした技術評論社の方、運営をして頂いているゼロスタートの方々いつも楽しいイベントにして頂きありがとうございます。
自分が優勝するまで続けてくださいw優勝したら勝ち逃げしたいですwなので数年〜10数年続けていただけるとwwww

そして2次会は近くの権八で技術話をつまみにお酒と翌日の朝は起きるのが辛かったです・・・

TwitterのURLの部分やgistの部分がちゃんtp表示されるかわかりませんが、参加したエントリーになります。