*iroi*

mechairoi の Blog

Cloudflare SQLite in Durable Objects の可能性

Cloudflareのバースデーウィークで発表されたSQLite in Durable Objectsが面白そうだったので少し調べてみました。D1の裏で使われていた機能が一般のユーザーでも使えるようになったようです。

blog.cloudflare.com

概要

Zero-latency SQLite storage in every Durable ObjectBuild a seat booking app with SQLite in Durable Objects | Cloudflare Durable Objects docs を読むとより詳細な情報が得られますが、大まかには以下のようになります

  • DurableObject クラスを継承したクラスを定義して登録すると、そのクラスの中のコードはローカルマシンにストレージを持った別のV8 isolateで動く。
  • メソッドを呼び出すと、裏でそのDurable Object(DO)にRPC*1
  • ストレージはリージョン内の複数のデータセンターで冗長化されている。
  • ストレージのインタフェースがKVストアだったのがSQLiteになりました。

良さそうなところ

SQLite と同じスレッドでユーザーコードが動く

Zero-latency SQLite storage in every Durable Objectにも書かれていますね。 N+1だけでなく、ツリーのような再帰的な構造を扱ったり、GraphQLのAPIを作るにも使えるかもしれません。 バックアップや冗長化などがマネージドなSQLiteで、ユーザーコードが同じマシンで動かせるのは大きな魅力です。

トランザクションが使える

D1ではトランザクションが使えませんでしたが、Cloudflareの開発者によるとDOsでは this.ctx.storage.transactionSyncトランザクションを使えるようです*2(BEGINは利用不可)。 試した限りではINSERT OR ROLLBACKのような文は使えなくて、 INSERT (OR ABORT) を使ってunique 制約に違反するなど、JavaScript 側の例外でロールバックできるようです。トランザクション内でawaitもできませんが、十分に実用できそうです。

以前はストアドプロシージャーを使ってトランザクションを実現するといった話もありましたが*3SQLite in DOsの方が柔軟でよさそうですね。

多数のデータベースを扱える

D1は1つのbindingが1つのデータベースで、1つのWorkersには5000個くらいしかbindingできませんでした*4DOsは1つのbindingが1つのネームスペースで、ネームスペースの中にはいくつでもDO(=データベース)を作れます。 それぞれのDOが別のV8 isolateになるので、適切にパーティショニングできれば書き込みもスケールしそうです。

活かせそうな応用例としては

  • モバイルアプリ用のユーザーデータを保存する。シングルプレイ寄りのゲームとか、ユーザーごとの閲覧履歴をサーバーと同期するとか。
  • SNSのようなタイムラインをユーザーごとにDOを用意して、GAしたWorkers Queuesでfan outするのも面白そうです。

地理的にユーザーの近くにDOが作られそうなのもいいですね。

また読み込み性能のスケールのために read replica? のような機能の開発も進行中のようです*5

1行のサイズ制限がD1の2倍

ドキュメントのミスでなければD1は1MBですがDOsは2MB *6*7

おわり

機会があれば使ってみたいですね。Drizzle ORMは割と早く対応してくれそうな気がしてます。