ISUCON7にrubyで参加して手も足も出なかった
どうも。昨年に続き今年もisuconに出てきました。 チームメンバーは完全新規でチームrehash.fm ( おばちゃん (mobata) , ゆづるくん (yudsuzuk) ) で参加しました。別に仲違いとかではないです。
結果としては222位と惨敗でした。 ISUCON7 オンライン予選 全ての順位とスコア(参考値) : ISUCON公式Blog
この悔しさを忘れないために反省点などメモっておきたいと思います。
当日の流れ
開始まで
10時開始予定だったのが13時開始になり大分時間を持て余してました。それでも去年(goで参加)とは違い不慣れなrubyでの参加だったので過去のisuconの問題を振り返ったり、rubyでの解き方などを改めて復習してたりしました。 BGMは仲間内で流行っているシンフォギアのキャラソンをずっと流してました。ゆづる君にとっては完全に意味不明だったと思います。
開始直後(13:13)
サーバーの準備が整いいざ開始してからは、定石に則ってalpを入れたりslow-logをonにしてからベンチを流したりしてました。
予選で初めての複数台構成でしたが、予想してなくはなかったのでそこまでは慌てませんでした(慌てなかったとは言ってない)。
alpを眺めた結果、大量に /icons/:file_name
へのアクセスが大量に来ていてまずはこれをどうにかするというのはすぐにわかりました。
この時点(rubyデフォルト)でのスコアは 4119
でした。
チューニング開始(14:13)
そこからアプリケーションコードを眺めて iconsへのリクエストがmysqlから画像データを配信していることが分かり、nginxで配信する方針が立ちました。また、画像ファイルのテーブルにindexが張られていなかったためindexを張ったところ 6453
と微増しました。
nginxで静的ファイル配信(15:55)
mysqlのバイナリファイルをどうやってファイルに書き出そう?とあれこれ調べながら、curlで取ればいいやんと気づくまで結構かかりました。この間ゆづるくんはアプリケーションコードでボトルネックになりそうなところを直してくれてました。おばちゃんはnginxの設定をいじってました。
なんとかnginxでのファイル配信ができるようになったところでスコアは 8846
になってました。(この時点であまりスコアが上がらないことに焦りを感じてました)
静的ファイル配信の試行錯誤(16:01)
nginxでの配信に切り替えてもalpで表示されるログには /icons
へのリクエストが支配的でした。そういえばgzipつけてなかったと思ってつけたところスコアが 13393
にまで上がったのでやはり /icons
をなんとかしなければという方針のまま進みました。この時点でおばちゃんが帯域を使い切ってることに気づき、Cache-Control
だ!!!と過去問(isucon4)のことを思い出せたのでnginxの設定をいじくり回す旅に出ることになりました。完全に
進研ゼミでやったことあるやつだ!
状態でした。勝ったなガハハと思ってました。 この間ゆづるくんはユーザー情報をredisにキャッシュするのをやってくれてました。
ベンチマークツールで複数台指定できることに気づく(16時過ぎ)
去年のisucon本戦に引っ張られてベンチマークに登録できるサーバーは1台だけだと思いこんでました。おばちゃんが「これチェックボックスじゃない?」と気づいてから複数台に対してリクエストが送れることに気づきました。今までweb1, db1サーバーで動かしていたのでこれで帯域倍使えるじゃん!と希望が見えたりもしました。
Cache-Controlが効かない。スコアが上がらない(終了まで)
それからというものweb2台 - db1台構成にしようと色々いじってました。
webが2台になるので画像がアップロードされたらローカルに保存し、nginxはローカルになければ反対側に取りに行く構成にしてました( try_files
とかいう便利なディレクティブがあるのを知りました) 。
この設定を動かすのに結構苦労しました。
最終的にちゃんと動く様になったもののスコアは13000台と全く変わりませんでした。帯域も使い切っていることがわかりました。明らかに Cache-Controlが効いてない。。。
そこからはずっとCacheできるように試行錯誤してましたが、結局時間内に解決することはできませんでした。
Keep
- 去年に引き続き会社の会議室を使わせてもらえたのはとてもありがたかった。社外の人との参加だったけど使わせてもらえたのは本当にありがたいです。大きいディスプレイも使えてalpのスコアを常に見られる状態だった。
- 事前打ち合わせ(過去問)をやって感覚をつかめた。alpの導入やslackでのやりとり、git(private)でのコード管理を事前に手を動かしながら確認できた。
Problem
- 過去問を読んだだけで解いた気になってはいけない。isucon4でCache-Controlでハマったというのは知識としては知っていたけど、どんなリクエストが来ていてどんな設定を入れれば適切にCache-Controlを返せたのか理解していなかった。
- 役割分担がふんわりしていた。これはProblemなのか微妙なところだけど特に誰が何をやるというのは決めていなかった。なんとなくゆづるくんがrubyいじる(アプリケーション担当)、おばちゃんがインフラ、自分は... 🤔 みたいな感じだったのできっちり分担しても良かったのかもしれない。全員がどれもある程度できるといえばできるので自律的に動けていれば問題なかったかもしれない(なんとなく途中で誰かの手が空いてしまう状態が見受けられたのでリーダーポジションは必要なのかもしれない)。
- レギュレーションをちゃんと読む。当たり前すぎて書くまでもないが、レギュレーションにはちゃんとヒントが載っている(いた)。帯域が制限されていることとかスコアの測定についても記述があるので、もっと早くCache-Controlについて気づけたかもしれない。nginxを解析してボトルネックを解消すればいいという定石に囚われすぎた感がある。
- ちゃんと動くコード, 設定ファイルが管理できてなかった。rubyのコードはgitで管理していたけどnginxの設定ファイルを複数人で生でいじりすぎた。しかもweb1, web2とそれぞれいじってしまったため途中でどの状態が一番スコアがでる(正常に動く)のか分からなくなってしまった。またrubyのコードもほぼレビューなしでmasterにマージしてしまっていたためgithubを使っていた意味がなかった。
完全にこれでした。
準備するようじゃ出遅れてるんだ。 #isucon pic.twitter.com/LQVVop4HLq
— ふそやん (@azihsoyn) 2017年10月21日
Try
- ちゃんと過去問を解く。手を動かす。
- 役割分担ちゃんと決めてみる。去年はある程度決めていた。リーダーポジションがいたのは大きかった気がする。
- tcpdump (+ Wireshark)はデファクトになりそう(すでになってるのかも)。途中でクライアントのリクエストヘッダーが気になったけどnginxの設定だけでなんとかなると思い込んでしまった。使えるようにしておく。
- 履歴をもっと残す。写真もっと撮る。ブログ書いてて味気ない。スコアの履歴はissueにコミットログと紐付けて残していたけど、
これめっちゃいいなと思った。今回から採用したテク、git tag score/346917 とかをベンチ直後に冷静に叩く事です #isucon
— そらは (@sora_h) 2017年10月23日 - isucon8も参加する。このままでは終われない!!来年も同じチームで出るかは未定ですが、今年よりも成長した自分で臨みたいです。差し当たってはisucon関連ブログを読み漁って復習したいと思います。まだisuconは終わっていないし、すでにisuconは始まっている!
結果こそ残念でしたが、予選から複数台構成 + 過去にあった問題 + αでとても楽しめました。運営の皆さんありがとうございました!!チームの二人もありがとう!
あと rehash.fm もよろしくお願いいたします。