- 650GB規模のDelta LakeデータをS3に保存し、これを単一ノード環境でPolars、DuckDB、Daft、Sparkにより処理した性能比較実験
- 32GBメモリのEC2インスタンスで、各エンジンが大規模データを処理できるかを検証し、クラスター型Sparkに対する単一ノードの可能性を探った
- DuckDBは16分、Polarsは12分、Daftは50分、PySparkは1時間以上を要し、単一ノードでも実用的な処理が可能であることを確認
- PolarsはDeletion Vectorを未サポートで、DuckDBのみがこの機能をサポートしており、Lake House互換性に差がある
- 結果として、単一ノードフレームワークが低コストなハードウェアでも大規模データ処理を可能にすることを実証し、分散コンピューティングへの依存を見直す必要性を提起
クラスター疲れと単一ノードの代替案
- SaaSベースのLake Houseクラスター運用のコストと複雑さが増す中で、「クラスター疲れ(cluster fatigue)」という現象に言及
- 過去にはPandas以外に有力な代替がなくSparkを使っていたが、**DuckDB・Polars・Daft(D.P.D.)**の登場により、単一ノード処理の可能性が広がった
- D.P.D.はメモリより大きい(LTM)データセットの処理と高速演算が可能
- 記事は分散型と非分散型という2つの選択肢を示し、**「Single Node Rebellion」**という概念を強調している
実験環境の構成
- S3にDelta Lakeテーブルを作成し、約650GBのデータを保存(1TBを目標としていたが中断)
- **EC2インスタンス(32GB RAM、16 CPU)**でDuckDB、Polars、Daftを実行し、その後Sparkと比較
- データはソーシャルメディア投稿形式の模擬データで、Python dictを作成してDaft DataFrameに変換後、Parquetファイルとして保存
- その後ParquetファイルをDatabricksでDelta Lakeテーブルに変換し、年・月単位のパーティションを構成
- Deltaログを除くと約650GBのデータであることを確認
メモリ制約とストリーミングの必要性
- 単一ノード(32GBメモリ)で650GBのデータを処理する必要があるため、ストリーミング方式でのクエリ実行の必要性が提起された
- PolarsのGitHub Issueを引用し、Icebergへのストリーミング書き込み機能を求める事例に言及
- PolarsやDuckDBなどの新世代フレームワークには、Lake Houseフォーマットをストリーミング方式で読み書きできる標準サポートが必要だと強調
各エンジン別のテスト結果
- DuckDB
- Deletion Vectorをサポートする唯一のエンジン
- 650GBのデータを32GBのLinuxマシンで16分で処理することに成功
- コードはシンプルで、結果ファイルも正常に生成
- Polars
- Deletion Vector未サポートのため、Lake House環境では制約がある
- Lazy API(Scan/Sink)の利用が必要
- 12分で処理完了し、DuckDBより高速
- Daft
- Rustベースで使い勝手は良いが、処理時間は50分で最も遅い
- Iceberg関連の作業では安定した動作を確認
- PySpark(Databricks Single Node)
- 1時間以上を要し、チューニングなしで実行
- 単一ノードエンジンと比べて効率は低い
- 実験の目的は速度よりも単一ノードの実現可能性の検証にあった
結論と示唆
- 単一ノードフレームワークでも大規模なLake Houseデータを処理可能であることを実験で実証
- 低コストなハードウェアでも妥当な実行時間とシンプルなコード構造を確保
- DuckDB・Polars・Daftはいずれも分散クラスターなしで実用的な性能を提供
- 分散コンピューティングだけが唯一の解決策ではないことを示し、現代のLake Houseアーキテクチャの再考を促している
- **「Single Node Rebellion」**という概念を通じて、コスト効率の高いデータエンジニアリング手法の可能性を浮き彫りにしている
1件のコメント
Hacker Newsのコメント
Daft は AI ワークロード向けの 高性能データ処理エンジン で、単一ノード環境と分散環境の両方で動作する
今回のベンチマークを通じて、並列性 と パイプライニング に多くの改善余地があることが分かった。特に deltalake リーダーと groupby 演算子には最適化すべき点が多かった
今後のリリースでこれらの改善を反映する予定で、詳細は GitHub、Twitter、LinkedIn で確認できる
Daft が面白そうなら、
pip install daftで直接試せる過剰なツール導入 の代わりに GNU ツールを使えばいい
ちなみに古い記事だが今でも興味深い資料だ — command-line tools can be 235x faster than your Hadoop cluster
650GB の JSON データを CLI ツールで集計しても、DuckDB や ClickHouse の 並列処理性能 に追いつくのは難しい。GNU Parallel でも試したが限界があった
実際にはデータカタログとクラスター基盤の作業が必要になる
Delta や Iceberg の代わりに Parquet ファイルを直接たどって クエリしている
BigQuery でクエリした結果をローカルの Parquet ファイル(約 1GB 単位)に落として DuckDB で分析している。RAM よりはるかに大きいデータでもうまく動く
BigQuery と DuckDB のそれぞれの 集計性能の差 を比較して、処理を 2 つのエンジンに分けて実行することもある。こういう組み合わせがデータエンジニアリングの面白いところだ
c5.4xlarge インスタンスの最大 10Gbps 帯域幅では、S3 から 650GB を読むのに最低 9 分かかる
I/O スケジューリング方式のわずかな違いが結果に大きく影響したのではないか
むしろ大きなインスタンスを使って早く終わらせるほうが、より 経済的 かもしれない
NVMe ストレージ は S3 よりはるかに速く、ローカルの 8〜16 コア CPU がクラウドより良いかもしれない
S3 は優れた製品だが、ローカルストレージ性能 には及ばない
ファイルサイズの分布や API 呼び出しの偏りのほうが大きな変数だった気がする
「大きなインスタンスのほうが安く終わるかもしれない」という話には全面的に同意する
Spark は多段階の大規模データセットに向いており、S3 をバックエンドに使う場合は ネットワークボトルネック がコストとして表れる
DuckDB / Polars の単一ノード性能は印象的だが、これはまるで 滑走路上の飛行機とオートバイを競争させる ようなものだ
こうした違いのせいで分散コンピューティングに疲れを感じる人も多い
リソースの限界を把握し、その限界に対する実測性能を比率で表せば、ずっと明確になる
さまざまなシステムを試した点は良いが、メモリより大きいクエリ を本格的に扱ってほしかった
DuckDB はメモリ超過ストリーミングに強いが、Polars はまだ成熟していない
S3 のデフォルト設定は並列読み取りを妨げないので、結局は VM のネットワーク帯域幅 がボトルネックだった可能性が高い
ClickHouse が最も速く、DuckDB は シンプルさと安定性 の面で最高だった
Flink と PySpark は 3〜5 倍遅く、Dask と Ray も遅すぎた
今ではほとんどのワークロードで DuckDB か ClickHouse から始めることを勧めている。Pandas が遅いときは DuckDB に置き換える のが私の基本戦略だ
単一ノードのライブラリでも 1TB 程度なら十分処理でき、10TB を超えるあたりから Spark に移ればよい
関連イシュー
だが、もっと良いツールで解決できる場合が多い
以前、ジュニアエンジニアが 5GB の JSON を数百個 Python の文字列結合 で処理していて 18 時間かかっていたが、
簡単なコンソールツールと multiprocessing に置き換えたら 35 分に短縮できた
適切なツール選び が核心だ
メンテナンスと実行コストが非常に安く、コストパフォーマンスの高いツール だ
小さなバッチ書き込み時に Parquet ファイルが増えすぎる問題を解決するため、DuckLake はそれを DBMS(Postgres など)にインライン保存する
最近になってようやく Parquet に再書き出しする機能が追加されたが、まだ安定化が必要だ
関連ドキュメント
カタログを SQL DB で表現しなければならないが、Parquet の利点はまさにその複雑さを避けられることにある
カタログも Parquet ベースにすれば、自己ブートストラップ型フォーマット にできそうだ