⛓️

ISUCON11予選 反省会

2021/08/22に公開

ISUCON11に初参加して、予選敗退しました。

悔しさを糧に来年も頑張りたいですが、まずは鉄を熱いうちに打っておきます。

また、ここでの反省は”チームとして”ではなく、”個人的に”という話です。

上手く出来た事

自分用memo-isuconを作成した

練習では、catatsuyさんのmemo_isuconリポジトリを見て作業をしていました。
https://github.com/catatsuy/memo_isucon

このREADMEに書かれている事をファイルに書き出して、自分にとって欲しいものへの検索がすぐに行えるようにしました。
また、アプリケーション名などを変数に置き換えて、エディタで一気に書き換えがおこなえるようになっています。

サンプル

# Database: {isucon_db}
# バックアップ
mysqldump -uroot {isucon_db} > dump.sql
# 戻す時
mysql -uroot {isucon_db} < dump.sql

結果、練習よりもスムーズに行えた気がします(体感値)

データベースのGUIクライアントツールを用意していた

これは、たまたま容易していただけなのですが、DBを俯瞰的に眺める時はGUIで操作できるアプリケーションがあるととても助かります。
おすすめDBクライアントツールはTablePlusです。
https://tableplus.com/

出来たけど無駄に時間かかった事

DBから画像の抽出に手間取った

今回、isuテーブルのimageカラムに画像がblob型で入っていました。これを抽出してバイナリファイルとして書き出すだけの事ですが、無駄に時間が掛かりました。

まず前提として、ISUCONはGo言語で参加しました。しかし自分はGo言語とはフレンドリーな関係ではないので、チームに影響が出ないところはPythonで書くことにしました。

PythonでDBを操作すること自体はやったことがあるし、やり方もイメージ出来ていたので楽勝だと思っていたのですが、今使っているPCの環境にMySQL操作系のライブラリが入っておらず、それを探すところからはじめました。
Python3.7で動きそうなPyMySQLをインストールしました。

$ pip install PyMySQL  # インストールは成功していた
$ python -m "import PyMySQL"
[path-to]/bin/python: No module named import PyMySQL

なんで???

予想ではpyenvとpipが上手く紐付いていない気がして、闇が深そうなので諦めました。

次に、Goのアプリケーション内にGETアクセスで全ての画像の書き出しが出来るAPIを立てようとしました。しかし、Goでの書き方がわからない事が多く、やり方がイメージ出来なかったので諦めました。

最終的にDBクライアントツールのエクスポート機能からCSVに書き出しました。PythonでそのCSVをパースしてバイナリファイルとして保存しました。MySQLとの接続を考慮する必要が無くなったので、標準ライブラリだけで何とか出来ました。(実際はpandas.read_csv使いました)

※追記
今見たらPython実装のディレクトリにrequirementsがありましたね。。

SSHの接続にあたふたした

本番ではGitHubで使っている公開鍵がサーバーに登録されていました。これは練習で使っていた公開鍵ではありませんでした。.ssh/configはチーム共通で使っていたので、Permission denied (publickey)となりました。
結局、共有した.ssh/configから各サーバーのIdentityFileを書き換えました。

秘密鍵はどれがどのサービスで使っているか、ひと目でわかるようにしましょう。

やったけど出来ていなかった事

デプロイスクリプトが間違っていた

init.shでテーブル全てを作り変えており、POST /initializeで必ず呼ばれていたので、サーバへのデプロイはビルドしたGoアプリケーションとsqlファイル(ここにインデックスを貼る処理を書いていた)をアップロードする必要があります。
webapp/sql/配下は全てrsyncしていましたが、rsync先を間違えていました。

rsync -vau ../sql/ $server:/home/isucon/isucondition/webapp/sql/

正しくは

rsync -vau ../sql/ $server:/home/isucon/webapp/sql/

でした。

単に注意不足でしたが、デプロイスクリプトの不具合はチーム全体に迷惑をかけてしまっているので猛省です。

共通の.ssh/configの設定が間違っていた

デプロイスクリプトの都合上、チーム全員が共通のホスト名を使うようにし、そのために共通の.ssh/configを使うようにしていました。
それを作る担当が僕だったのですが、ssh/configの書き方をよく理解せず、memo_isuconの.ssh/configをコピペしていたので、ProxyCommandをつけていました。

Host isu01
  HostName xxxxxxxxxxxx
  User isucon
  Port 22
  IdentityFile ~/.ssh/id_rsa.github
  ForwardAgent yes

Host isu02
  HostName xxxxxxxxxxxx
  User isucon
  Port 22
  ProxyCommand ssh isu01 nc %h %p
  ForwardAgent yes

isu02はisu01を踏み台にする必要はないし、そうすると逆に接続できなかったりするので、ProxyCommandは完全に不要です。

自分以外のチームメンバーはゴリゴリにインフラやっている人なので、ミスは1回のエラーで瞬殺だったのですが、このような基礎的な事が出来なかったのは猛省です。

やり始めたけど出来なかった事

Go言語でインメモリキャッシュ

画像をファイルに書き出したら、それ以外のisuテーブルのデータをインメモリにキャッシュできそうだったので、やってみました。が、出来ませんでした。
前述のとおり、自分はGoで書かれたコードを読む事が得意ではないので、どうやって実装に組み込めばいいかわかりませんでした。

Nginxでtry_filesの設定

今回は画像にユーザーのログイン認証が必要だったのですが、アプリケーションで画像を返している部分をNginxで返すことで高速するTipsは、過去のISUCONで何回かありました。
つまり、「画像をNginxで返すようにしましょう」って方針になったら、出来る事が当たり前に期待されるのですが、出来ませんでした。

具体的には、URIが/api/isu/:jia_isu_uuid/iconとなる時に/home/isucon/webapp/public/img/:jia_isu_uuidを開くようにしたかったのですが、わかりませんでした。練習不足です。

まとめ

上記の反省点は、天才的な閃きが必要だったり、圧倒的に技術力が足りないことではなく、単に練習不足です。

また来年、がんばります。

リンク集

予選で使ったリポジトリ
https://github.com/catatsuy/isucon11q

チーム全体として何をしたか(出来なかったか)などのまとめ。catatsuyさんの感想など。
https://zenn.dev/catatsuy/articles/6265ca623545ed

Discussion