【ISUCON14】配車アプリ「ISURIDE」の全体像を図解!API高速化だけでは勝てない採点メカニズムとボトルネックの移動

ISUCON14の題材である「ISURIDE(イスライド)」は、Uber や GO のようなリアルタイム配車サービス(自律運転チェア版)。

「DBクエリを高速化したのに、なぜかスコアが思うように伸びない…」という現象に直面したとき、システム全体の構造と採点ルールを把握していないと原因を見失いやすい。

個別のチューニングに入る前に理解しておくべき 「ISURIDE全体の処理フロー」「API高速化だけでは勝てない理由」「ボトルネックが次の場所へ移動する仕組み」 を整理した。


TL;DR:この記事のまとめ

要するに、「大量の高頻度ポーリングと位置情報更新をバックエンドで捌きつつ、空いている椅子を効率よく配車して1つでも多くのライドを完了させる」 というゲーム。


1. どんなアプリ? Uber/GO 型の自動運転チェアサービス

ISURIDE は、街中を走る「自律運転式の椅子(チェア)」をユーザーがスマホアプリから呼び出し、目的地まで自動で移動できる配車サービス。

ISURIDEの全体イメージ

主な登場人物(4つのアクター)

  • 👤 カスタマー (User): スマホアプリから配車依頼を出し、到着を待って乗車する乗客。
  • 🪑 ドライバー / 椅子 (Chair): 乗客を乗せて走る自動運転端末。
  • ⚙️ マッチング (Matcher): 空いている椅子と配車待ちユーザーを結びつける司令塔。
  • 🏢 オーナー (Owner): 椅子を所有し、管理画面から売上を確認するオーナー。

2. なぜ重い? バックエンドに押し寄せる高頻度通信の正体

ISURIDE のバックエンドが高負荷になる最大の理由は、乗客端末と車載端末の双方が、状態同期のために大量のリクエストを送信してくる ため。

クライアント端末とバックエンドの通信構成
  • 椅子(車載端末): 移動しながら 現在地(GPS)を更新 し、自分宛の配車指示をポーリングで監視 する。
  • ユーザー(スマホ): 「椅子はマッチしたか」「今どこまで近づいたか」をポーリングで監視 する。

競技における前提

ベンチマーカー側の実装では、通知取得APIへのポーリング待機時間がデフォルトで 30ms 程度と非常に短く設定されている。

クライアント側の通信間隔は競技者側で変更できないため、「押し寄せる大量のリクエストを、バックエンド側でいかにミリ秒未満で捌き切るか」 が前提条件となる。


3. 1ライドが完了するまでの全ステップ

配車依頼から目的地到着・決済までのライフサイクルは、以下のステップで進む。

ライド完了までの流れ
  1. 配車依頼 (MATCHING): ユーザーが乗車位置と目的地を指定して配車を依頼。
  2. お迎え移動 (ENROUTE): Matcher(約500ms間隔で巡回)が空いている椅子を割り当て、椅子が乗車位置へ移動開始。
  3. 乗車 (PICKUP / CARRYING): 椅子が乗車位置に到着し、ユーザーが乗車して目的地へ出発。
  4. 目的地到着 (ARRIVED): 椅子が目的地に到着。
  5. 決済・評価 (COMPLETED): ユーザーが決済と評価を完了。ここで初めて1つのライドが完結する。

4. 採点式を読む:「APIが速い = 高得点」ではない理由

ISUCON14 の公式レギュレーションにおけるスコア計算式は以下の通り。

スコア =(お迎え移動距離 × 0.1)+(乗客を乗せた移動距離 × 1.0)+(ライド完了数 × 5)

採点式の直感解説

初見でつまずきやすいポイント

  1. APIレスポンスタイム自体には直接点数が付かない: いくらAPIをミリ秒未満に高速化しても、実際に椅子が乗客を乗せて目的地まで移動し、決済が完了(COMPLETED)しないとスコアは加算されない
  2. ユーザー・椅子の「同時1ライド制約」: ユーザーも椅子も、現在のライドが完了するまで次の配車依頼や受注ができない。1回のライドにかかる拘束時間が長いと、街全体の回転率(完了数)が落ちてしまう。
  3. 遠い椅子マッチングによるタイムロス: 初期実装の Matcher は遠く離れた椅子を割り当てがちなため、お迎え移動(ENROUTE)に時間を浪費し、椅子の稼働効率が上がらない。
  4. 待ち時間の長さと評価への影響: マッチングやお迎えに時間がかかるとユーザーの評価が下がり、間接的に新規ユーザー獲得やライド発生ペースへ悪影響を及ぼす。

5. 「ボトルネックは移動する」というチューニングの本質

ISUCON14 において「DBクエリを速くしたのにスコアが大きく伸びない」と感じる場合、ボトルネックが次の場所へ移動した ことを意味している。

ボトルネックのシフト
  1. 初期状態(DB律速): 通知取得や座標更新の裏でテーブルフルスキャンが多発し、DBがシステム全体の時間を食い潰している状態。
  2. DB高速化後(Matcher律速): DBが軽くなると通信詰まりは解消されるが、今度は 「遠い椅子を割り当ててしまうマッチング品質」や「Matcher プロセスの処理能力」 が次の壁として顕在化する。
  3. その後の世界(通信オーバーヘッド): マッチングを近傍探索に改良した後は、大量の位置情報更新(coordinate)の書き込み負荷や通知のリアルタイム化(SSEなど)が勝負を分ける。

6. まとめと今後の改善ロードマップ

全体構造を俯瞰すると、どのような順番で手を打つべきかが明確になる。

改善ステップ 対象領域 狙い・効果
Step 1 (完了) DBインデックス最適化 高頻度アクセスのフルスキャンを撲滅し、DB負荷を半減
Step 2 (次回) Matcher の複数件・効率化 マッチャーのキュー詰まりを解消
Step 3 近傍マッチングアルゴリズム 最も近い椅子を割り当て、お迎え時間を最小化
Step 4 coordinate 位置送信の軽量化 大量の位置情報更新をインメモリ化 / バルク処理
Step 5 通知の SSE 化 ポーリングを廃止し、リアルタイムプッシュ配信化

次回からは、このロードマップに沿って 「なぜSQLを高速化したのにスコアが伸びなかったのか?」「マッチャー改善でどうスコアを跳ね上げるか?」 の実践編へ進む。