- データレイクとカタログフォーマットを統合した新しいソリューション
- ParquetファイルとSQLデータベースを基盤として動作し、従来のレイクハウスより簡潔なデータレイク実装を可能にする
- PostgreSQL, SQLite, MySQL, DuckDB など複数のデータベース上でメタデータカタログ管理が可能
- スナップショット、タイムトラベルクエリ、スキーマ変更、パーティショニング など多様な機能をサポートしつつ、頻繁にコンパクト化しなくてもよい軽量なスナップショット処理を提供
- 複数のインスタンスが同時にデータを読み書きするマルチプレイヤー DuckDB モデルをサポートし、標準のDuckDBではサポートされない同時実行性処理モデルを実装
- DuckLakeは仕様、DuckDB拡張、DuckLake形式で保存されたデータセットを包含する概念であり、MITライセンスで公開されている
DuckLake 紹介
- DuckLakeはDuckDBチームが作成したオープンフォーマットで、複雑なレイクハウスなしでも高度なデータレイク機能を提供する
- SQLデータベースとParquetファイルだけで独自のデータウェアハウスを構築できる。
- メタデータ管理のためにデータベースを使用: PostgreSQL, SQLite, MySQL, DuckDB
DuckLakeの主な機能
-
データレイクオペレーション
- スナップショット
- 時点参照 (Time travel)
- スキーマ進化
- パーティショニング
-
軽量なスナップショット処理
- スナップショット数に制限なく作成可能
- 頻繁にコンパクト化する必要なく動作可能
-
ACIDトランザクション
- マルチテーブル操作に対して同時アクセスとトランザクションを保証
-
パフォーマンス志向の設計
- フィルタープッシュダウンのための統計活用
- 大規模データセットでも高速なクエリが可能
よくある質問
-
なぜDuckLakeを使うべきですか?
- データレイクとカタログを統合した軽量ソリューションが必要な場合に適している
- 複数のDuckDBインスタンスが同一データセットを読み書きするマルチプレイヤー環境が可能
- これは従来のDuckDBではサポートされていない同時実行性モデル
- DuckDBだけを使っても時点参照、パーティショニング、マルチファイル保存構造などの利点を享受できる
-
DuckLakeとは何ですか?
- DuckLakeは次の3つを指す:
- DuckLakeフォーマットの仕様 (specification)
- DuckLakeをサポートするDuckDB拡張機能 (ducklake extension)
- DuckLakeフォーマットで保存されたデータセットそのもの
-
DuckLakeのライセンスは?
1件のコメント
Hacker News のコメント
Parquet で以前から少し不満に感じていた点があり、さまざまな「data lake / lakehouse」が互換性のない形で個別に解決してきた
ranged partitioning周りに物足りなさがある。私のアプリケーションは Parquet にほぼ完璧に適合しているが、時系列ログのようにタイムスタンプが均一に分布していないデータを扱っている。パーティション列は Hive partitioning に従っている一方で、同時にタイムスタンプでも自然に分割される。問題は Hive partitioning がこれをサポートしていないため、主要なクエリツールが私のデータ構造を正しくインポートできないことだ。日付ベースの列のような不要な回避策を導入するか、単にファイルを積み上げるしかなく、そうすると性能面でもコスト面でも不利になる。Iceberg や Delta Lake などは ranged partitioning に対応しているが、私はそこまでの複雑さは必要としておらず、もっとシンプルなファイル名やディレクトリ名の規則が標準化されてほしいと思っている。また、Parquet row と Arrow row、Thrift、protobuf などのフォーマットは非常に似ているものの完全に同一ではないので、単一 row あるいは row ストリーム向けのバイナリフォーマットが併存すれば、さまざまなツール間の相互運用性はもっと良くなると思うParquet ファイルの footer metadata だけで必要な情報を得るには十分ではないのだろうか。メタデータにはその列の最小/最大タイムスタンプが入っているので、クエリ時にクエリツールがそのメタデータだけ読んでファイルを読むべきかどうかを判断し、無駄な読み取りを防げるはずだ
時間データは扱いが難しいが、やり方次第では回避もできる。元の時系列を直接クエリするのではなく、イベント処理段階でタイムスタンプを正規化して保存すると有用だ。スライディングウィンドウを使ってイベントの開始点を見つけて offset を調整し、時系列が基準点 (0) に戻る位置を特定して、それをイベント単位として使える
Hive は injected と dynamic の 2 種類の partitioning をサポートしている。パーティションキーとして UNIX 時間ベースの hour 列(エポックから 3600 秒ごとに増える整数)を使える。クエリエンジンで参照するパーティション範囲を明示する必要があるかもしれないが、
datepartition >= a AND datepartition < bの形でクエリ内で利用できる。Iceberg はこれをはるかに単純化してタイムスタンプ範囲として使えるようにし、メタデータが不要なパーティションは自動で除外するarrow/parquet の低レベルライブラリでは row group や data page を直接制御できる。
arrow-rscrate を使ってファイルクエリ速度を 10 倍以上改善したことがある。row group が少ない場合もあれば非常に多い場合もあるが、必要な row group だけを高速にスキップできるので skew は問題にならない。ただし、ファイルあたりの row group 数は2^15に制限されている点には注意が必要だこの問題は Parquet の問題というより Hive の限界に近い。列の min, max 情報を見るために Parquet ファイルを開く必要はあるが、範囲外のデータならそれ以上のリクエストは発生しない。こうしたメタデータをより上位、たとえば DuckLake のような場所で活用すれば効率的だ
Iceberg(Delta Lake も似ているが、個人的には Iceberg のほうが少し難しい)で最も不便だった点の一つは、ノートブックやローカル環境で試しに使うのが難しいことだ。Delta Lake は Python 実装が複数あるものの断片化していて、Iceberg は JVM クラスターのセットアップなど手間が多い。私は sqlite/postgres + duckdb + parquet の組み合わせで blob storage に保存しようとしたが、かなり面倒だった。DuckDB 側はこうした苦労なしにすぐ動き、適度な規模のデータまでは自然にスケールする。DuckDB チームはこの分野をよく理解していて、本当に期待している
PyIceberg を使ったことはあるだろうか。純粋な Python 実装で、かなりよく動く。SQL Catalog と SQLite ベースのインメモリ catalog もサポートしている
https://py.iceberg.apache.org/
S3 と RDS を使った段階的なセットアップガイドがある。ローカルの sqlite に置き換えるのも難しくないはずだ
https://www.definite.app/blog/cloud-iceberg-duckdb-aws
ローカルでも本当に簡単に試せる。marimo notebook なら数行のコードで可能だ(参考までに、私は marimo の開発者だ)
https://www.youtube.com/watch?v=x6YtqvGcDBY
k3s と相性の良い Helm chart を作ろうか考えている。datapains を使えば trino も簡単に立ち上げられるし、少し手を入れれば hivemetastore も起動できる。Iceberg connector を trino と連携させて全体の動作を試してみた。hive にデータをロードして trino から同じテーブルを参照させ、その後
selectで iceberg にinsertする構成だ。DuckDB 側が本当に簡単に動く環境を提供できれば、業界の主導権も握れるかもしれないdelta-io(deltalake-r ベース)はローカルでも非常に簡単に動く。
pipでインストールすればすぐに catalog とファイルの作成が可能だhttps://delta-io.github.io/delta-rs/
Iceberg に対する鋭い批判をよく突いている。どうせデータベースを使うのに、なぜメタデータをファイルに入れて扱わなければならないのか疑問だ。DuckLake が DuckDB を超えて広く成功するのは簡単ではないかもしれないが、最終的には catalog がメタデータまで担う構造になり、既存の Iceberg フォーマットは次第に歴史の一場面として消えていくのかもしれないと思う
既存の Lakehouse システム(Iceberg など)は、スキーマやファイル一覧のような重要なテーブル情報を S3 のようなオブジェクトストレージ上の小さなメタデータファイルとして分散保存している。そのためクエリ計画やテーブル更新のたびにネットワークコールが多発し、遅かったり競合が起きやすかったりする。DuckLake はすべてのメタデータを高速でトランザクション性の高い SQL データベースに格納し、単一クエリで必要な情報をすべて取得できるため、効率性と信頼性が大きく向上する
DuckLake に関するマニフェスト: https://ducklake.select/manifesto/
私は社内で deltalake-rs の Python バインディングと duck db を使って「poor man’s datalake」を開発中だ。parquet ファイルを blob storage に保存する構成になっている。ただし concurrent write では常に問題が起きる。一定周期ごとにクラウド関数が API からデータを引いてくる分には問題ないが、バックフィルを何度も回すと timer 関数と同時実行になって衝突する危険が高い。特にバックフィルキューに数百件のジョブを積み、ワーカーが飽和すると顕著だ
ファイル名の末尾にランダムな suffix を付ける方法がある
write の前に json ファイルに一時的な lease を取り、write リクエストをキューで管理すれば衝突を防げる
Iceberg の限界、特にメタデータ管理の問題を解決する競合ソリューション(例: Snowflake は FoundationDB を使ってメタデータを管理し、Iceberg は blob storage まで使っている)
https://quesma.com/blog-detail/apache-iceberg-practical-limitations-2025
私も似た印象を受けたが、動画を見る限り DuckLake は直接の競合ではない
https://youtu.be/zeonmOO9jm4?t=4032
DuckLake は必要なときにだけ Iceberg 用の manifest/metadata ファイルを書いて同期し、既存の Iceberg データの読み取りもサポートしている。Iceberg の中核的な問題を改善したものであり、独立した競合製品というより、Iceberg ときれいに双方向連携できる構造だ
メタデータの肥大化は状況次第で十分に管理できる
以前は大きなスキーマのせいで最後の項目が問題になっていた。ほとんどのエンジンは compaction や snapshot export などのツールで管理を支援しているが、ユーザー側の責任でもある。S3 tables も一部の管理機能を提供している。メタデータが 1〜5MB 程度なら実際には問題にならない。commit 速度はメタデータサイズと writer 数に左右される。1GB を超えるメタデータも自前スクリプトで対処したことがある。通常は上書きされた snapshot だけを整理し(実ファイル削除は bucket policy に任せる)、あるいは古いスキーマバージョンを掃除すれば解決する
結局、データベースをきちんと作るには本物のデータベースのように構築しなければならない。DuckDB チームには感心する
Mother Duck(https://motherduck.com/) とはどんな関係なのか気になる。「DuckDB-powered data warehousing」を提供する会社で、DuckLake より前から始めている
MotherDuck と DuckLake は非常にうまく統合される予定だ。MotherDuck のデータは DuckLake に保存されることで、スケーラビリティ、同時実行性、一貫性が向上し、第三者ツールからも underlying data にアクセスできるようになる。この部分はここ数か月開発が進められており、近いうちにさらに多くの情報が公開される予定だ
MotherDuck はデータをアップロードすると自動的に整理し、DuckDB を通じたデータインターフェースを提供してくれる。さらに lakehouse 的な特徴や blob storage 連携、DuckLake との追加統合、メタデータ保存先を MotherDuck にしたいなら DuckLake を使える
MotherDuck は duckdb をクラウドでホストするサービスで、DuckLake はそれよりずっとオープンなシステムだ。DuckLake では S3 や EC2 など多様な環境上で、複数インスタンス・ペタバイト級ウェアハウス・複数 reader/writer をすべてトランザクション性ありで構築できる。MotherDuck では同時に 1 writer しか使えず、read replica は 1 分程度のレイテンシがあり、トランザクション性もない。複数インスタンスが同時に別々のテーブルへ書き込むこともできない。DuckLake はストレージとコンピュートの分離に加え、トランザクション性の高いメタデータ層も提供する
duckDB が大好きで、DuckLake も本当に素晴らしいと思う。気になるのは、もし今から使うとして、会社ですでに Snowflake を運用している場合、アナリストはそれぞれ duckdb + 拡張機能をローカルにインストールし、blob store と datalake 拡張用データベース(たとえば VM 上で動かす duckdb)を参照させることになるのだろうか。クエリ実行時のコンピュートはどこで起こるのか、そしてより大きな処理を行うにはどうすればよいのかが気になる。全ユーザーが巨大な duckdb VM に ssh してクエリを投げる構成になるのか、そのあたりの説明がほしい