
2026/08/05 7:09
ラップトップ用データパワーツール DuckDB が Clojure で登場(2023 年)
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Tech.ml.dataset は、高価な分散クラスターを必要とせずに標準的なラップトップ上で直接、効率的かつ大規模なデータ処理を可能にするツール「tmducken」をリリースしました。DuckDB の最新 C インターフェースによるバッチ操作およびゼロコピーパスウェイを活用することで、この統合は開発者がローカルで大量のデータセットを取り扱う方法を根本的に変革します。例えば、このシステムでは、4 億行を含む 50GB の CSV ファイルを約 2 分(具体的には約 1 分 50 秒)で読み込み、自動インデックス作成により 18GB に圧縮することに成功しています。さらに、消費グレードのハードウェア上で約 14 億行を含む後続の結合操作はわずか 2.5 秒で完了し、ゼロコピーパスウェイを使用した特定のリダクションタスクでは最短で約 1 秒(1037 ミリ秒)で処理されました。この機能により、業界が依存していた高価な Apache Spark インフラストラクチャへの依存が解消され、高性能な分析は大型組織だけでなく個人開発者にも利用可能になります。DuckDB はオープンソースであり MIT ライセンスの下で提供されている C++ システムであり、コードベースは約 10 万行あります。この画期的な成果により、複雑なデータ分析が民主化され、以前は主要なデータセンター外では実用的ではなかった機能型プログラミングのワークフローを使用して、企業が行う詳細な結合やローカル調査が可能になりました。
本文
大規模データ処理における DuckDB と tech.ml.dataset (TMD) の統合と活用
1. TMD の現状と課題
機能的なデータサイエンスプラットフォームである「tech.ml.dataset」(TMD)は、以下の特性を持っています。
- 列優先形式: メモリ内に格納されたデータを効率的に処理する設計です。
- スケーラビリティ: メモリ収容を超えた場合でも、サンプル単位の操作やサブセットフィルタリングにより利用可能です。
- 永続化:
、nippy
、arrow
などを使用して、小型から大型までのデータを保存できます。parquet
しかし、以下のような大規模データに対しては現状の TMD だけでは不十分な場合があります。
- 超大規模データ: 例として、100GB 規模でリレーションシップ属性を持つ
ファイルセットなどが挙げられます。.csv - Spark クラスタへの依存回避: 機能的ではない Spark クラスタに巻き込まれるリスクを避けつつ、トランザクション的な相互作用や単純なディスク I/O モデルを維持したいニーズは依然として重要です。
- 現環境での処理能力: 現地のディスク容量とチップ処理速度は十分であり、クラウドクラスタへの依存は必要ありません。
2. DuckDB の進化と TMD との親和性
リレーショナルデータベースである DuckDB は、TMD の列優先モデルを損なうことなく、以下の利点を提供します。
- 効率的なデータ導入: JDBC または Postgres を通じた非効率な全行変換手法では、バッチ化されていない API が課題でした。これに対し、DuckDB は解決策を提供しました。
- 大幅な改良(過去 2 年):
- C インターフェースが挿入とクエリに対してバッチ化されたシステムを提供しています。
- これにより、非常に大規模な結合処理が可能になりました。
- Clojure と TMD を通じて DuckDB の最先端のベクトル化 SQL 実行エンジンにアクセスできるようになっています。
3. 実際の活用事例:50GB データセットの処理
前回の投稿を踏まえ、以下のデータセットを用いて検証を行いました。
- データ規模: 50GB の
ファイル(3 年分のトランザクションデータ)。.csv - 行数: 全行数 4 億行。
データベースへのロードと圧縮
DuckDB にデータをロードするのは容易ですが、処理に時間がかかります。
time duckdb data.ddb 'CREATE TABLE data AS FROM "data.csv";' # real 1m50.091s # user 21m42.693s # sys 0m57.887s
- 結果: DuckDB は自動的にインデックスを生成し、データを約18GBに圧縮しました。
Clojure 環境からのアクセス
TMD を介して DuckDB にアクセスする手順は以下の通りです。
(require '[tmducken.duckdb :as duckdb]) (require '[tech.v3.dataset :as ds]) (duckdb/initialize!) ; バイナリをロード (def db (duckdb/open-db "data.ddb")) (def conn (duckdb/connect db)) ; クエリ実行 (time (duckdb/sql->dataset conn "SELECT COUNT(*) AS n FROM data"))
データの結合と分析
別のデータセット(SKU ごとの製品カラー情報)を追加し、データベースに挿入します。
; カラー情報の生成および dataset 化 (def colors-ds (-> (let [colors ["red" "green" "blue" "yellow" "purple" "black" "white"]] (->> (for [brand (range 100) style (range 10) item (range 10)] (let [sku (format "sku-%s-%s-%s" brand style item) n (rand-int 8)] (for [color (take n (shuffle colors))] {"sku" sku "color" color}))) (apply concat))) (ds/->dataset {:dataset-name "colors"}))) ; データベースへ作成・挿入 (duckdb/create-table! conn colors-ds) (duckdb/insert-dataset! conn colors-ds)
結合クエリの性能検証
4 億件のトランザクションとカラー情報を結合した結果、ノートパソコン上で1.42 億行の結合処理をわずか2.5 秒で完了しました。
(time (duckdb/sql->dataset conn "SELECT COUNT(*) FROM data INNER JOIN colors ON data.sku = colors.sku")) ; Elapsed time: 2486.620275 msecs ; | count_star() | ; |-------------:| ; | 1416737859 |
ビジネスロジックの適用(時系列分析)
SQL では複雑な処理が困難な場合でも、Clojure と TMD を用いて処理できます。ここでは特定 SKU の全トランザクションを時系列順に取得し、簡易的な減算処理を実行しました。
- 通常クエリパス: 約1.07 秒で完了。
- ゼロコピー(Zero-Copy)パス:
オプションを使用することで、理論上の最低メモリ消費パスを実現し、約1.04 秒で完了しました。{:reduce-type :zero-copy-imm}
; 通常パス (time (reduce (fn [eax ds] (conj eax (ds/row-count ds))) [] (duckdb/sql->datasets conn "SELECT * FROM data WHERE sku='sku-50-5-5' ORDER BY inst"))) ; ゼロコピーパス(より低メモリ消費) (time (let [sql "SELECT * FROM data WHERE sku='sku-50-5-5' ORDER BY inst" options {:reduce-type :zero-copy-imm}] (reduce (fn [eax zc-ds] (conj eax (ds/row-count zc-ds))) [] (duckdb/sql->datasets conn sql options))))
4. DuckDB の技術的雑記
DuckDB は以下の特徴を持ちます。
- 自動インデックス管理:
- 数値データには自動的に minmax インデックス(BRIN)が作成され、クエリ性能が劇的に向上します。
- 一意またはプライマリーキーを持つ列には ART インデックスが自動作成されます。
- ユーザーがカテゴリー型列にオプションでインデックスを作成することも可能ですが、ストレージ増大やトランザクション速度低下のトレードオフがあります。
- 移植性: 標準的な C++11 で記述されており、Mac M-1 などのプラットフォームへの対応も迅速です。
- コードベース:
ディレクトリに約10 万行の C++ コードが含まれています。src
(base) chrisn@chrisn-lp2:~/dev/cnuernber/duckdb$ cloc src Language files code ------------------------------------------------------------------------------- C++ 831 99454 C/C++ Header 679 28287 CMake 101 1541 Markdown 1 15 ------------------------------------------------------------------------------- SUM: 1612 129297
5. まとめ
DuckDB と TMD の統合は、以下の価値を提供します。
- 分散ソリューションへの依存排除: 小型のチームでも高価な Spark クラスタに頼らず、効率的に大規模データを扱えます。
- 計算ツールの民主化: ノートパソコン上で高品質な計算を実行可能にし、「鈍器のようなツールしか持たないユーザー」がクラスタを求めている状況を解消します。
TechAscent はこの DuckDB 統合機能をサポートし、ご依頼によるカスタマイズも可能です。お問い合わせください。