ISUCON4に初めて出場し、予選敗退しました。これはその記録。

優勝賞金100万円!今年もやります 第4回 ISUCON 開催と日程のお知らせ #isucon : ISUCON公式Blog

結果


  • チーム:Luxury
  • メンバー:joe_hrmn(アプリ担当)と(インフラ担当)
  • 言語:Python
  • 最終スコア:29058


当日の流れ


環境構築→初回ベンチ

まずAMIからベンチ送信用(本番)1台に各々の開発用2台ずつ起動。joe_hrmnがコード一式をGithubに上げてる間にnginxのログ出力($request_time)とMySQLのスロークエリログ(0.1秒)を設定、解析用にGoAccessPercona Toolkitをインストール。初回のスコアを出して1300ぐらい。
ボトルネックのチェック

初回ベンチ時に以下の項目について見てみた。
  • dstatなどでベンチ中のリソースチェック
  • goaccess -f /var/log/nginx/access.logでリクエストの比率を見る
  • cat /var/log/nginx/access.log | awk '$NF>0.05 {print}'でレスポンスが悪いログを抽出
  • pt-query-digestでスロークエリログ解析

MySQLのインデックス作成

チェックした結果、計測中のCPU張り付きとインデックス使ってないクエリが大量に流れてたのが気になったのでとりあえずlogin_logipuser_idにインデックス作成をinit.shに追加。あとから気づいたけど、発行されてるクエリも10種類ぐらいしかないし、データ量もそんなに多くないのでスロークエリ解析するまでもなかった。最初にソースと設定見ておけばもっと短縮できたかなと思う。このあたりでお昼回ってた気がする。これで8000ぐらいだったかな?
nginxで静的コンテンツを返す

すべての接続がプロキシされていたので静的コンテンツのみnginxから返すように変更。ここで無駄にハマったのが、ログ上では200を返してるのにブラウザから見ると表示されない問題。include mime.types;がないだけだったんだけど、ちゃんとデベロッパーツールを見ていれば早かった…。
エフェメラルポートを増やす

workloadを増やしてくると (99: Cannot assign requested address) みたいなエラーが出始めるのでnet.ipv4.ip_local_port_rangeでエフェメラルポートを増やす。これで12000ぐらい。
超えられない30000の壁

最初はボトルネックがわかりづらくなるからworkloadを1で上げれるところまで上げようっていうスタンスでやってたんだけど、12000あたりまでいってもう15時回ってたので、いったん今出せるスコアを送信しておくことになりworkloadを上げ始める。上げれば点数も上がるんだけど、7~8あたりからゆるやかになり、29000付近で限界が来る。workloadもいくつまで上げるのかよくわからないまま20でスコア送信。結局これが最後の送信になった。
その後はnginxのキャッシュいじったりgunicornの設定をいじったりしたけど大した効果もなく、PythonをUNIXドメインソケットに変更しようと思ったけど普段やっていないことができるわけもなくタイムアップ。暫定16位でフィニッシュ。
AMI作成→反省会

AMIを作りながら、一日目のチートの話を聞いて驚いたり、fujiwara組のグラフを見て絶望に打ちひしがれるなど、ひと通り敗北感を味わった後Skypeの観客席でワイワイしていた一日目の予選出場のla_luna_azulと合流し、道玄坂の米心で反省会を開く。ちなみに米心は日本酒好きならたまらない良いお店だった。メニューを持って帰りたい。

最後に


今回は満足とはいかない結果に終わってしまったけど、自分の弱い部分が明確にわかったのでとてもよい経験となりました。あと単純にすごく楽しかったです。
運営の皆さん、危うく出れなくなるところを助けていただいた941さん、出題してくれたクックパッドの皆さんありがとうございました!