Webサービスをいい感じにチューニングしてスピードアップさせるコンテストのISUCON予選に初参加してきました。
結果はお察しという感じでしたが、あーだこーだ言いながらチューニングしてくのはとても楽しかったです。
ということで来年も参加するであろう自分に向けた参加メモです。
当日までの準備
時々チームメンバーの友人2名と集まって、ローカルマシン上で過去問を解いたり、当日の環境となるAlibaba Cloudで作ったECSインスタンス(名前がAWSと紛らわしい)に過去問環境を作って解いたりしてました。
ローカルマシン上で過去問を解くときは、matsuuさんが作成されているVagrantfile集を利用させていただきました。ありがたい限りです。
当日
計測ツールのインストールなどの当日の定型的な作業はansibleのplaybookに雑にまとめておきました。 つかった計測ツールはこの辺。
- kataribe
- webサーバのアクセスログからエンドポイント単位のプロファイリングする。
- netdata
- リアルタイムで諸々のパフォーマンスをモニタリングできるツール。ベンチかけながらこれを見つつインスタンス増やすとか構成変えるとか考えた。
- pprof
- Golang用のプロファイリングツール。メソッド単位で負荷見れる。Web UIでリモートから見れるの便利。
- Percona Toolkit
- 主にMySQLのスロークエリをみる
pt-query-digest
を使った。
- 主にMySQLのスロークエリをみる
当日開始からセットアップ〜一回目ベンチ〜計測ツールを入れて二回目ベンチまではスムーズに行きました。
バージョン管理などは、基本的にアプリとnginx、MySQLの設定ファイルあたりをそれぞれGithub上で管理。あとはスロークエリやkataribeなどの計測結果をベンチかけるたびにGithubのリポジトリに勝手にpushしてくれるシェルが便利でした。
その後は粛々と、過去問でもあったようなボトルネック箇所のチューニング(インデックス貼る。更新系がないテーブルをメモリに載せる。SQLやn+1のところ直す。)をしていきます。
ただ複数台構成に変えたらなぜかfailが連発。結局原因がわからないまま1台構成に戻して終了しました。
振り返り
雑ですがざっくりメモっておきます。
自分たちの中で勝手な制約を作ってしまった
-
goのpprofを使って重めな処理を眺めていると、パスワードのハッシュ化のbcryptの処理が重めでした。が、自分たちはここは勝手に変えちゃダメだよねーみたいな前提の思い込みをしていてスルーしてしまった。
-
レギュレーションに書いてあった「パスワードを平文で保存しないこと」というのは他の方式や、ストレッチ回数変えるのならいいよということだったんですね。
-
もちろん重いからと安直に、商用サービスでも「軽めなSHA-1にしよう!」とか「ストレッチ回数減らそう!」とは行かないと思いますが、「パスワードのハッシュアルゴリズムは変えちゃいけない」みたいな前提や制約見たいなのを自分たちの中で勝手に作ってしまったのは反省です。今回に限らず、普段の業務の設計でも前提を取り払って一から作るなら〜を考えたい次第です。
-
(2019/9/13追記) パスワードの平文/ハッシュ化保存を巡って色々盛り上がってしまってますね。速度を目指すコンテストである以上、トレードオフとなる要素についてはある程度細かくレギュレーションが必要なのかもしれません。商用サービスでもなくコンテストな訳で、バランスをとったレギュレーションとその運用はなかなか大変だったかと思います。はてブやtwitterでは一方的な暴言なコメントもあり悲しくなりますが、自分は来年度以降の開催も応援しております。
当日のアプリの品質的なところの担保難しい
- 当日はローカル環境を作ったりする時間はないだろうと思い、VS Codeの拡張機能のRemote Developmentを使ってアプリを改修していました。この拡張機能自体はとても便利なのですが、ちょっといじって画面から軽く動作確認してベンチ流したらバグ埋め込んでしまいfailみたいなことがちょくちょくあり、無駄に時間かかってしまった。とはいえテストコードをコツコツ書く余裕もなかった。
- ベンチマークを流した時のインプットとアウトプットを保存して手元で確認できるツールなどないだろか。(作ろう。)