Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

Durable Objects のコントロールプレーン / データプレーン構成パターン

最終更新 Markdown で表示Agent セットアップ

はじめに

Durable Objects は、Cloudflare Workers の上に構築され、グローバルインフラネットワーク上の複数拠点にまたがります。 各 Durable Object インスタンスは、リクエストをまたいで残る永続ストレージ、インメモリ状態、シングルスレッド実行を持ち、特定リージョンに配置できます。

1 つの Durable Object インスタンスには、一定の 性能とストレージの上限 があります。 そのため、単一インスタンスの上限に縛られずにアプリケーションをスケールするには、アプリケーションデータをできるだけシャーディングし、Cloudflare のインフラ を活かして Durable Object インスタンスを世界中へ分散し、データとコンピュートの両方をユーザーの近くへ寄せます。

このドキュメントでは、コントロールプレーンとデータプレーンを分離し、機能を落とさずに性能と信頼性を高める構成パターンを説明します。

  • コントロールプレーン は、リソースのメタデータを管理する管理用 API を提供します。たとえば、ユーザーが wiki を作成 / 削除する、ユーザーの wiki 一覧を取る、といった操作です。
  • データプレーン は、アプリケーションの主機能を提供し、リソースデータへの操作を直接扱います。たとえば、wiki の内容の取得と更新、共同編集ドキュメントの更新です。データプレーンは意図的に単純で、扱うリクエスト量は通常はるかに大きくなります。
  • マネジメントプレーン は任意の構成要素で、コントロールプレーンより高い抽象度で操作し、設定と運用を簡単にします。このドキュメントでは扱いません。適用する原則はコントロールプレーンと同じです。

コントロールプレーンとデータプレーンの分離パターン

このパターンでは、アプリケーションは少なくともリソースタイプごとに 1 つの Durable Object インスタンスを持ち、そのコントロールプレーン操作をすべて処理します。データプレーン操作には、アプリケーション内で作られたリソースインスタンスごとに 1 つずつ、必要な数の Durable Object インスタンスを使います。

Durable Object インスタンスは、リソースごとに 1 つずつ、数百万までスケールできます。

この構成の主な利点は、データプレーン操作(通常はコントロールプレーンよりリクエスト量が多い)を、コントロールプレーンの Durable Object を経由せず、リソースデータを持つ Durable Object インスタンスが直接扱うことです。 そのため、アプリケーションの性能と可用性は、単一の Durable Object インスタンスではなく、数千から数百万の Durable Objects に分散します。

汎用のリソースタイプ XYZ を例にします。実務では XYZ は wiki、共同編集ドキュメント、ユーザーごとのデータベース、その他のリソースタイプです。

図 1: Durable Objects のコントロールプレーン / データプレーン構成パターン
図 1: Durable Objects のコントロールプレーン / データプレーン構成パターン
  1. ロンドン(LHR)のユーザーが、リソース XYZ の作成リクエストを開始します。リクエストは最寄りの Cloudflare データセンターへルーティングされ、アプリケーション API を提供する Workers フリートが受け取ります。
  2. Worker コードは、タイプ XYZ のリソースを管理する、適切なコントロールプレーン Durable Object インスタンスへリクエストを送ります。Durable Object インスタンスの参照には idFromName を使い、名前(control-plane-xyz)で指定します。マッピングを保持しなくても、コントロールプレーン Durable Object へすぐアクセスできます。
    • コントロールプレーン Durable Object の配置は、最初にアクセスしたリクエストの近く、または Location Hints で明示したリージョンになります。
  3. コントロールプレーン Durable Object インスタンス(control-plane-xyz)はリクエストを受け取り、すぐに別の Durable Object インスタンス(data-plane-xyz-03)をユーザーリクエストの近くに作ります(Location Hints を使用)。リソースの内容を持つ実体を、作成したユーザーの近くに置きます。 - 作成した Durable Object インスタンス(data-plane-xyz-03)に対して、カスタムの init(...) を呼び出し、リクエスト処理の開始に必要なメタデータを渡します。 Durable Object インスタンスはこの情報をローカルストレージへ保存し、必要な初期化を行います。 以降の各リクエストに、処理に必要な情報がすべて含まれている場合、この手順は省略できます。たとえば、リクエスト URL のパスとクエリパラメータに必要な情報がすべて入っている場合です。 - Durable Object(data-plane-xyz-03)の参照には idFromName を使い、名前ベースのリソース識別子を使えます。 - 代わりに newUniqueId で参照すると、名前ではなくランダムなリソース識別子が得られます。このランダム識別子はユーザーへ返し、以降のリクエストでリソースへアクセスするときに指定してもらう必要があります。
  4. コントロールプレーン Durable Object インスタンス(control-plane-xyz)は、生成した識別子(data-plane-xyz-03)をローカルストレージへ保存し、作成済みリソースの一覧 / 削除ができるようにしたうえで、Worker へ返します。
  5. ユーザーはリソース作成の成功レスポンスと対応する識別子を受け取り、(任意で)そのリソースへリダイレクトされます。
  6. ユーザーは、前の手順で返ったリソース識別子に対して API へ書き込みリクエストを送り、リソースの内容を更新します。
  7. Worker コードは、渡されたリソース識別子を使い、そのリソースのデータプレーン Durable Object インスタンス(data-plane-xyz-03)を直接参照します。Durable Object インスタンスは、内容をローカルの永続ストレージへ書き込み、適切にレスポンスを返します。
  8. ポートランド(PDX)の別ユーザーが、以前作成したリソース(data-plane-xyz-01)へ読み取りリクエストを送ります。
  9. Worker コードは、指定されたリソース識別子のデータを持つ Durable Object インスタンス(data-plane-xyz-01)を直接参照します。Durable Object インスタンスは、ローカルストレージを読んで内容を返します。

アプリケーションのデータモデルがリソース単位でシャーディングできるなら、好きなだけスケールアウトでき、そのリソースへアクセスするユーザーの近くにデータを置けます。

必要な性能を得るために、同じパターンを必要な回数だけ適用できます。

たとえば負荷に応じて、コントロールプレーン Durable Object をさらに複数の Durable Objects へシャーディングできます。 タイプ XYZ の全リソースを 1 つの Durable Object インスタンスで扱う代わりに、リージョンごとに 1 つ置けます。 名前ベースの参照なら、対象インスタンスの指定も簡単です。

まとめると、アプリケーションのデータモデルを、自己完結した細かいリソースへシャーディングできれば、リソースごとに少なくとも 1 つの Durable Object インスタンスを割り当ててスケールアウトできます。

関連リソース

役に立ちましたか?