あおかびのおすなば

日々のコトとかなんか見た感想とか

ISUCON10予選を突破したので感想とやったことを書く(百万円ドリブン:21位)

目次

あいさつ

チーム百万円ドリブンは今年もISUCON本戦出場です!!!

こんにちは.

今年もISUCONの予選に出場したので,参加記を書きます*1

チームはISUCON7の初参加から同じ 百万円ドリブン です.

ISUCON参加も今回で4回目になります. 今まではどこかに集まって参加していたのですが,今年は初めて slack call を使って参加しました.

チームメンバーはmurataさんとgnuさんです. 今回のISUCON予選でも,Bot対策を爆速でやったり,使ったことがなかったspatial indexを使えるところまで持っていったりしていてパワフルです.

チームメンバーの参加ブログを読んでください!!!

nakario.hateblo.jp

chy72.hatenablog.com

レポジトリは以下のものです.

GitHub - nakario/isucon10q: 定額給付金x10

さて,ではやったことと感想を書いていきます.

やったこと

ISUCON10予選概要 問題は,物件検索と物件に合う椅子を検索するアプリケーションでした. 元ネタはSUUMO.

まずチームがやったこととしては,

  • 正規表現Botを弾く
  • インデックスを張った
  • N+1を排除した
  • Geometryに置き換えた
  • Jsonのインデント処理をなくした
  • 1サーバー1テーブルにした

だいたいこんなことをやってました.

メモリに余裕がありそうだったので,カウント系のクエリは一部メモリに乗っけてしまって良さそう, というのもやりたかったのですが,マージまではたどり着けませんでした.

自分がメインでやったのはインデックスを貼るのと,1サーバー1テーブルにするところ(のDB側の設定)です. あとはMySQLやNginxのログの設定や,複数台にしたときに使えるようにMySQLのユーザーを作ったりしました.

自分がメインじゃないところはチームメイトのブログにおまかせするとして,自分がやったことについて書いていきます.

【やったこと1】 インデックスを貼る

インデックスを貼るのは,

  • スローログを見て重そうなクエリを見つける
  • 見つけたクエリを EXPLAIN してインデックスが効いていないことを確かめる
  • 効きそうなインデックスを貼ってもう一回 EXPLAIN して確認する

という流れを繰り返しながらやっていました.

ぶっちゃけ時間がかかるし,スロークエリを見て効きそうなインデックスを一気に貼ってベンチにぶん投げる,というやり方のほうが早いしISUCONならそれでもいい気がします. 私は勇気がなかったので一個ずつやってました. (やっぱり非効率な気がする...)

インデックスを張っている途中でorder by popularity desc, id asc をどうするかという問題にあたりました. popularityを全部正負反転すれば良さそうという案もありましたが,結果的にはMySQL8.0にして降順インデックスを使いました. MySQL8.0にする判断にしたのは,前にISUCONの練習でやったことがあったからです.

スコアへの影響はじわじわ効いた感じです.

「劇的な改善にはならないがやらないと予選突破できないやつだな......」と思いながらやってました.

【やったこと2】1サーバー1テーブルにする

上記のインデックスを貼ったり,チームメンバーがしてくれた改善を含めても,MySQLのCPU使用率が高くボトルネックのままでした. どうにかしてDBを複数台で使おうということになり,

をしようとしました.

10分くらいで諦めました. なぜなら一度もやったことがないからです.

残り1時間くらいの状況で,一度もやったことがないレプリケーションの設定をするのはちょっと厳しかったです. 悔しいので本戦までに練習したいと思います.

  • 1サーバー1テーブルにすればいいのでは

という提案をしてくれたので,そっちに方針を変えました.

といっても自分がやったのはDBの設定を移したりMySQLのユーザーを作ったりするくらいでした.

ここで初めて2000点超えのスコアが出て,盛り上がりました.

【やったこと3】その他

MySQLやNginxのログの設定をしたり,restart.sh書いてログのクリアと再起動処理を一度にやれるようにしたりしました. ここらへんは流石に慣れてきて素早くできるようになってて良かったです.

良かったこと

一つは事前準備です.

今回は踏み台サーバー経由ということで,そのままではFrameGraphやNetDataなどのモニタリングツールが見えませんでした. 競技前にポートフォワーディングの設定を用意していたので,競技開始後にバタバタすることなくモニタリングツールを使うことができました.*2

MySQLを8.0にアップグレードするのも比較的スムーズにできたと思います. これはいつかの予習でやったことがあって,参考にしたサイトをScrapboxにメモしていたのが良かったです. (実行したコマンドをメモしておけばもっとスムーズだったはずなのでそこは反省)

こういう事前準備,スコアに直接関係はしないですがISUCONでは結構重要だと思います.

あとはインデックスをちゃんと貼ったり,データベースを複数台に配置したりするのをスムーズにできたのは,過去の経験が活きててよかったと思います.

良くなかったこと

静的ファイルの配信に手を付けようとしたことです. ドキュメントにベンチマーカーはAPIだけ見に行く,と書いてあるところは読んだのですが,頭から消し飛んでました. 結果的には手を付ける前にgnuさんに指摘されたので,「確かに!」となって時間をロスせずに済んだので良かったです.

強いて言うならやろうとしていることをちゃんと宣言したのはえらい!

あとは,後半気持ち的に焦ってしまったことです. 今回は幸い焦りによる凡ミスは(多分)無かったですが,焦ってもいいことはないので, ちゃんと最後まで落ち着いていられるようになりたいです.

まとめ

過去の経験を活かせているところもあればまだまだだなあと感じるところもあるISUCONでした.

競技終了後の感想とか見ると,結構知らないこともありました. MySQLが8.0でデフォルトでバイナリログを吐き出すようになったとか,generated columnとかspatial indexとか.

運営の皆さんもひとまず予選お疲れさまでした! ポータルのclerとかスコアページが死んでてもベンチマーカーへのキューイングはちゃんとできたりとか良かったです. Webプッシュ通知機能があるのは気づきませんでした!ごめんなさい!

本戦も頑張りたいと思います. 今度こそ100万円取りたい!!!

*1:過去の参加記は何故か下書きに埋もれています

*2:運営がssh_configのサンプルを用意してくれてて気づいた.運営の皆さんありがとうございます.