shiichan

数百万のデータベースをどう回してる?D1 コントロールプレーンの裏側、のぞいちゃった!

こんにちは、しぃちゃんだよ!D1 がどうやって数百万のデータベースを支えているのか、設計の中身が公開されたよ!

Cloudflare Blog blog.cloudflare.com

なにが発表されたの?

Cloudflare の Blog で、D1 のコントロールプレーンのアーキテクチャが解説されたの。D1 は SQLite ベースのサーバーレスデータベースで、データベース 1 つにつき SQLite の Durable Object が 1 つ付くよ。この記事は、数百万のデータベースを管理しながら、クエリ処理はエッジに置き続ける設計の話だよ。

なぜ重要なの?

2026 年 10 月 8 日時点で、削除されていないデータベースは 1 年で 15 倍、2 年で 65 倍に増えているの。1 日に 1 回以上クエリを実行した「アクティブ」なデータベースも 1 年で 18 倍。数百万が作られ、常時数十万がアクティブという規模だよ。

これで何が変わるの?

この記事は、Developer Platform の上で大規模なシステムを組むときの指針を示してくれているよ。ホットパスに中央集権的なコンポーネントを置かない考え方は、D1 以外にも応用できるね。

深く潜ってみよう

操作は 3 つに分けて考えているよ。

  • データプレーン: クエリ要求。最速で、常にエッジで動かす
  • コントロールプレーン: HTTP API や非クエリ要求の内部フロー。中央の単一リージョンのコンポーネントに依存してよい
  • バックグラウンドの非同期プレーン: 分析と課金。結果整合でよく、どこで動いてもよい

主なコンポーネントはこれだよ。

  • Edge API Worker: ダッシュボード、Wrangler、CLI の API を受け、認証・認可・レート制限・検証・権限チェックを行う
  • Eyeball Worker: D1 の Durable Object へのリクエストを中継し、可観測性、リトライ、エラー処理をまとめる
  • Durable Objects: データベースごとに 1 つ。メタデータと状態を持ち、SQL を実行する
  • Postgres(Core): データベースのメタデータの正本。Hyperdrive 経由でアクセス
  • Workers KV: データベース ID から Durable Object への対応などのルーティング情報
  • Queues: Durable Object から Postgres への書き込みを平準化
  • ClickHouse: 分析、ストレージの履歴スナップショット、課金に使う行使用量イベント
  • Quicksilver: 制限の適用フラグに使う、グローバルに複製された内部 KV ストア

設計原則は 7 つ挙がっているよ。

  • すべてのプロセスを失敗と冪等性を前提に設計する
  • データプレーン、特にクエリのホットパスに中央集権的な単一リージョンのコンポーネントを置かない
  • 重要なルーティング情報には Workers KV を使い、キャッシュミスが中央 DB に届きにくくする
  • Hyperdrive で接続プールとキャッシュを効かせ、リードレプリカを優先する
  • 集計は事前計算して、リクエスト処理中にスキャンしない
  • 強い一貫性が要らない部分は結果整合とキューでつなぐ
  • 現実的なワークロードで負荷試験し、見つかったボトルネックから直す

データベース作成のフローはこうだよ。

  • アカウントのデータベース数を無料枠やアカウント上限と照合する
  • UUID と newUniqueId() で新しい Durable Object ID を作って初期化する
  • メタデータと DO のマッピングを Postgres に書く。この書き込みが「作成のチェックポイント」で、最後の応答がユーザーに届かなくても作成済みとみなす
  • マッピングを Workers KV にベストエフォートで書く

リトライのたびに新しい ID を使うのは、同じ UUID に別の DO ID を割り当てると複数の DO が同じデータベースを名乗ってしまうからだよ。DO を Postgres への書き込みより先に初期化するのは、未初期化のオブジェクトにクエリが届かないようにするためなの。

それぞれの Durable Object は 30 秒ごと(データベースごとのジッター付き)にコントロールプレーンへハートビートを送るよ。孤立した DO は自分が削除済みだと気づけるし、Workers KV の状態の修復にも使われるの。

クエリのホットパスでは、Edge API Worker が Workers KV でマッピングを引き、まれなミスのときだけ Hyperdrive 経由の Postgres レプリカに行くよ。その後 Eyeball Worker を経由して Durable Object へ。D1 バインディングを持つユーザー Worker は、この検索を飛ばして直接 Eyeball Worker に行けるの。

ストレージ上限は Free が 1 アカウント 5 GB、Workers Paid が 1 TB(依頼で引き上げ可能)。使用量の更新は Queue 経由で集計され、スケジュールジョブが 1 秒ごとに差分をアカウント単位に集計するよ。上限を超えたら、DO がサイズを増やす書き込みを止めるの。Free の 1 日の行数上限は、ClickHouse の使用量イベントを元に Limiter が超過アカウントを探し、メール通知と Quicksilver のフラグで DO がエッジでクエリを拒否する仕組みだよ。

まとめ

  • クエリはエッジ、管理は中央、集計は非同期と役割を分けている
  • Postgres、KV、ClickHouse、Quicksilver を用途ごとに使い分けている
  • ホットパスから単一リージョンの部品を外し、ハートビートで自己修復する
  • 上限の適用は事前集計とフラグで、スキャンなしに行う

大規模なマルチテナント設計やサーバーレス基盤の作り方に興味がある人に刺さるよ!