分散SQLite: パラダイムシフトか、それとも誇大宣伝か?
(kerkour.com)- SQLiteは非常に高速。一般的なシングルサーバー(約40€/月)で、同時に約168,000件の読み取りと約8,000件の書き込みを持続できる
- 組み込みシステム、スマートフォン、デスクトップアプリケーションなどのクライアントサイドアプリケーション向けに設計された組み込みライブラリであるため、SQLiteデータベースはアプリケーションサーバーと同じ場所に置く必要があり、ネットワーク経由でアクセスすることはできない
- では、複数台のマシンが必要な状況でSQLiteをどう活用するのか?
- 週末プロジェクトが爆発的な人気を得て、急速なスケールが必要になるかもしれない
- CTOの要件の1つが、少なくとも2つの異なるデータセンターに高可用性サービスを展開することかもしれない
- ここ数年、SQLiteをバックエンドアプリケーション向けのバックエンドデータベースへと作り替えようとするプロジェクトがいくつか登場している
- これは組織がより良いユーザー体験をより速く提供できるようにするパラダイムシフトなのか、それとも「独自の売り(Unique Selling Proposition)」を膨らませようとする企業が押し出しているマーケティング上の誇大宣伝なのかを見極めるための記事
SQLiteをエッジデータベースとして活用
- SQLiteは単なるバックエンドデータベースではなく、エッジデータベースとして宣伝されている
- 代表的なプレイヤーとしては、Cloudflare D1、LiteFSを使うfly.io、Tursoなどがある
- ほとんどのSQLite派生製品は似たような方式で動作する
- どこかに書き込みを受け付けるプライマリデータベースがあり、それが他のリージョンへ非同期に複製される
- 複製は主に、データベースで実行されたすべてのトランザクションのログ、つまりSQLiteのWrite-Ahead Logをストリーミングする形で行われる
- このアーキテクチャでは理論上、読み取りはエッジのデータセンターで処理できるが、書き込みは依然として中央の場所へ転送しなければならない
- 実際には、ECアプリケーションで顧客が注文を完了し、プライマリSQLiteデータベースでは注文が承認されているのに、ローカルの読み取りレプリカが遅れていて更新済みデータをまだ受け取っておらず、「見つかりません」というエラーメッセージを表示したい人はいないだろう
- 「つらい結果整合性の世界」へようこそ
LiteFSの解決策と限界
- LiteFSはハック的な解決策を提案している。アプリケーションがローカルレプリカの最新トランザクションを追跡するために
__txidクッキーを設定し、古すぎる場合は読み取りクエリをプライマリデータベースへ転送する - これでアプリケーションはデータベースやリバースプロキシと密接に結び付くことになる
- LiteFSが1秒あたり約100件の書き込みしかサポートしないことには触れていない
ほとんどの分散SQLiteシステムの主な欠点
- ほとんどの分散SQLiteシステムは、トランザクション内の異なるクエリの間で何らかの計算を行う対話的トランザクションをサポートしていない
- 同時にアクティブにできる書き込みトランザクションは1つだけ。通常のSQLiteデータベースではほとんどの書き込みは数十マイクロ秒以上続かないため、一般には問題にならない
- しかし、アプリケーションとSQLiteデータベースの間にネットワーク遅延が入ると、システムは破綻する。データベースはトランザクションの往復時間のあいだロックされ、1秒あたり数件の書き込みに制限されるだろう
- Tursoはこれをバッチ処理で「解決」している。複数のクエリをバッチとして束ね、単一トランザクションとして実行できる。Cloudflare D1はバッチ処理とストアドプロシージャでこの問題を「解決」している
もっとシンプルな解決策があるとしたら?
- Webアプリケーションを世界中で非常に高速にする、とてもシンプルで強力な方法はすでにある。それが
Cache-ControlとETagヘッダーを使ったHTTPキャッシュだ - HTTPキャッシュを使えば、弱い整合性のデータベースに似た技術を使う必要がなくなり、Webアプリケーションが過度に複雑になったり競合状態に弱くなったりするのを防げる
- この記事の著者は新刊『Cloudflare for Speed and Security』で、Webアプリケーションを高速化するだけでなく、最小限のリソースで多数の同時ユーザーを処理できるさまざまなキャッシュ戦略について多くのページを割いて説明している
抽象化としてのデータベース
- レイテンシは、分散SQLiteが解決しようとしていた唯一の課題ではない。もう1つは運用の複雑さだ
- ネットワーク接続されたサーバークラスタの管理は難しく、しばしばダウンタイムや収益損失につながる。2017年にGitLabが経験したような惨事を避けるには、継続的な管理と優れたセキュリティ文化が必要なデータベース管理はなおさらだ
- そこで生まれたアイデアが、データベースをアプリケーションとバンドルし、すべてを単一サーバーに配置することだ
- 開発者が1人しかいないときには良いが、大規模な組織ではデータベースサーバーの保守を専任で担う人やチームがいるだろう
- だからこそ、組み込みライブラリではなくソケット経由でアクセスするデータベースは優れた抽象化なのだ。しかもそれは技術的な抽象化というより、組織的な抽象化である。開発中は開発者のマシン上で動く単純なコンテナかもしれないし、本番ではアプリケーションと同じサーバー上で動くコンテナから、ネットワーク越しにアクセスする分散クラスタまで何でもあり得る。開発者は単一の設定変数
DATABASE_URLを差し替えるだけでよく、残りは運用チームがすべて処理する - 逆に、従来のUnixファイルシステムは分散コンピューティングに向いた抽象化ではなかった。もちろんNFS(Network File System)は存在するが、Unixファイルシステムが単一マシンからのアクセス向けに設計されているため、性能はかなり良くない。一方、S3プロトコルは大量の非構造化データを効率的かつスケーラブルで信頼性高く保存するための、かなり優れた抽象化だ。開発者はS3互換SDKを使ってしまえばよく、性能・耐久性・信頼性などは運用チームやクラウドプロバイダーが面倒を見る
結論
- SQLiteは本当に素晴らしいデータベースだが、ほとんどのチームはSQLiteを避け、代わりにPostgreSQLを選ぶべきだ
- PostgreSQLを最高のバックエンドデータベースにするために、膨大なエンジニアリング時間が費やされてきた。SQLiteを選べば、PostgreSQLが長年備えてきたものを脆くバグの多い形で再発明せざるを得なくなる
- 現在の「SQLiteをバックエンドデータベースにしよう」という流れは、コンピューティングはデータストアなしでは成り立たないと気付いたエッジコンピューティング基盤の販売企業によるマーケティング上のクーデターにすぎない、という見方だ。彼らへの(求められてもいない)助言は、CDNを構築してアプリケーションに複雑さを押し付ける代わりに、HTTPキャッシュへ投資することだ。その方がはるかに良い結果をもたらす
- 引き起こされる複雑さのため、バックエンドアプリケーションの99.9%はエッジへ移行しても何の利点も得られず、代わりに世界中で100ms未満の優れた体験を提供するための良いキャッシュ戦略の展開に注力すべきだ
- そして、ここがサーバーサイドアプリケーション向けSQLite実験の終着点だ。PostgreSQLの勝利である
-
「アマチュアは戦術を語り、プロは兵站を語る。(Amateurs discuss tactics. Professionals discuss logistics.)」
成功には、現場での戦術的判断よりも、その判断を可能にする裏側のシステムとプロセス、つまり兵站と管理の方が重要だということ
GN⁺の見解
- 著者の主張どおり、ほとんどのバックエンドアプリケーションでSQLiteを使うのは、複雑さを増すだけで実質的な利点はないように見える。すでに実証され成熟したPostgreSQLのようなデータベースを使う方が良い選択だろう
- エッジコンピューティング基盤の事業者がSQLiteを強く押し出しているのは、技術的優位性というよりマーケティング戦略の一環に見える。HTTPキャッシュとCDNにもっと投資する方が、アプリケーション開発者の助けになるだろう
- ほとんどのバックエンドアプリケーションは、適切なキャッシュ戦略だけでも十分に高速でスケーラブルなサービスを提供できる。エッジコンピューティングが本当に必要な場合でなければ、過度な複雑さは避けた方がよい
- 分散SQLiteは特定のユースケースでは有用かもしれないが、汎用ソリューションとして使うにはまだ限界がありそうだ。開発のしやすさ、性能、一貫性などをすべて満たすのは簡単ではないだろう
- 結局のところ最も重要なのは、アプリケーションの要件とチームの力量に合った技術を選ぶことだ。流行に流されるのではなく、長所と短所を徹底的に分析し、慎重に意思決定すべきだ
- 著者はSQLiteがバックエンドデータベースとして使われるにはまだ不足が多いことを強調しているが、SQLiteの長所を生かせる別のユースケースもあり得るため、完全に排除する必要はないように思える。
3件のコメント
Postgres と sqlite のどちらが最善かというより、
どちらが自分の状況により合っているかを考えてみるほうがいいのではないでしょうか。
状況によって最善は変わるはずですから
Hacker Newsの意見