これはDuckDB 座談会 (2025-01) の発表者向けの資料です。
- 著者: @voluntas
こちらの資料がとてもお勧めです。
DuckDB雑紹介(1.1対応版)@DuckDB座談会 - Speaker Deck
- Release Calendar – DuckDB
- DuckDB 1.2 は 2025-01-27
- DuckDB Node Neo Client – DuckDB
S3 という呼び方は S3 互換オブジェクトストレージも含んだ総称として利用しています。
- DuckDB と S3
- DuckDB と Go
- DuckDB-Wasm と S3
- DuckDB-Wasm と OPFS
- DuckDB と PostgreSQL
- DuckDB と Parquet
- Parquet 2.x
- DuckDB と Parquet Encryption
- DuckDB-Wasm とブラウザエディター
- duckdb_lsp
- DuckDB を利用した完全性の確認
結局 S3 が便利。
DuckDB/DuckDB-Wasm を導入するにあたり、結局 S3 (または S3 互換オブジェクトストレージ、以降は S3) をベースに組み立てることが良いという判断をしました。
ログ検索サーバーとして Meilisearch を導入したりしていましたが、シングルノードの場合は障害に備えて、検索情報の復旧などを作り込んでいく必要があります。だからといってクラスターを組む場合はコストがかかります。マネージドサービスも同様です。
ただ、ログの保存先を S3 に保存してしまえば、何考えなくて良い。障害については基本考えなくて良いですし、容量の問題でディスク増やすか ... とかも考えなくて良くなります。
バックエンドで利用す場合は、全て Go から利用しています。
https://github.com/marcboeker/go-duckdb
公式ではなくサードパーティですが、 DuckDB 開発者がかなりコミットしています。
Go は DuckDB のプロセス利用と相性が良いです。残念ながら CGO になってしまうため、ビルド自体は面倒くさいのですが、利用する分には問題ないです。
HTTP リクエスト経由での DuckDB を実行したい時、Go であれば Goroutine で処理を行うことができるため、同時実行に脳みそを使わなくて良くなります。
自社では HTTP リクエストを Go のサーバで受けて、DuckDB を起動し、S3 にあるログから必要な情報をとり、フィルタリングを行い、その後 Parquet ファイルに変換、そして S3 に minio-go を利用してアップロード、さらに Presigned URL を生成してクライアントに提供という仕組みを採用しています。
そもそも解析したいときに要求される仕組みにしているため、常時解析情報をため込んでおく必要がありません。
非同期解析結果要求はかなりコストメリットが高いので、大変お勧めです。
S3 の Presigned URL を利用する事で、ブラウザに安心して S3 の Parquet ファイルをダウンロードできます。
DuckDB-Wasm で s3:// を使うよりは、普通に fetch で取得してきて、DuckDB-Wasm に読み込ませる方が良いです。コントローラブルでエラーハンドリングがやりやすいです。
一度永続化したい場合は OPFS に Stream 保存するのが良いと思いますが、 DuckDB OPFS が利用できる今は、そこまでの必要性はないかもしれません。
先日 (2025 年 1 月) に DuckDB-Wasm のデータベース保存先を OPFS (Origin Private File System) にできる、Pull-Request がマージされました。
Add OPFS (Origin Private File System) Support by e1arikawa · Pull Request #1856 · duckdb/duckdb-wasm
この機能は革命的な機能で、今までは DuckDB-Wasm に書き込みを行ってもブラウザを更新したタイミングで消えてしまうため、Parquet ファイルなどを OPFS に書き込んでおき、それを再度 DuckDB に読み込ませるなどの処理が必要でした。
しかし、この OPFS の仕組みを利用することで、 DuckDB-Wasm に書き込んだデータをブラウザを更新や終了してもデータが消えることがなくなります。
OPFS に Parquet ファイルを置いていたのも不要になり、管理もとても楽になります。
npm の duckdb-wasm で next で既に利用できます。
DuckDB は直接 PostgreSQL からの読み込み/書き込みができる機能が備わっています。 この機能を利用することで、集計処理を全て DuckDB 側で行う事ができるようになります。
PostgreSQL のクラスターを普段利用しているのですが、リードレプリカに対して、 DucKDB から PostgreSQL へアクセスをするというのがとても相性が良いことに気付きました。
バッチ処理系は DuckDB で集計してしまう方向で進めています。
恥ずかしながら DuckDB を触るまでは Apache Parquet の存在を知りませんでした。使ってみると恐ろしく便利な事がわかってきました。
ファイルがまずデフォルトで圧縮されていること、そして read_parquet でさくっと読み込める。さらには出力も簡単にできる。言うこと無しです。
DucKDB と DuckDB-Wasm のやりとりも Parquet ファイルを利用しています。また S3 にある JSONL 形式のログファイルを解析したりフィルターした後も Parquet ファイルにして、S3 に置いています。
Parquet ファイル様々です、あまりにも便利なので DuckDB 以外のところでも利用できないか?という気持ちになってきています。
DuckDB は Parquet を扱うツールとしてだけみても、かなり便利だと感じています。
個々まで便利だとローカルで出力した JSONL のログを Parquet にしてから S3 にアップロードするというのもありでは?とおもっています。別に json.gz で保存するのではなく parquet すれば Zstd で圧縮されますし良いことずくめです。
Parquet にバージョンがある事を最近まで知りませんでした。1 系と 2 系があるんですね。
DuckDB 1.2 では COPY TO で Parquet ファイルを出力するさいに、 Parquet のバージョンが指定できるようになるようです。
Query Engines: Gatekeepers of the Parquet File Format – DuckDB
-- Generate TPC-H scale factor 1
INSTALL tpch;
LOAD tpch;
CALL dbgen(sf = 1);
-- Export to Parquet using Snappy compression
COPY lineitem TO 'snappy_v1.parquet'
(COMPRESSION snappy, PARQUET_VERSION V1); -- 244 MB, ~0.46s
COPY lineitem TO 'snappy_v2.parquet'
(COMPRESSION snappy, PARQUET_VERSION V2); -- 170 MB, ~0.39s
-- Export to Parquet using zstd compression
COPY lineitem TO 'zstd_v1.parquet'
(COMPRESSION zstd, PARQUET_VERSION V1); -- 152 MB, ~0.58s
COPY lineitem TO 'zstd_v2.parquet'
(COMPRESSION zstd, PARQUET_VERSION V2); -- 135 MB, ~0.44s
zstd と parquet v2 恐ろしいほど圧縮されていてビックリです。
Parquet ファイルがあまりにも便利すぎるので、クライアントにファイルを渡す際、何か署名的なモノができないか?とおもってて調べたりしていました。
ファイルに署名ができたら、ファイルが改ざんされていないか?ということが確認できるようになります。 さらには利用社側も「誰が生成したファイルなのか」というのがわかってとても良いなと。
ただ、残念ながら署名機能は無く、 DuckDB でも Parquet ファイル自体を暗号化するくらいしかないようです。 暗号化すると、性能は 2.5 倍程度落ちるようです。
CodeMirror と組み合わせて使っています。
DuckDB-Wasm + Parquet + S3-compatible object storage + OPFS
現在DuckDB 向けの LSP を Rust で開発中です。
DuckDB をブラウザ (DuckDB-Wasm) や VS Code で利用する際、 DuckDB LSP を利用する事で、コード補完、エラー表示、ホバー表示、シンタックスハイライトなどの機能を利用することができるようにする予定です。
現在は VS Code でエラー表示までは実現できています。
現在はクローズドコードですが将来的には Apache-2.0 ライセンスで公開を検討しています。
- supabase-community/postgres_lsp: A Language Server for Postgres
- WhatsApp/erlang-language-platform: Erlang Language Platform. LSP server and CLI.
DuckDB で で S3 や PostgreSQL にあるデータの完全性を確認するというブログを読んでこれはかなりいいのでは?と感じました。
DuckDB を使ったデータ品質保証の実践 - Timee Product Team Blog
分散システムを運用していると、ログが分散します。これらのログが「期待通りに出力されているか」というのを DuckDB を定期的に確認する仕組みを作れるのではないか?と感じました。
ツール自体は Python で書いて Systemd Timer 辺りで定期実行して問題が起きたら Slack やらなんやらに通知するだけで十分でしょう。