ISUCON14参加記 nodejs実装を利用し131位でした

ISUCON14にチームownmaとして参加しました。
結果、スコアは9263点、131位だったようです。
雑ながら参加記を書きます。
(ISUCON8から楽しく参加させていただいているものの、インターネット上に参加記を書くのは今回が初めてです。ようやっと…)

弊チームのリポジトリ: https://github.com/kefi550/isucon14

主なプロフィール

ISUCON13と同じメンバーでチームを組み、同じくnodejs実装を使った
nodejsの選択は、会社のプロダクトの多くがTypeScriptであり、メンバーが一番慣れているから 会社の同僚3人チームだったが、わたしが11月中旬に退職したり、メンバーそれぞれなんやかんや忙しかったりして、チームでの練習時間というものがあまり取れなかった
前回ISUCON13では、ツールを十分に使いこなせていなかったりといった反省点はあったものの、ほぼ何もできずに終了していたため、
今回練習時間が短くなってしまったことからも、前回と言語、ツール等の環境は変えずに、できる改善をやろうという意気込みで臨んだ

練習

ISUNARABE にお世話になり、ISUCON12予選、ISUCON13本戦で素振りした
特に時間制限を強く意識せずに、取り組みを実装してスコアを上げる体験を思い出すことを目的

監視等のツールセットはISUCON13とほぼ完全に同じものを使うことにした

  • alp でアクセスログからエンドポイントごとのリクエストカウントやレイテンシをみる
  • pt-query-digest でスロークエリを見る
  • Netdata で数分前~リアルタイムでのOSやプロセスのメトリクスをみる
  • NewRelic APM でトレーシング

前回と同じツールセットで臨むといえど使い方を皆忘れており、ツールセットの運用という点だけでも素振りの価値が大いにあったと思う

序盤

  • ansibleで各ツールを導入
    • ただ、今回ansibleが動かなくて、早々にあきらめて手動で準備した
  • 11:00ごろまでなんやかんや準備系やってた
  • pt-query-digestで出たクエリにひたすらindex

13:00ごろ時点で4866点
NewRelic APMで、エンドポイントが分類されず全部 * としてまとまってしまった(honoとの相性?)
結果的にNewRelic APMはあまり使わず、database起点にトレースを見たり、* から目grepで気になるトレースを見たりしてた

中盤

  • インスタンス3台使うように変更
    • isu1: nginx+app+matching, isu2: mysql, isu3: app
    • このときに出た9615点が最大瞬間風速で、なぜか以後しぼんでいった
  • TRIGGER を使って最新のride statusを保管するテーブルを作成
  • 外部 payment API へのリクエストにリトライをつける
  • chairの緯度経度、総移動距離を保管するテーブルを用意して /api/owner/chair のクエリを改善

16:15ごろ時点で7770点
わたし以外の2人のメンバーが手が速いことから、わたしは諸ツールを見て改善アイデアを出しそれを2人が実装してくれるといったスタイルだった
GET nearby chairのクエリ発行量を抑える改修をやってたけどベンチを通過させられなかった(最終盤にメンバーがやってくれた)

13時くらいの時点ではリーダーボードに載ってテンションがあがっていた

終盤

  • 中盤からハマっていたGET nearby chairsのN+1を改善
  • 再起動試験はやるつもりではいたものの、↑の実装が山場だったためやらないことにした
  • 競技終了直前までベンチマークが通らない(0点)地獄だったが、なんとかバグ解消し点数を獲得
  • 最後にこれまで試していなかったmatchingの間隔を若干短くしてベンチマーク実行して時間切れ
    • 0点にならないことを祈った
    • (後にこの変更は反映されていないことが分かった)

最後の最後でスコアが出て、そのまま結果スコアとなった

感想戦

今回は競技終了後日に感想戦モードとして競技と同じインスタンスを使って、かつベンチマーカーも提供されISUCONを続きから遊べるようになりました。とても楽しい、ありがたい施策です。

  • まず、最終スコアが9263に対し、追試スコアが13432とかなり高いベストスコアだった
    • ISUCON_MATCHING_INTERVAL を少し短縮した変更が、実はmatchingプロセスを再起動していなかったために適用されていなかった
    • おそらく追試時に行われたインスタンス再起動時にはじめて反映され、その結果大幅にスコアアップした
  • 感想戦で ISUCON_MATCHING_INTERVAL を0.01まで短縮したところ、 27372点を叩き出す
  • matchingのアルゴリズム変えずにクエリ発行量だけ減らすことをやってみたものの、スコアはほぼ変わらず
  • 最終的に 28761点 で感想戦終了

競技時は全インスタンスでCPU使用率等リソースを目一杯使っている状況だったので、ここからさらにmatching頻度高めて負荷を高めるのは無理だろうという先入観を持ってしまっていた
まさに推測するな計測せよに反していた…

おわりに

  • ISUCON今回もめちゃくちゃ楽しかったです。毎度毎度面白い問題をありがとうございます
  • 前回と同じチームで、前回ほぼスコアをあげられずにFinishしてしまった反省を胸に、なんとかスコアは伸ばす体験はできたのでよかった
  • ISUCON11予選だったかな?なんかのパラメータを調整したらそれだけでスコア上がった(これも競技後に判明)という惜しいやつをまたやってしまった
  • 感想戦モードはひたすらありがたい、楽しい施策でした。
    • 感想戦ができるとたらればが捗ってしまう