DeepSeek总结的在单节点上处理 1TB Parquet 数据方法

原文地址:https://github.com/danielbeach/duckdbAndDaftEat1TB

在单节点上处理 1TB Parquet 数据

本仓库展示了现代数据处理引擎(如 DuckDBDaft )如何在单节点 上高效处理存储在 S3 中的 1TB Parquet 数据,即使数据集大于可用内存。

数据集

测试数据集使用 rustGenerate1TB 生成,该工具创建了 1TB 的银行交易数据作为 Parquet 文件并上传到 AWS S3。数据集包含:

  • 位置s3://confessions-of-a-data-guy/transactions/
  • 格式:Parquet 文件(每个约 256MB)
  • 模式
    • transaction_id(字符串)
    • datetime(日期时间)
    • customer_id(Int64)
    • order_qty(Int32)
    • order_amount(Float64)

为什么单节点处理很重要

传统的数据处理通常需要分布式系统(如 Spark 集群)来处理大型数据集。然而,现代分析引擎可以在单台机器上处理大于可用内存的数据集,通过以下方式实现:

  1. 流式/分块处理:以小块读取和处理数据,而不是将所有数据加载到内存中
  2. 惰性求值:构建查询计划以优化数据访问模式
  3. 溢出到磁盘:在内存受限时自动将中间结果溢出到磁盘
  4. 列式格式:利用 Parquet 的列式存储进行高效的列剪裁和谓词下推

DuckDB 实现

文件duckdb_main.py

DuckDB 使用其 httpfs 扩展直接从 S3 读取 Parquet 文件,并使用以下方式进行处理:

  • 自动溢出到磁盘 :通过 temp_directory 配置,在内存受限时将中间结果溢出到磁盘
  • 内存管理:可配置的内存限制允许 DuckDB 处理大于 RAM 的数据
  • SQL 接口:使用标准 SQL 查询,并自动进行查询优化
  • 直接 S3 访问:无需在本地下载文件

主要特点:

  • 读取匹配 S3 glob 模式的所有 Parquet 文件
  • 按日期对交易进行分组
  • 聚合:交易计数、客户计数、订单金额和数量
  • 直接将结果写入 CSV,而无需在内存中物化

内存配置:

python 复制代码
con.execute("SET memory_limit='50GB';")
con.execute("SET temp_directory=?;", [str(spill_dir)])

即使在 16GB 的机器上,DuckDB 也可以通过自动溢出到磁盘来处理 1TB 数据。

Daft 实现

文件daft_main.py

Daft 是一个分布式 DataFrame 库,可以在单节点上运行并高效处理大于内存的数据集:

  • 批量处理:以可配置的批次大小(20万行)处理数据
  • 惰性执行:构建执行计划,在物化之前进行优化
  • 内存高效:通过流式执行自动管理内存
  • 原生 S3 支持:直接访问 S3,自动处理凭据

主要特点:

  • 使用 glob 模式从 S3 读取 Parquet 文件
  • 将 datetime 转换为 date 以便分组
  • 执行聚合操作,自动进行内存管理
  • 将结果转换为 Arrow 格式,以便高效写入 CSV

内存管理:

python 复制代码
df = df.into_batches(200_000)  # 以 20 万行为批次进行处理

使用方法

前提条件

  1. AWS 凭证:配置 AWS 凭证以访问 S3:

    bash 复制代码
    aws configure
    # 或设置环境变量:
    export AWS_ACCESS_KEY_ID=your_key
    export AWS_SECRET_ACCESS_KEY=your_secret
    export AWS_DEFAULT_REGION=us-east-1
  2. Python 依赖项:安装所需软件包:

    bash 复制代码
    pip install duckdb daft pyarrow boto3

运行 DuckDB

bash 复制代码
python duckdb_main.py

这将:

  • 从 S3 读取所有 Parquet 文件
  • 按日期聚合交易
  • 将结果写入 daily_transactions_summary.csv
  • 显示执行时间

运行 Daft

bash 复制代码
python daft_main.py

这将:

  • 分批读取 Parquet 文件
  • 执行相同的聚合操作
  • 将结果写入 CSV
  • 显示执行时间

性能特点

这两个引擎都证明了单节点可以处理大于内存的数据集

  • 内存使用:通过流式处理和溢出到磁盘,保持在可用 RAM 内
  • I/O 效率:利用 Parquet 的列式格式进行选择性列读取
  • 网络优化:仅从 S3 读取必要的数据
  • 可扩展性:可以处理比可用内存大很多倍的数据集

查询示例

两种实现执行相同的聚合操作:

sql 复制代码
SELECT
    CAST(datetime AS DATE) AS date,
    COUNT(transaction_id) AS transaction_count,
    COUNT(customer_id) AS customer_count,
    SUM(order_amount) AS total_order_amount,
    SUM(order_qty) AS total_order_qty
FROM read_parquet('s3://confessions-of-a-data-guy/transactions/**/*.parquet')
GROUP BY 1
ORDER BY total_order_amount DESC

输出

两个脚本都会生成 daily_transactions_summary.csv,其中包含按日期聚合的交易数据,并按总订单金额降序排列。

这为什么重要

这证明了现代分析引擎已经发展到不再需要分布式系统来处理大型数据集。单节点处理提供了:

  • 更简单的架构:无需集群管理开销
  • 成本效益:单机 vs. 多节点集群
  • 更快的开发:更易于设置和调试
  • 足够的性能:通常对于分析工作负载来说足够快

关键在于使用专为分析工作负载设计的引擎(列式处理、向量化、查询优化),而不是逐行处理。

参考资料

相关推荐
么么...1 小时前
系统性 MySQL 优化:性能分析、索引设计与失效场景全解
数据库·经验分享·sql·mysql
一只落魄的蜂鸟1 小时前
【2026年-04期】Intelligent agent architecture
人工智能
咋吃都不胖lyh1 小时前
GBDT 回归任务生成过程(逐步计算演示)
人工智能·数据挖掘·回归
幻云20101 小时前
Next.js 之道:从入门到精通
前端·javascript·vue.js·人工智能·python
阿豪Jeremy1 小时前
LlamaFactory微调Qwen3-0.6B大模型实验整理——调一个人物领域专属的模型
人工智能·深度学习·机器学习
heartbeat..2 小时前
数据库性能优化:优化的时机(表结构+SQL语句+系统配置与硬件)
java·数据库·mysql·性能优化
YongCheng_Liang2 小时前
分布式数据库核心原理深度解析:架构、理论与事务解决方案
运维·数据库·sql
培根芝士2 小时前
把PP-OCRv5_server模型转换为OpenVINO格式
人工智能·openvino
UrSpecial2 小时前
IM项目——文件管理子服务
服务器·数据库·oracle