名もなき未知

エンジニアリングとか、日常とかそういうのをまとめる場所。

ISUCON10に参加した(予選敗退)

久々にコンテストらしいコンテストに参加したと思います(本当か?これは嘘です、まあもう少し詳しくは後日)

ISUCON出ました。チームメンバーは会社以外の人と組んでみたい気持ちがずっとあり、前々から交流のあった @pytran3 さんが興味を持っていたので、やりましょうという流れで、チームを組んだ。ちなみにチーム名は「ちゅかちゅかちゅかぴ〜♪」です(身内ネタ全開なので、あまり掘り下げないでほしい)。

僕自身は普段はバックエンドって言ってもほとんどAPIコード書いてばかりの人なので、インフラ回り不安ありつつ学べることがあればいいなと思って参加しています。

前日までの用意

Docker で立てたり、 pytran さんが NewReric 試したりしてた。ただ、十分に準備できたかというと、2人とも技術書典の原稿を抱えていて、9月入ってからちょろっと練習した程度でした。

まあここに対してはいろいろ思うことがありますが(主に自分の精神面がかなり不安定だったので、それを戻して大会に参加するだけでやっとだった)、もう少し日ごろからWebアプリと戯れておきたいなというお気持ちが強まりました。

当日

終始ペア作業的に進めていて、2人でコードリーディングしながらやばそうな点を見たり、 slow_query_log 見たりしてました。

前半は結構自明なカウントクエリ周りを直したり、ルールの読み込みをしたりして軽めにコード修正を行いました。 MySQLサーバの分割、思ったよりさくっとできてよかったなと思っています(なんで過去こんなに苦戦してたんだ…)。

あとインデックス貼ったり。雑に検索に使われてそうで、数値または特定の値しかとらないようなものは index がさっと入れちゃえでやってました。若干効いていたとは思います(スロークエリが減っていたので)。

pytranさんが前半はNewReric用意してくれたので、リクエストベースで遅そうなところとDBネックになってるところは割と早く特定できました(NewReric使いこなせませんでしたが、役立てはしました、タスカルタスカル…)

後半はいろいろ攻めていきましたけど、整合性保ったり POST リクエスト早く返すところで失敗しまくったりして、僕は全然ダメでした。

slow query log を見ながら、明らかに ORDER BY がかみ合わずに file sort してるのはわかったのですが、ソート順をいい感じに整理することができなかったです(ソート用にもう1つカラム足してインデックス貼ったが、どうもデータ登録速度が間に合わないらしく、POSTリクエストがうまくさばけなかった)。

ORDER BY がだめそうなのは、個人ブログを読んだり、公式ドキュメントを読んだりして行く中で気づくことができました。 https://dev.mysql.com/doc/refman/5.6/ja/order-by-optimization.html

対応としては下記が考えられそうです。

  • そもそも評価値をマイナスにしていい感じにやる(これはできたはずなんだが… 冷静になれていなかった)
  • 複合インデックス的にやる
  • MySQL 8.0に上げ降順INDEXを使う

あとは特徴項目の CONCAT と like の引きはがしもうまくいかなかったです。 FULLTEXT INDEX でなんとかならんかなと思いましたが、やっぱりPOSTの処理周りで時間が足りなくなり、0点になってました。うーん。厳しい。(ちなみにこれを参考にした https://tech.bita.jp/article/4 )

ちなみに setbit とかで頑張って対応する手もあるらしいんだけど、全然思いつきもしなかった。 https://stackoverflow.com/questions/60645538/how-do-you-store-and-mutate-a-bitmap-bitset-using-mysql

っていうのを3時間以上かけてやって虚無ったので、さいご nginx と mysql 周りの設定をいじくったりしていました。あまり成果は出せていない気がする。pytranさんは N+1 クエリの問題を頑張ってました。若干スコア改善してたので、すごい…。

nginx はいい感じのテンプレがあったので、これを参考に設定を進めていきました。めっちゃ助かる。

https://gist.github.com/koudaiii/386eb55a29b1adc19c5e

以上をごちゃごちゃやっていたのですが、最後いろいろデバッグ用の設定外して800点程度だったので、力及ばずといったところでした。 予選敗退となりますが、順位はうーん、まあ真ん中よりチョイしたくらいかなとは思っています(順位表凍結時点ではごちゃごちゃいじっててベンチ0点だったので、よくわかりません。再起動?一回も試してないので、通ってないかもなー…)。

他知らなかったこと、あとから知ったこと

もう少し手を伸ばしたいところ

  • MySQL 8.0 周り
    • 5系ならまだなんとかなりそうだが、8系への経験とかがなさ過ぎ
    • 後この手のコンテストでミドルウェアをえいやと変えるのも得意ではない
    • 今後の課題点の1つかなと思う
  • nginx 周り
    • あるあるコンフィグとか、あるある設定くらいは押さえときたいような気もする
    • (これは軽くで終わりそう)
  • 監視系
    • NewReric 使いこなせていなかった(学習する時間の問題もある)
    • そのほかのツールの比較検討もできてない
    • 1つでいいので自分がちゃんと使えるツールは持っておいたほうが良いかなとなった
  • INDEXや特殊なカラムの取り扱い
    • 基本的なデータの入れ方とか、インデックスの貼り方はまあまあ今回役立てた気がする
    • 上のほうの自分があまり使ってこなかったインデックスたちに対しては全然歯が立たなかったので反省
  • 監視系含めて仮想環境立てるとか
    • パフォーマンスとかコンテストで成績取るとかとは別に、どうアプリケーションを構成するか、またそれを楽に開発できるようにするかみたいなのは考えてもよいのかも
    • 具体的に何を、みたいなのは何も思い浮かんでない
  • CPUやメモリ使用率周り
    • 朝になってから思い出したが、このへんできてなかった
    • 2台しかマシン使えなかったので、もう1台を分散して使うまたは前半は開発機にして2人でコードいじるとか、そういうのやるのもありだった

あとこれは買ったので目を通してみようと思う(3, 4章あたりを読んで多少学びがあればいいなと思っている…)

まとめ

参加した中で今回が一番楽しめたし、一番勉強になったなと思ってます。できなかったなーという気持ちはありますが、悔いなく最後まで考え抜けたので参加したことに対してはポジティブな気持ちしかないです(そしてチームを組んだ pytran さんに感謝)。

あと何もできなかったわけでもなかったのと、チャレンジしてうまくいかなかったのはまあ悔しかったんですが、観測結果からどんどんこういうアイディアでやってみようと動けたのは良かったと思っています。惜しむべくはもう少しチャレンジしたものを成功させることができなかった点ですが、まあゆるふわで楽しんで参加しよう!ってコンセプトは最初からチームで認識合わせしていたので、最後まで楽しんでやることができ、とても良かったと感じています(そういう認識合わせは大事)。

また以前は何もできなさ過ぎて、感想戦を見ても何もわからんので真面目に読んですらなかったのですが、自分が引っかかったこれ、この方法で突破できたのか… という発見が今回のコンテストでは多かったように思えます。少しは成長したのかもしれないなというのを久々に実感しました。

決勝に進出される皆様は陰から応援しています…。

来年はどうなるかわかりませんし、誰と出るのかもわかりませんが、少しづつ順位を上げられるよう日々の鍛錬を怠らず、心身ともに健康に過ごしていきたいです。