🐈

(限界突破)10000個のCloudflare D1を1つのWorkerにバインドすると、どうなるのか?

2023/11/14に公開

こうなるのだ

期待させてすみません、デプロイが失敗するだけです。

まずは以下のようなwrangler.tomlファイルを用意しましょう。

name = "test"
main = "src/index.ts"
compatibility_date = "2023-10-25"

[[d1_databases]]
binding = "Test1"
database_name = "test-1"
database_id = "30a1add2-5713-4b69-82e1-14a4f7f3619a"

[[d1_databases]]
binding = "Test2"
database_name = "test-2"
database_id = "aeaceaa2-02fb-4f34-8926-96cfd10a45d7"

# 省略

[[d1_databases]]
binding = "Test10000"
database_name = "test-10000"
database_id = "f2e5ad60-3a14-47d5-9e77-5f2a07c31a9d"

デプロイしてみましょう。

$ wrangler deploy

...省略...

✘ [ERROR] Received a malformed response from the API
  -> 504 Gateway Time-out

ここで注目するべきはD1の個数でリクエストをきょひしているわけではない点です。レスポンスが帰ってくるまで1分ほど待たされたので、リソースのプロビジョニング処理は継続していたものと推測されます。

なお、ローカル環境はOOMでサーバーの起動が失敗します。

$ wrangler dev

...省略...

# Fatal JavaScript out of memory: MemoryChunk allocation failed during deserialization.
✘ [ERROR] MiniflareCoreError [ERR_RUNTIME_FAILURE]: The Workers runtime failed to start. There is likely additional logging output above.

Cloudflare D1は記事を投稿した2023-11-14時点でOpen Betaです。将来的に制限が緩和されて10000個のD1がバインドできるようになるかもしれませんし、ならないかもしれません。

5000個までバインドできる?

Cloudflare D1の公式ドキュメントによると、1つのWorkerにバインドできるD1の上限は約5000個だそうです。

Maximum bindings per Workers script: Approximately 5,000 [1]

  1. A single Worker script can have up to 1 MB of script metadata. A binding is defined as a binding to a resource, such as a D1 database, KV namespace, environmental variable or secret. Each resource binding is approximately 150-bytes, however environmental variables and secrets are controlled by the size of the value you provide. Excluding environmental variables, you can bind up to ~5,000 D1 databases to a single Worker script.

(引用元)Limits Cloudflare D1 docs

試してみましょう。バインディングはD1のみ指定してデプロイしてみます。

$ wrangler deploy

...省略...

✘ [ERROR] Received a malformed response from the API
  -> 504 Gateway Time-out

失敗しました!もちろんローカル環境のサーバーも起動できません!

記事の投稿にあたり実験のため大量のD1を作成したり削除したりといった捜査を繰り返していたので、不審なアカウントと判定されて制限が厳しくなっているのかもしれません。

1000個までバインドできる?

それでは数を減らして1000個のD1をバインドしてみましょう。

$ wrangler deploy

...省略...

Current Deployment ID: 4bd8ffd4-147b-4ba1-a21c-01f48df4bed3

デプロイが成功しました!ローカル環境のサーバーも問題なく起動できます。

$ wrangler dev

...省略...

⎔ Starting local server...

私のアカウントの場合、D1のバインディングは1000個までならば確実にデプロイが成功します。Cloudflareの公式ドキュメントに書かれている内容が常に正しいとも限りませんし、D1を大量にバインドする場合は各自で動作検証をした方がよさそうです。

(おまけ)大量のD1データベースを一括で作成する

wrangler d1コマンドに一括でD1データベースを作成する機能はありません。そこで、記事の投稿にあたり簡易的なd1 bulkcreateコマンドを実装しました。

最新のGoツールチェインをインストールした後、以下のコマンドを実行するとd1をインストールできます。

go install github.com/moutend/d1/cmd/d1@latest

まずは作成したいD1の一覧を格納したJSONファイルを用意します。nameにはデータベースの名前、locationにはデプロイされる地域名を指定します。

[
  {
    "name": "apple_db",
    "location": "apac"
  },
  {
    "name": "banana_db",
    "location": "enam"
  },
  {
    "name": "cherry_db",
    "location": "wnam"
  }
]

以下のコマンドを実行すると、JSONファイルで指定したデータベースが作成されます。

d1 bulkcreate databases.json

アクティブなD1データベースの一覧は以下のコマンドで確認できます。

d1 list

参考資料

  1. Limits Cloudflare D1 docs

Discussion