名もなき未知

エンジニアリングとか、日常とかそういうのをまとめる場所。アクセス解析のためGAを利用、Googleに情報を送信しています。商品紹介のためAmazonアフィリエイトを利用、Amazonに情報を送信しています。記事に関しては私が書いていない引用文を除いて自由にご利用ください。

ISUCON12予選に参加しました(敗北)

今年はダメダメでしたが、学びはあったので振り返りです。

最終スコア

過去数回参加して初めて0点で終わってしまったので悔しいですね…。 ちなみにBestが10597となっていますが、ログを切って11900点くらいまで伸びていました(最後0点取った瞬間にあーあーとなって画面を閉じてしまったのでそのタイミングのスクショなし)

当日の振り返り

4:00

目が覚めてしまったので、邪神ちゃん見たり、お風呂入ったりした。

8:00

Rust環境を最新化した。

9:30

チームメンバーが集まったので初動を決めたりする。 AWSに1年ぶりにログインする~とか言ってたので、いろいろフォロー。

10:00

競技開始。初動はこんな感じ。

  • もっさんさん:alpでアクセス履歴を見たりする
  • pxfncさん:gitにいろいろ登録
  • yumechi:pt-query-digest でログの解析

11:00

2台目をMySQLサーバーにする方針にする(いつも通り)。bind-addressの設定のことを忘れており、時間がかかる。 もっさんさんにフォローしてもらった。

サイズが大きく、git add されていないファイルがあるので、pxfncさんが git lfs で登録できるようにしてくれた。

自分はログから generate_id の処理が明らかにバグってることを明らかにしたのと、 create_at の集計が遅いことだけはわかったので、インデックス貼って試したりしていた(なお今回の初期化処理の理解に時間がかかり苦戦した模様( schema.sql がマジで構造しか示してないことに気が付かなかったので、ちょっと苦労した)。

12:00

言語的にはNode.jsを選択したものの、Dockerで用意したビルドが壊れまくる。 このあたりからこのチームはビルドがうまくいかない問題にずっと悩まされることになる。

ついでに initial_data も管理対象にしたかったので、ホームディレクトリ配下をgit管理配下にした。

自分はインデックスが反映されていない? とずっと疑問に思っていた。

13:00

ビルドに全く成功しないので、あきらめて一度スタックを削除して再作成する。 どうも tmp ファイルへの書き込み権限の問題っぽく、以後どこかのタイミングで root で動かすようにしていた。

ファイルの分割を行っていたものの、動かなくなり、これ以上元に戻すのも難しそうな感じになってしまう。

14:00

環境を戻すのが無理臭くなってしまったので、Rustに変更した。

インデックスを張ってみて、計測してみるもののパフォーマンス上がらず。 このあたりからどちらかといえばアプリケーション側で頑張らないとダメそうという話になる。

SQLiteをまじめに見始めたのはこのあたりから。

15:00

ビルドが遅くはかどらないうえに、権限問題でビルドできない状況がまた起こる。 アプリケーションを分割試用と考えたが、SQLiteで管理されているものを同期できないので無理かもなーとなる(EFSを仕事で使っていたので、速攻思いついたものの、多分今回のレギュレーションではダメだよなーとなった)。

SQLiteのものをMySQLに移し替え始める。 あとはSQLiteのままにしかできない場合に備えて、オプションを変更する。

16:00

ようやくアプリケーションコードのほうを直し始める。pxfncさん、もっさんさんにより、 generate_id の修正がかなり効いて、スコアが2倍になる。 また yumechi は htop でメモリ使用量や CPU 使用量を見ながら、 nginxのworker数を調整する。今回、初期値が小さめの設定だったので、2048くらいまで上げたらスコアが1万近くまで上がった(17時凍結前がそれくらい)。

SQLiteからMySQLの移行をしていたものの、通信速度的に間に合わないことが分かり始め、あきらめる。

17:00

pxfncさん、もっさんさんが N+1 クエリをいくつか対応している裏で、空いているマシンでyumechiがnginx、MySQLの設定を変更していく。

17:40時点でN+1クエリをつぶし、ログをオフにしてから再起動試験などをする。 再起動した後は大丈夫であったものの、ログの調整をした結果、またビルドがおかしくなる問題が発生していまい、そのままタイムアップ… となってしまう。

結果的に0点となりました。うーん…。 正直終わった瞬間にかなり放心状態になっていたのを覚えています。

19:00

振り返りとかを軽めにしました。 最後失敗した原因はちょっとビルドの問題なのか、DBのinitの問題なのか(どっちもありそう)って感じはしますが、どちらにしろ切り分けができなかったので無理でしたねぇ… というお気持ちになりました。

今回の振り返り

KPT

疲れ切ったので来週やろうという話になったものの、とりあえず話し合った結果を自分がまとめたのは下記。Figmaでまとめました。

当日活動に対しての振り返り

  • 自分たちが対応可能なフィールドにもっていくのが明らかに遅かった
    • Docker普段から使っているものの、環境上で全然動かん状態を考えると、去年同様に直接仮想マシン上でのビルドに変更すべきだった
      • 去年の構成と同じにできていれば。。。
    • SQLiteでなんとかするより、使い慣れているMySQLに変更して、観測性などを高める方針に行ったほうがよかった
      • パフォーマンス的には上がらなかったらしいが、pt-query-digestやコマンド系はMySQLのほうが圧倒的に使えるので、引きはがしが遅かった
      • 最後の壊れ方もSQLiteのファイルが壊れているのか、ビルドがおかしいのかわからなかったものの、ファイルが壊れている起因ならMySQLに上げておくのがよかったかも
  • 言語選定
    • Rustふわっとやりましょうとなっていたが、最初nodejsにしたりと方向性が定まっていなかった
    • この辺りは作戦負けな気がする
  • 各種環境の保全が甘かったかも
    • 権限回りもう少し真面目に自分も見たほうがよかった(設定回りをいじくりまわしてる場合でなかったかも)
    • もう直接的で直近動いたビルドを残すみたいな大胆な作戦でもよかったかもしれない
  • SQLiteの特性にちょっとだけ詳しくなった
    • ファイルの書き込み、読み込みになるので更新に弱め
      • どこで読んだか忘れが、書き込み時にファイルの更新がかかるので、この負荷ではスケールが厳しい(ローカルのAndroidで、とかがやっぱり現実的)
    • 更新のモードのオプションとかはあるだろうと思って調べてそれがヒットしたのは良かった
  • tmpfsは頭の片隅にあったけど、使えなかった
    • EFS思いついたんだからついでに思い出していれば…(今回同じネットワークにいるね、という意識がだんだんと薄くなってしまった)
    • 残り時間的なタラればなので、まあ思い出せても使えなかった可能性は高い
  • クエリ全部さっと見れた
    • Where, Group By, Order Byを抑えるために速攻ですべてのクエリを見たのはえらい
    • インデックスも比較的まっとうに貼れたと思う
    • ただ、今回はどちらかといえばRDBMS自体をどうするか、みたいなところにも焦点が合ったので、あまり役に立たなかったといえばそうなのかもしれない

ただ、今回の振り返った感じ、この辺は思いついていたので、ビルドに苦しんでいなければ行けたかもなーと思ってるんですよね。 下あたりの抑えるべき重要なポイントは抑えられていたと思うので、かなり悔しい。

  • generate_id の改善
  • Min(create_at) の改善(これもクエリとか結果見てる感じ、できたなーと思う。インデックス貼って効かないってのはわかっていたので、テーブル構造とか、クエリ変えるとかそういう動きはできたはず)
  • SQLite -> MySQLに移植したうえで、チューニング

前日活動に対する振り返り

  • 前週に練習をして、必要なツール類をまとめ上げれたのは良かった
    • zshとか、fzfとか
    • ansibleとか本当は書いたほうがよかったかもしれないが、今回は手で入れた
    • .zshrc が活用できた、と思う
  • ISUCON本は役に立った
    • 予選でpt-query-digestは使えて、問題の発見には役立ったので勉強しておいてよかった
    • nginxも主要な設定については見直しに役立った
  • 言語に対する勉強不足
    • Rustで行きましょうをもう少し強くいったほうがよかったかも
    • 結局フワフワしていたので、当日始まってから言語決めたのは意思決定速度下げたように思う(そのタイムラグすら8時間の制限時間ではもったいない)
  • AWSの試験勉強
    • 6月にAWS Certified Cloud Practitioner Certificationを受けて合格している
    • 勉強していたSecurity Groupとかを見つつ、ポート空いてる? とかは推測に走らず厳密に見ることができた
    • これはAWS環境なので役立ったことではあったものの、勉強していてよかったと思う

今後に向けて

  • Cache周りの練習は結局できなかったので、やっておきたい
    • Rust + Redis とか
    • Memcacheと微妙に得意不得意が異なるのは知ってるものの、まあinit考えるとデータ永続化がしやすいRedis選ぶんかなーと思う
  • Rustもう少しやる
    • チュートリアルとか、exampleとかはさっと見たが、習熟不足
    • TypeScriptは仕事で少し使おうかなーと思ってるので、仕事でTypeScriptを足していって、趣味でRust書くとかにしたい
    • (ただお仕事的にはPHP or Goやらないといけない部分もあるのだが…)
  • エンジニアとして活動するような方向性を見出す
    • 実のところ、この1年くらいは指示だし、方向性決め、技術調査などのリーダーシップを発揮しつつ合間でエンジニアっぽい仕事をしていて、コードや設定回りゴリゴリやるとかができてない
    • ただ、今回の件を通してそういう仕事を少し減らして、ピュアなエンジニアリングの力をもう少しつけたり発揮するのもいいなと思った
      • (そういう仕事もちゃんとやれそうな環境があれば、ちょっと話を聞いてみたいような気もします)
      • エンジニアとしてのスキルはまだ伸びるなと思った
  • あとは過去のISUCONなどから使用技術や飛び道具をそろえておきたい
    • 圧倒的にMySQLとNginxだけで頑張ってるので、それ以外の外部ツールとかコマンドとか、設定とか、そのあたりでカバーできるものがあれば覚えておきたい
    • MySQLも8系の設定回りはあまり詳しくないので、文献を読み漁りたい
    • ありがたいことにISUCONの過去問は公開されていて、構築方法も用意されているので、いくらでも練習ができる
      • 練習してもコストが大したことがないのもありがたい
      • これは生かすしかない!

終わりに

結構悔しさがあるので、引きずっていたりするのですが、まあ終わってしまったことは仕方がないです。 今後もISUCONが開催されることが望ましいとは思いますが、いつ開催がなくなってしまうのかわからない部分もあると思っていて、毎回今回がラストなのかもしれない、という気持ちで自分はいるので、そういう意味で結果を残せなかったのはとても苦しいです。

来年もISUCONが開催されることを祈って(個人スポンサーに今年はなり忘れましたが、来年はちゃんと申し込もうと思います、、、)、そのための準備だけは進めていきたいと思います。

終わりです。