DuckDBが、ついに「別のDuckDBと会話できる」ようになりました。
その名も Quack。DuckDBらしい、ちょっとユーモラスで覚えやすい名前です。
今回の発表は、単なる新機能追加ではありません。
DuckDBを“1つのアプリの中で使うDB”から、“複数のプロセスや端末から共有して使えるDB”へ広げる試みだと言えます。しかも、ただの後付けではなく、HTTPベースでシンプルに設計されているのが面白いところです。
quack:localhost のように接続して、別のDuckDBのテーブルを参照・書き込みできるまず背景からです。
昔のデータベースは、ざっくり言うと「1台のマシンの中で全部やる」世界でした。
その後、1980年代ごろから client-server architecture が広まりました。これは、データベース本体がserver、そこに接続するアプリがclient という分業です。
この方式のいいところは、複数のclientが同じDBにアクセスしやすいこと。
一方で、通信のオーバーヘッドが増えます。つまり、便利だけど少し重くなりがち、ということですね。
DuckDBはもともと、SQLiteと同じく in-process を強く意識したDBです。
これは「DBを別サーバーとして動かす」のではなく、アプリと同じプロセスの中で動かす 形です。Pythonのノートブックや分析アプリの中にスッと入れて使えるので、データ分析ではかなり気持ちいい。ここがDuckDBの強みでした。
ただし、弱点もあります。
それは、複数のプロセスが同じDBファイルを同時にガンガン更新する用途には向きにくい ことです。
たとえば、
みたいな場面です。
こういうとき、DuckDBはメモリ上に持っている状態を同期しないといけないので、簡単にはいきません。
もちろん、回避策はありました。
記事でも触れられているように、RPCを自前で作ったり、Arrow Flight SQLを使ったり、MotherDuckのような独自protocolを使ったり、あるいはPostgreSQLに寄せたり、という道はありました。
でも、そういう「周辺技術でなんとかする」状況がたくさん生まれていた、という事実自体が、DuckDBにもclient-serverの需要がかなりあったことを示しているわけです。
個人的には、ここがかなり重要だと思います。
DuckDBは「in-processであること」がアイデンティティのひとつでしたが、世の中の使い方はそれだけでは収まらなかった。
今回のQuackは、その現実にちゃんと応えにいった感じがあります。
Quackは、DuckDBインスタンス同士が会話するためのprotocol です。
名前の通り、duckが会話するときは quack する、というノリですね。こういう遊び心、DuckDBらしくて好きです。
使い方はシンプルです。
DuckDBがserverにもclientにもなる のがポイントです。
記事の例では、片方のDuckDBで quack_serve() を呼んでserverを立て、もう片方から ATTACH 'quack:localhost' で接続しています。
すると、remote側のテーブルをそのまま参照できます。
remote.hello のように、server側のテーブルを見られるさらに、query 関数を使うと、クエリそのものをremote側で実行できます。
これが意外と大事で、単にテーブルを遠隔参照するだけでなく、重い処理をどちらでやるかをコントロールしやすいんです。
これは実運用ではかなり効くと思います。
大きなデータをいったんローカルに引っ張ってきて処理するより、必要な処理を向こうでやらせて結果だけ返すほうが、当然速くて省メモリになりやすいからです。
Quackは HTTP の上に作られています。
これはかなり賢い選択だと思います。
HTTPは、
という強みがあります。
新しいDB protocolを一から作ると、だいたい「通信は速いけど周辺ツールが弱い」か「周辺は便利だけど設計がやや重い」みたいなことになりがちです。
その点、HTTPを土台にするのはかなり現実的です。DuckDBらしい「賢い割り切り」だと感じます。
さらに、DuckDB-Wasm、つまりブラウザ版DuckDBとも相性がいいのが面白いです。
ブラウザのDuckDBが、EC2上のDuckDBと直接話せる。
これは地味に未来感があります。ローカル、ブラウザ、サーバーが同じ言葉でつながる感じです。
Quackは request-response pattern です。
つまり、clientが「これやって」とrequestを送り、serverがresponseを返します。
たとえば、
といった流れです。
ここで大事なのは、巨大な結果を一気に返すのではなく、必要に応じてfetchしながら取る設計になっていること。
これなら、大きい結果でも扱いやすいですし、複数スレッドで並行に取得することもできるようです。
Quackの通信データは application/duckdb というMIME typeで表現されます。
MIME typeというのは、簡単に言うと「このデータは何の形式ですか?」を示すラベルです。
中身の表現には、DuckDB内部の efficient serialization primitives が使われています。
serializationは「メモリ上のデータを通信や保存のために並べ替えて書き出すこと」です。
記事によると、この仕組みはすでにWAL(Write-Ahead Log)で長年使われてきたものだそうです。
つまり、新規の危なっかしい仕組みではなく、実績ある部品を流用しているわけです。
こういう設計は、私はかなり信頼できます。新機能ほど、こういう再利用が大事ですから。
Quackは便利そうですが、DBをそのままインターネットに出すのは当然危険です。
記事でもかなり慎重です。
デフォルトでは、
ようになっています。
さらに、SSLはデフォルトでは使わない とあります。
これは「localhost通信にわざわざ重いSSL基盤を載せるのは大げさ」という考え方です。これは理にかなっています。
ただし、外部公開は推奨されていません。
もし公開したいなら、nginxのような一般的なHTTP endpointの前に置いて、そこでSSLを終端するのがよい、という方針です。
このあたりは、かなり実務的です。
「便利だから全部開けて使ってね」ではなく、「基本は閉じて、安全に使ってね」というメッセージがはっきりしています。
Quackの価値は、単に「DuckDBがネットワーク越しに使える」ことだけではないと思います。
本質は、DuckDBの使える場面が一気に広がることです。
これまでは、DuckDBは主に
で強かったわけですが、Quackが入ると、
みたいな用途にも広がります。
つまり、DuckDBが「単体で気持ちよく動く分析エンジン」から、
“ちょっとしたDBサービス”としても使える存在に近づいた、という印象です。
ここは冷静に見たいところです。
Quackが出たからといって、DuckDBがいきなり巨大な本格RDBMSの領域を全部置き換える、という話ではありません。たぶん、そういう方向ではないです。
DuckDBの魅力はあくまで、
ところにあります。
Quackはその延長線上で、必要だったけどなかった接続方式を足した、という理解がしっくりきます。
なので、私はこれを「DuckDBの思想を壊す拡張」ではなく、
DuckDBの適用範囲を自然に広げるアップデートだと思います。
Quackは、DuckDBにとってかなり大きな一歩です。
しかも、それをやたら複雑にせず、HTTPベースで、既存の技術を活かしながら実現しようとしているのがDuckDBらしい。
個人的には、こういう機能追加はかなり好きです。
派手な新機能というより、「本当に欲しかった境界の穴を埋める」タイプの進化だからです。
そして、DuckDBが「ローカルで速いDB」から「分散環境でも扱いやすいDB」へ少しずつ伸びていく、その途中の重要な節目に見えます。
今後、Quackがどこまで育つのか。
分析用途だけでなく、軽量なデータサービスやブラウザ連携の世界でどんな使われ方をするのか。
ここはかなり楽しみです。