ISUCON12 に Rust で参戦し77位で終了しました

作戦会議

事前に予行練習や作戦会議をしました。方針は以下の通り。

  • 一番大きそうなボトルネックを見つけることに集中する
  • 目の前の明らかに改善できそうな所に、すぐ手を出さない
  • メンバーそれぞれ別のことをやらず、ボトルネックに対し全員で対応
  • サーバ複数台構成は後回しにし、1台でもスコアが伸びる状態を作る
  • とにかく落ち着く

## まさかの SQLite

大会が始まりサーバの中身を確認していくと SQLite っぽいファイルが見つかり「え…?」と思わず声が出ました。当然? SQLite のチューニング経験なんてないです。困った。

## ID 生成が大胆

分析を進める中で MySQL の `REPLACE` を使ってユニークな ID 生成をしている箇所が重そうでした。アプリケーションコードを見ると、そもそもこの ID、この生成方法である必要がないと分かったので以下のようにしました。

  • MySQL の ID 生成をやめた
  • ランダムな文字列なら OK なので Rust 側で生成
  • `player_score` テーブルの ID は使われてないので、NULL 状態にした

## N+1 の解消

チームメンバーのペッパーがプレイヤー詳細周りの N+1 を良い感じに除去してくれました。これでスコアが 5000 から 7000 くらいに伸びた。ただし、サーバの負荷状況を見ると明らかに IO 負荷が高い。SQLite の読み書きがボトルネックになってきています。

## SQLite のチューニング

SQLite のチューニング、全然分からないし、何ならスロークエリログとか分析する手法自体を知らないので調べたりしましたが、ぜんぜん良いのが見つからず断念。クエリだけでなにか改善できる方法はないのか?と調べたところ `PRAGMA` でファイル同期モードを切り替えられることを発見。

## サーバを全て使い切れず終了

この時点で大会終了20分前。実質やれることは少なくタイムアップ。

  • 初期テナントは A サーバへロードバランス
  • 新規作成と Admin API は B サーバへロードバランス

## さいごに

予選を突破するには 22111 点以上必要だったと言うことで、サーバの分散化ができてたらもっと迫れたのかな?という感じで、悔しいですが一定の成果も出せた実感もあります。なによりハチャメチャに楽しかったです。本当に、毎年イベントの開催・運営をしていただいている関係者の皆さん、ありがとうございます! また来年も期待しています。

--

--

I’m programmer. I love code.

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store