ホーム > ISUCON

ISUCONのアーカイブ

#isucon 負けてきました

  • 投稿者: chiba
  • 2013/11/10 日曜日 18:30:30
  • ISUCON

ISUCON3本戦に毎度おなじみ山形組で参加してきました。結果は過去2回の出題者チームであるLINE選抜チームが圧倒的スコアで優勝という結果で、さすがでした。

うちは一応本番計測で完走したため5位という結果でしたが、途中経過では11位ぐらいをさまよっていましたので惨敗といって良いと思います。
ちなみに、予選も含めた過去4回の本番計測すべてを完走しているのはうちだけじゃないでしょうか。パーマネントなチーム自体が少ないので個人単位ならいるかもしれませんが。

やったこと

nginx化
serve static
x-accel-redirect
既存画像の事前リサイズ
新規画像のPOSTはオリジナルを置くだけにして、リサイズをApp::watcherで実施
明らかに無駄なコードの最適化

やれなかったこと

インメモリDB化
画像ファイルのストレージ分散
新規画像のリサイズ処理のCPU分散

コンテスト中の流れ

いつもどおり開始から1時間ほどは現状分析を行い作戦会議をしたのですが、初期画像データがだいたい3Gあり、そのSML版を作ると最大12Gになるからこれをメモリ4Gの4台でうまくすべてをファイルキャッシュにのせるようにしましょう、で、変換もそれぞれの分散先のサーバ自身で変換するようにしましょうと話していました。のちにimageのL版はなく、さらにオリジナルの劣化版をつくっておけば(LINEチームはそれで画像サイズを1/3ぐらいにしたそうです)1台でもそれなりにキャッシュにのることを知ることになるわけですが。

あとは、転送量制限が最終的には問題になるからフロントは5台にして内部のアプリケーションサーバ(1台)にPrivate IPでリバースプロキシしましょう、という戦略でした。(アプリケーションサーバが1台なのはインメモリDB化を見据えていたため)

画像の転送はNFSという話もあがったのですが、アプリケーションサーバを画像ストレージ用のサーバにも置いてそこにPOSTすれば楽にいけそうですねとなりました。

あとはいつもやっているアプリケーションの書き換えは今回はさすがに他にやることが多すぎて無理っぽいので部分書き換えで、最終的にはmysqlのデータのインメモリ化までいけたらいいね、といっておりました。

結果、最初にたてた戦略の半分も実行できず、既存画像の事前リサイズで6800ぐらいを出したところでボトルネックを見失い、timeline等のmysqlのクエリチューニングに走ってしまい、そこからはたいしてスコアがあがらずに時間の浪費。

終了30分前ぐらいに、そういえばworkloadをあげてなかったと、あげてみたところ新規画像のリサイズのCPUボトルネックになってFAILすることがわかったのですが、もう時間的に根本対策は無理で終了。

感想

予選のあとにインメモリDBどうなの話の流れで @methane さんが


っておっしゃってたのを見ていたので、「あ!ここtwitterでやったやつだ!」となりました。

アプリケーションロジックやMySQLのチューニングがボトルネックになるのは多分まだまだ先の話で、まずは画像の配信時の処理を速くすることと、workloadをあげていった時に新規画像の生成(CPUボトルネック)をいかに矛盾なく速くするかという戦いだったように思います。(自分は後者の戦いにはほぼ参加できていませんが)

あとはアプリケーションの複雑性があがっていたり、まっさらのサーバが4台あったり、既存データの処理を別途する必要があったりで、発想と瞬発力だけではなく、きちんとチームとして機能していないと勝てないようになっているように感じました。(正直二人ではきつかった)

ということで、かなり悔しい思いでいぱいですので、来年またあったら3人目の組員と共に参加したいとおもいます。

主催/共催のカヤック、LINE、DATA HOTELの皆様ありがとうございました。

#isucon 3 予選総合3位でした

  • 投稿者: chiba
  • 2013/10/7 月曜日 2:41:23
  • ISUCON

毎年でているISUCONに今年も山形組として参加しております。

今年からオンライン予選があり、10/5の一日目に参加し結果は現在のところ暫定で3位で予選通過の予定です。
暫定なのは使ったサーバの運営側による検査が残っているためです。

で、今年は何をやったか、というとあいも変わらず去年と同じことをしておりました。去年と同じ方式でかくと

やったこと

アプリ全書き換え
 1fileなPSGI
 https://gist.github.com/nihen/6852251
 feersum(1プロセスマルチスレッド)
 データはすべてオンメモリ
  スレッド間でシェア
 永続化はテキストファイルへjsonで追記
html renderのキャッシュ(といってもmarkdownぐらいか)
リバースプロキシをnginxにして静的ファイルもそこでserve

やれなかったこと

benchmark –workloadの試行
さらなるhtml renderのキャッシュ(メモリストの各liとか)
POST後に与えられている1秒間の猶予の活用
nginx embedded perl
 Plack::Handler::Nginx
 二年ぶりにnginx,perlそれぞれ現在の最新バージョンでやろうとしたらまったく原因不明のbugった挙動になっており、断念

コンテスト中の流れ

まず始まる前から決めていたのは、外部要件をブラウザで丁寧に確認するということでした。
予定通りこれを時間をかけて行い、その後それに対応したコードの読み込みを行い予め取り決めていた11:30にそれを打ち切って作戦会議。ここまでコードやサーバに変更は一切なし。ベンチマークは初期状態で実行しました。

作戦会議の結果、前回と同じ手法が使えるはずと決まり、実装開始。今回は前回よりアプリケーションとして複雑というのもあり途中少し諦めかけるも、14時ぐらいには完成。意気揚々とtestを実施するもFAIL。まあ一発で成功するとおもってもいなかったので出てきたメッセージを元にひたすらデバッグ。しかしだいたいめぼしいバグとれただろう…という段階になっても原因不明なFAILがまったくとれなくなり、ここでひたすら時間を浪費する。

2013/10/05 16:58:11 [FAIL] Post http://localhost/mypage: EOF
2013/10/05 16:58:11 [FAIL] Post http://localhost/mypage: EOF
2013/10/05 16:58:12 [FAIL] Post http://localhost/memo/41324: use of closed network connection
2013/10/05 16:58:12 [FAIL] Post http://localhost/memo/41326: use of closed network connection
2013/10/05 16:58:12 [FAIL] Post http://localhost/memo/41325: EOF
2013/10/05 16:58:12 [FAIL] Post http://localhost/memo/41328: EOF
2013/10/05 16:58:12 [FAIL] Post http://localhost/memo/41327: EOF
2013/10/05 16:58:21 [FAIL] Get http://localhost/recent/35: EOF
2013/10/05 16:58:41 [FAIL] Get http://localhost/recent/89: EOF
2013/10/05 16:58:45 [FAIL] Get http://localhost/recent/31: EOF
2013/10/05 16:58:46 [FAIL] Get http://localhost/recent/60: EOF
2013/10/05 16:58:56 [FAIL] Get http://localhost/recent/168: use of closed network connection

出てたエラーはこんな感じ。ログに書かれている時間を見ると分かるように、この状態で残り1時間を切るという状態に追い込まれておりました。もうこれはだめかもわからんね、という話をし、ここから1時間王道チューニングで足掻こう…と既存アプリのチューニングを始める。

計測はしていないものの全要件をコーディングしていたおかげでボトルネックはなんとなく把握していたので、ボトルネックの解消自体は順調に進められたのだけれども、いかんせん時間が足りそうになくその頃既に1位は3万点台を計測しており、もうこれはやはりFAILを取ることに全力を傾けたほうが後悔はないだろう、と再度17:30ごろにFAILをとることに舵を切り直す。

で、実はFAILをしていたときはテストがしやすかろう、とFeersum単独で80ポートをlistenしていたのだけれども、Apacheからリバースプロキシというもとの構成にもどしてみる。しかしまだFAIL。ここで静的ファイルをApacheでServeをやっていないことに気づくもAliasの書き方等をぐぐる時間も無かったので、豊富にローカルに設定を持っているnginxに切替え、静的ファイルのserveをしたところ…Success!。急いで本番用のbenchmarkコマンドを実行し、32270点を出したのがたしか17:45ごろ。あとはちょこちょこアプリを修正しつつ終了。正直いまだにFAILの原因は分かっておりませんのでベンチマークツールが公開されたらじっくりしらべてみようと思います。

というわけで長々と書いてしまいましたが、つまりギリギリまでスコア提出をほとんどしていなかったのは高度な情報作戦でもなんでもなく単純にFAILしていたからなのでした。

感想

前回参加からのこの一年の間に、幸運にも負荷を要因としたスケールアウトが必要になるような案件に携わらせていただいており、そういった王道チューニングもいいだろうなぁと思いつつも、いまの自分の実力的にはやはりこの飛び道具を使わざるを得なかったというのが実情ではあります。

今回はKlabさんのチームも似たようなアプローチで2位にはいっており、運営のfujiwaraさんも対策すると言明されているので、本戦でまったく同じアプローチが通じるとは思っていません。本戦まで本業のほうも含め王道チューニング的な経験値、やはり増やして臨みたいところですね。

主催されたfujiwaraさんをはじめKayacの皆様、LINEの皆様、いつもこんなに熱く楽しいイベントを開催していただきありがとうございます。
本戦の出場が正式に決定しましたら、その際はまたどうぞよろしくお願いいたします。

#ISUCON2 で特別賞を頂いて来ました

  • 投稿者: chiba
  • 2012/11/4 日曜日 14:08:29
  • ISUCON

というわけで前回に引き続き山形組として参加してきました。

まとめブログはこちら

結果は、スコア18万切りに最初に到達すると頂ける特別賞を16時ごろ10万ちょうどぐらいのスコア(スコアは低いほうが優秀)で頂いたものの、その直後に藤原組さんにさくっと8万あたりのスコアで抜かれ、こちらも9万台のベストスコアはだしたものの、最終結果は10万あたりで、藤原組さんは8万台で2位で終了。

スコア的には僅差だったので正直かなり悔しいですが、藤原組さんは「実運用に突っ込んでも運用が破綻しない状態」を維持されていたようで、うちはかなりチート手法でしたのでこれはもう完敗ですね。次があったら正攻法で戦えるように経験値を上げて望みたいなと思いました。

やったこと

アプリ全書き換え
 1fileなPSGI
 https://gist.github.com/4006644
 feersum(1プロセスマルチスレッド)
 データはすべてオンメモリ
  スレッド間でシェア
 部分的なhtmlのキャッシュ
 永続化はテキストファイルへjsonで追記
リバースプロキシだけでアプリも立ち上げ
 つまり動いてたのは一台だけ
  DBサーバがスペックよかったのでそっちでアプリうごかせばよかったかも。
リバースプロキシをnginxに

やれなかったこと

永続化の遅延
リバースプロキシでstatic serve
 なぜかやるとFAILした
  これがkazeburoさんの罠とざわつく
nginx -> feersum間をkeepalive
nginx embedded perl
 Plack::Handler::Nginx
 上記のFAIL問題で焦ってて時間なくなってできなかった
TIME_WAIT対策
 reuseつかったらFAILした
  他の問題かも

コンテスト中の流れ

前回の感想ブログエントリに書いた通り一人Isucon1をやっていたときに、nginx embedded perlでデータはすべてオンメモリが最速という結論を得ていたので、その方法がとれるようであれば今回もやろうと事前に考えていました。

今回は最初にぱっと構成をみたときにstockデータがそれなりに大きかったのでこれはオンメモリは無理か?と思ったもののvariationごとの64*64の単純なデータ構造だったのでこれは計算でいける、とオンメモリ化でいく決断を開始一時間後ぐらいにする。

であれば用意されているアプリとはまったく考え方が違うので、一から実装のほうが早いと判断し、がりがりとコードを書き始める。で、途中お昼食べたりしつつ4時間ほどでできたのがこれ。今回の参加者中キータイプ数なら間違いなく一位だったと思う。KINESIS最高!作り方としては既存アプリのコードはなるべく見ないでブラウザから外部仕様の動作確認をしつつ移植という感じ。

オンメモリデータの一枚psgiなので手元の環境のplackupのみで簡単に動作確認できるというのは一つの強みだったとおもう。

で、それをデプロイしていくつかの移植ミスによるFAILをクリアしたところで10万スコアがでて特別賞。

その後nginx embeddedに進むためにもstatic serveをnginxでしたところなぜかFAIL。
このあたりから完全に迷走し、いろんなことに手をだし(nginxの最新バージョンを試したりtime_wait問題の解決を図ったり)何が原因でFAILしてるのかも見失う状態になり肝心のnginx embedded perlの作業に入れず、とりあえずFAILを解消しよう!といろんなことをrollbackしてなんとか完走するようになったところでタイムアップ。

感想

普段負荷を要因としたスケールアウトを必要とするような仕事をほとんどしておらず、安易なスケールアウト戦略に疑問をもっているというのもあり、世間で王道とされていることに対するアンチテーゼとして、この実装で優勝するということを密かに狙っていました。

会場では「業務には役に立たないチートです」と言いましたし王道な藤原組さんに結局負けてるわけですが、「なぜスケールアウトするのか」という点を考えるきっかけになってもらえたらいいなぁと思っています。

インフラチームが4台用意してくれてるんだからとりあえず4台使って分散してみるか~という安易な考えではなく、ボトルネックの解消や冗長性のためなど具体的な測定結果や理由によりスケールアウトするべきなんだろうなぁと。

まあ負け犬の遠吠えですが!

主催されたNHNのスタッフのみなさん、こんなに楽しいイベントを開催していただき、本当にありがとうございました!

ISUCONに参加してきました

  • 投稿者: chiba
  • 2011/8/30 火曜日 3:18:58
  • ISUCON

なんでもありのWebアプリケーション高速化バトル、#isuconに山形組として参加してきました。
結果はみなさんご存知の通り、藤原組さんの圧勝という感じになりました。
自分はというと、DBボトルネックの解消までは藤原組さんとほぼ同じ手法で解決して、4700req/minあたりのbest scoreを出した後には有効なチューニングが行えずにnginx導入の罠にひっかかって200req/minとかになってしまって泣きながらapacheに戻したりしつつ、最後はサイドバーのcacheをmmapにいれる作業をしていたらバグでfailするようになってしまってぎりぎりでDBのボトルネック解消直後にロールバックして、10000req/3minくらいがたしか最終スコアだったと思います。failしたチームを除けば下から数えたほうが早い感じになってかなり悔しい結果でした。

DBボトルネック解消直後にappサーバを一つにしぼったところたいして結果は変わらず、ああたかが10並列だしサーバ分散するほうが無駄なのかなとリバースプロキシでplackで直接80番ポートをlistenするとどうなるかなーと思ったりもしていたのですが、debianでdaemontools慣れしていた自分はceontosでsupervisordという構成にひるんでしまってそこまで踏み込めなかったので、帰ってきてからPSGI単体のアプリでどこまでチューニングできるかってのをやってみました。

で、できたのがhttps://gist.github.com/1178857これです。Feersumで動かしてあげると、自分の環境で96550req/minのベストスコアがでました。一応永続化もしているので(デーモン化の設定さえすれば)再起動後も有効な、ISUCONレギュレーション完全対応なPSGIアプリになっています。ISUCONアプリの全体像を簡単に見通したい方にもオヌヌメです。といってもこのやりかたはたかが10並列でたかが3分間のアクセス(とpost数)とわかっているからできる構成なので実際の運用にそのまま生かせるような内容にはなっていませんので、そこのところご注意くださいです。

こんなわくわくするイベントを開催してくださったlivedoorの担当者の皆様ありがとうございました!

追記: その後nginxとも組み合わせてやってみたところ(psgiもこんなかんじに修正して)

までいきました。nginxでは静的ファイルをserveして、keepalive,gzipオフ。

追記: nginx embeded perlで242686req/minでました。https://gist.github.com/1181564
nginx +proxy cacheでexpireしないようにして試すと、(当然FAILするけど)fetchesが30万前後だったのでまぁここらが自分的には限界

1 2

ホーム > ISUCON

検索
フィード
メタ情報

ページの上部に戻る