2023年12月23日

ISUCON 13 参加レポート

概要

ISUCON 13 に、
インフラ領域を主領域とする @ttyngmn と、
バックエンド領域を主領域とする @tmyksj で参加しました。

結果、 2 人チームながら 35,679 点で、 661 チーム中 48 位( fail したチームを含めて 58 位)でした。

ISUCON 13 について

こんいすー こんいすー

ISUCON 13 の問題内容はこちらです!
https://isucon.net/archives/58001272.html

事前準備

事前学習として、以下の書籍 2 冊を読み進めました。 CPU 、メモリ、ディスクといったシステムについての詳細、数多くの可観測性ツールやパフォーマンスチューニングの方法論の理解が進みました。

また、事前練習は、事前講習 2022 を参考にしたタイムテーブルの整備と、オフラインでの練習を何度か行いました。
https://www.youtube.com/watch?v=8NjJcarqv50

以下は、チーム固有の工夫点です。

コミュニケーション

コミュニケーションには、オフラインコミュニケーションと、会社の Slack を併用しました。方針決めや「デプロイするよ」のロックは口頭で行い、ベンチマークの結果などの共有は Slack (と GitHub Issues )を使用しました。

git の使い方

git は main ブランチひとつで行いました。
それぞれの主領域がインフラ領域とバックエンド領域に分かれているため、同じブランチを使ってもめったにコンフリクトしない判断です。実際にコンフリクトは発生せず、この判断は功を奏したように思います。

本番でやったこと

インフラ領域

ログの解析 / 出力 / ローテートの仕組みの構築

ログの解析 / 出力 / ローテートの仕組みの準備ができていないとお話にならないことが事前練習でわかっていました。そのため、ログの解析 → ファイル出力 → ログローテートを行うスクリプトを準備しておき、本番では微調整のみで環境を構築しました。これによって、残り時間の大半を OS やミドルウェアのパフォーマンスチューニングに専念できました。

OS やミドルウェアのパフォーマンスチューニング

OS やミドルウェアの設定値は一般的な最適解がある程度見えている、かつ逆効果になることはそうないだろうと判断し、ボトルネックがインフラレイヤに移るのを待たずにチューニングしました。

サーバの役割について

アプリケーションサーバと DB サーバを分けるのは常套手段です。そのため、ある程度落ち着いたタイミングで、アプリケーションサーバと DB サーバを切り分けました。

  • 1号機: MySQL(DNS用) / PowerDNS / Nginx / App
  • 2号機:
  • 3号機: MySQL(App用)

しかしながら、 1 号機 の DB 使用率が減らず、思ったよりも DNS がパフォーマンスに影響を与えることがわかります。その時点で DNS サーバを 2 号機に切り分けることを決めました。

DNS サーバを切り分けるにあたり、 DNS へのリクエストを行う一部エンドポイント向け処理の扱いに苦慮しました。というのも、その場で調べた範囲では DNS へのリクエストをローカル向けからリモートサーバ向けに切り替える方法が見つからなかったためです。そのため DNS へのリクエストを伴うエンドポイントの処理そのものを DNS サーバに振り分けることにしました。最終的に、以下の構成としました。

  • 1号機: Nginx / App
  • 2号機: MySQL(DNS用) / PowerDNS / App(DNS処理)
  • 3号機: MySQL(App用)

バックエンド領域

バックエンド領域では、マニュアルの確認とアプリケーションをひととおり読むところから始めました。アプリケーションを読み進めると、

  • DB のカラムにインデックスがほとんどない
  • N+1 Queries がとても多い
  • 画像は都度 hexdigest を計算している.

といったことがわかります。特に N+1 Queries がとても多く、改善しきれません。
そのため、 8 時間の中では狙いを決めて改善することにしました。

適宜 DB のカラムにインデックスを付与したあとは、ユーザーの行動を予測しつつ、効果的に見えそうなところから N+1 Queries を改善しました。

  1. ベンチマーカによると /api/user/:username/statistics のリクエストタイムアウトが多いため、ベンチマークの支障にならないように、まずはここを改善しました。
  2. ユーザはまず Live を検索するでしょう、ということで /api/livestream/search (と、一緒に改善できる箇所)を改善しました。
  3. Live を開いたらコメントを取得するでしょう、ということで /api/livestream/:livestream_id/livecomment を改善しました。
  4. また、同時にリアクションも取得するでしょう、ということで /api/livestream/:livestream_id/reaction を改善しました。

どこを改善するとよいかの判断には、 alp のログ出力が非常に役立ちました

そして、 N+1 Queries はまったくもって終わらず、ここで時間切れです。
ログの停止などのあと片付けで終了しました。

ISUCON 13 では、もっぱら N+1 Queries の改善に終始しました。
ユースケースを想定して改善ポイントを順に改善できたのはよかった点です。
一方、見るからに重たそうなスパム判定やアイコン画像配信のキャッシュなど、念頭に置きつつまったくもって着手できなかった点は惜しい点です。

まとめ

oRo のメンバーで ISUCON 13 に参加し、おおよそ上位 10% のスコアを取得しました。
できた点、できなかった点はありますが、非常に勉強になりました。

ISUCON 運営メンバーの方々ならびに関係する方々に、感謝いたします。

株式会社オロではエンジニアを募集してます!

株式会社オロ 採用情報

興味のある方はお気軽にご連絡ください!

RELATED POSTS