Open6

DuckDB/DuckDB-Wasm と Postgres と S3 を組み合わせるメモ

ピン留めされたアイテム
voluntasvoluntas

モチベーション

  • Postgres は OLTP として利用したい
  • DuckDB は OLAP として利用したい
    • 集計を Postgres でやらず、独立した DuckDB でやりたい
  • データ保存は S3 を利用したい
    • 保存先として一番安い
    • 一定期間経ったら削除が簡単にできる
  • 細かいデータ処理は DuckDB-Wasm を利用してクライアント側のリソースを利用したい
  • 一度前処理したデータは S3 に Parquet 形式で置いておきたい
    • 転送量ボトルネックに寄せる
      • Cloudflare R2 などを利用すれば転送量はかからなくなる
voluntasvoluntas

概要

ここまでを全て DuckDB 単体で実現できる。

go-duckdb と組み合わせる

marcboeker/go-duckdb: go-duckdb provides a database/sql driver for the DuckDB database engine.

Go の DuckDB と組み合わせることで、Go で HTTP リクエストを受け取り、DuckDB で処理をして Parquet 用の Presigned URL を返すという処理が実装できる。

Go から S3 API を触るときは minio/minio-go: MinIO Go client SDK for S3 compatible object storage がとてもオススメ。

voluntasvoluntas

シーケンス図

  • わかりやすくするため、かなり省略している
  • 本来はテーブル直接ではなく、フィルターしてから Parquet 化するべき
voluntasvoluntas

DuckDB-Wasm との組み合わせ

  • Postgres から取得したデータを DuckDB で整理して、Parquet 化し、S3 へアップロードする
  • S3 へアップロードした Parquet ファイルを Presiguned URL にしてブラウザへ取得させる
  • ブラウザは取得した Parquet ファイルを DuckDB-Wasm に regiserFileBuffer で登録する
  • DuckDB-Wasm でやりたい放題
voluntasvoluntas

OPFS との組み合わせ

  • voluntas/duckdb-wasm-parquet
    • fetch で取得した parquet ファイルを reigisterFileBuffer する前に、OPFS に保存してしまうのもあり
  • fetch から OPFS は Stream を使って書き込むのがオススメ
voluntasvoluntas

注意

  • HTTP リクエスト毎に DuckDB が上がるので、Postgres 側は PgBouncer とかでコネクションプールがある前提