ISUCON
2020/09/12のISUCON10予選にRubyチームとして参加したので、そのレポートをまとめます。
Fusicからは以下2チームが参加しました。
ぞうさんチーム
ラディカル・グッド・スピード(脚部限定)
詳細はISUCON10予選にPHPで挑戦しましたをご確認ください。
開始前
起床試験に通過し、10時前に会社へ集合しました。
開始が2時間程度遅れるとのことだったので、ゆとりを持って準備を行うことができました。
夜遅くまでの長丁場になるため、夕飯まで準備するメンバーもいました。
コンテスト開始
まずは当日マニュアルをしっかり読み込みます。
今回の問題となるWebアプリケーションは以下のようなものでした。
【アプリケーション名】
isuumo
【要旨】
イスと、イスを置くの物件を調べることができるシステム。
イスや物件は大きさ、価格、人気、特徴など様々な要素で検索をかけられる。
また、物件については地図をなぞって、範囲内の物件を調べられる「なぞって検索」がある。
イス詳細画面では、イスを室内に搬入できるようなおすすめ物件をレコメンドしてくれる。
またTOP画面では、イスと物件それぞれについて価格が安い順に20件を表示してくれる。
イスは在庫が有る限り購入することができ、
イスの購入成功件数と物件の資料請求成功件数(在庫縛りなし)の和が得点となる。
また、このアプリケーションにはクローラーからのアクセスが多くあり、適切にブロックすることが求められる。
【DB構造】
chairテーブルとestateテーブルの2つのみ。
過去のISUCONの問題と比較しても、とてもシンプルな問題であることが伺えました。
OSやコア数を確認し、最初のベンチを走らせます。初期スコアは460前後でした。
またMySQLが非常に重く、CPUが100%に張り付くことも確認できました。
下準備
alpを導入して分析をかけると、検索画面へのアクセス数が非常に多く、時間もかかっていることがわかりました。また、myprofiler・stackprofも導入し、検索周りで重たいクエリが連発していることも確認しました。
またローカルで開発が行えるように環境を構築しました。
一方でアプリケーションコードも読み進め、より深い仕様の理解と、改善できそうなポイントにあたりをつけていきました。
改善
まず目についたレコメンドクエリの改善を行いました。 イスの縦・横・高さについて、物件のドアを通るかを6パターン(イスのパラメーターから2つ選び、ドアの高さ幅を通るか並び替え)チェックしていたのですが、イスの縦・横・高さのうち小さいもの2つを使うようにし、2パターンの判定に削りました。
また、イス・物件の価格が安いものについて20件取得する部分をキャッシュすることにしました。 このキャッシュは、新しいイス、物件が追加された時やイスが売り切れた時に更新するようにしました。
またなぞって検索では最終的に出す候補の上限が50件にもかかわらず、範囲内の全物件について包含判定をしていました。これでは日本全土を多うような大きな丸を書かれた場合に、とても遅くなってしまいます。ひとまず最初の候補を絞る段階でLIMIT 100をつけ、包含判定回数が少なくなるようにしました。(整合性チェックでキラーケースがある場合は通りませんが、運良く通りました)
さらに、MySQLのクエリキャッシュを有効にしたり、不足していたIndexを追加したりしました。 途中、DBを別サーバへ移管したものの、CPU/メモリを使い切れずスコアが下がってしまいました。
他にもいくつかの改修を行いましたが、思うようにスコアが伸びず、ジリジリ時間を消費していきました。 最後にBotのブロックをした変更が消えていることに気付き、再度設定しました。
結果と反省
最終スコアは800弱で、順位は211位でした。(約500チーム中。参考値。)
「推測するな計測せよ」とはよく言ったものです。
最も重い検索部分の改善を後回しにし、とりあえずスコアが微増しそうな目につく箇所の改善に取り組んでしまいました。水を流すためには、まず詰まっている箇所を最優先で改善しなければなりませんでした。
結果、各種改善を行っても思うようにスコアが伸びず、焦りからかミスやバグも生まれるようになってしまいました。
感想
とはいえ、ISUCONは非常に楽しいものでした。 またこれほどシンプルなアプリケーションでありながら、取り組みがいのある問題に仕上がっていることにとても驚きました。
ISUCON11が開催されるのであれば、是非参加してリベンジしたいと思います。
最後になりますが、ISUCON10運営に携わった全ての方々にお礼を申し上げます。
Related Posts
Yuhei Okazaki
2021/09/29