SQL Lite in Durable Object をやってみる + D1 との違い
今日は9月に発表された SQL Lite をベースとしたデータベースサービスである SQL Lite in Durable Object を触っていきます。
その前に Durable Object について整理
Durable Object とはCloudflareが提供するサービスです。データ永続性を持つシングルトンWorkersが実態であり、Workersの特殊モードと言えます。
Workersとの主な違いは以下の通りです。
・データは永続化されメモリとストレージで分散して保存 Workersはメモリに128MB制限がありますが、Durable Object は取り扱える情報に制限がありません。メモリと連携してストレージが存在しており分散してデータを保存するため、データ読み込み等のレイテンシが発生する可能性があります
・Workersからのみ起動 Workersコードからclass
として呼びだす形態をとります。一つのコードでWorkersと、Workersから起動される(classとして宣言される)DurableObject両方を呼び出す形態をとります。
(サンプル)https://github.com/cloudflare/durable-objects-template
・分散ではなく中央モデル Workersはリクエスタから一番近いエッジにリクエストがルーティングされます。このためユーザーによって動作する場所(CloudflareのEdge)が異なります。一方DurableObjectは最初に作成されたエッジにとどまります。
この場合、リクエストを処理するWorkersとDurable Objectの場所が離れた場所になるケースがあるため、Smart Placement
というオプションでDurable Objectの近くでWorkersを起動させるオプションが存在しています。
またWorkersからDurable Objectへの呼び出しはJavaScript NativeなRPC通信が行われています。
D1 について整理
D1 はCloudflareが提供しているエッジで動作するリレーショナルデータベースです。実はこの機能は上記のDurable Object 上で実装されています。このためエッジからアクセス可能でありながら、シングルWriterのリレーショナルデータベースが実現されています。
key-value storage backend と SQLite storage backend
通常 Durable Object が利用するストレージバックエンドはKey-Value型です。一方D1の裏でDurable Objectが利用しているストレージバックエンドはSQLite型として定義されています。
D1 と SQL Lite in Durable Object の違い
ということで、D1の実態はSQL Lite in Durable Objectです。それに対してDatabaseのマネージドサービスとして必要な、バックアップ、インポート、SQL分析、Workersを介さないDBへの直接アクセス等の機能が加わったものがD1です。
今回SQL Lite in Durable Object としてリリースされたものは、より低レイヤのSQL Liteにアクセスできるようになったものです。現時点では10GBまでデータを維持可能なD1と異なり1GB制限が存在している関係上より高速にSQL処理が可能です。
さっそくやってみる
前置きが長くなりましたが、以下のチュートリアルをやっていきます。
以下のパラメータでprojectを初期化します。For What would you like to start with?, choose Hello World example.
For Which template would you like to use?, choose Hello World Worker Using Durable Objects.
For Which language do you want to use?, choose TypeScript.
For Do you want to use git for version control?, choose Yes.
For Do you want to deploy your application?, choose No (we will be making some changes before deploying).
その後スクリプトおよび設定ファイルを以下の内容に置換します。
(公式ドキュメントママだと動作しないので少しだけ手直ししています)
import { DurableObject } from "cloudflare:workers";
export class MyDurableObject extends DurableObject {
constructor(ctx,env) {
super(ctx,env); // Correctly call the parent constructor with context `ctx`
}
async sayHello() {
let result = this.ctx.storage.sql
.exec("SELECT 'Hello, World!' as greeting")
.one();
return result.greeting;
}
}
export default {
async fetch(request, env) {
// Extract the ID from the request URL
let id = env.MY_DURABLE_OBJECT.idFromName(new URL(request.url).pathname);
// Get the Durable Object instance (stub) from the DurableObjectNamespace
let stub = env.MY_DURABLE_OBJECT.get(id);
// Call the method on the Durable Object
let greeting = await stub.sayHello();
return new Response(greeting);
},
};
#:schema node_modules/wrangler/config-schema.json
name = "durable-object-starter"
main = "src/index.js"
compatibility_date = "2024-12-05"
[observability]
enabled = true
[[durable_objects.bindings]]
name = "MY_DURABLE_OBJECT"
class_name = "MyDurableObject"
[[migrations]]
tag = "v1"
new_sqlite_classes = ["MyDurableObject"]
wrangler deploy
を実行してアクセスすればWorkersのデプロイが完了します。Workers初回呼び出し時に自動でDurable Objectが生成されます。実際の呼び出しは以下です。
import { DurableObject } from "cloudflare:workers";
export class MyDurableObject extends DurableObject {
constructor(ctx,env) {
super(ctx,env); // Correctly call the parent constructor with context `ctx`
}
マネージメントコンソールからも以下の通り確認できます。
重要な部分は設定ファイルの以下の部分です。
new_sqlite_classes = ["MyDurableObject"]
従来のDurable Object はストレージの指定をnew_classes
として起動しますが、SQL Backendの場合new_sqlite_classes
として指定します。コンソール上でもストレージバックエンドがSQL Backendになっています。
・
Discussion