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

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

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

本仓库展示了现代数据处理引擎(如 DuckDB 和 Daft )如何在单节点 上高效处理存储在 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. 多节点集群
  • 更快的开发:更易于设置和调试
  • 足够的性能:通常对于分析工作负载来说足够快

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

参考资料

相关推荐
我的愿望是成为富婆6 小时前
2027校招AI产品经理能力清单:数据科学与大数据技术专业如何准备
大数据·人工智能·产品经理
空空dream6 小时前
03 | 更新:Ollama 换成 llama.cpp构建更小的离线镜像
人工智能·语言模型·llama
单向箔6 小时前
08|一套可复制的 AI Coding 流程:从需求到提交怎么走
人工智能·prompt·ai编程
AI棒棒牛6 小时前
YOLO26 改进:融合 LW-DETR 思想的轻量 TokenMixer,让 Neck 从局部堆叠走向局部-全局协同!嘎嘎创新!
人工智能·深度学习·yolo·目标检测
Alinket6 小时前
毫米波雷达 vs 摄像头 vs 手环:养老跌倒监测三类方案怎么选
网络·数据库·健康医疗·信息与通信·iot
Hello.Reader6 小时前
REA 深度实战让 AI Agent 学会逆向工程,从软件行为分析到二进制原理还原
人工智能
William一直在路上6 小时前
垂直领域大模型训练的一点思考和探索
人工智能·大模型·llm
腾讯云大数据6 小时前
本体立骨架,语义供刻度——DataBuddy对企业AI语义架构的一次完整回答
大数据·人工智能·架构·云计算·腾讯云
武汉星际互动6 小时前
从“一件事”到“一类事”,政务服务改革的“下一站”在哪里?
大数据·人工智能·政务
朝朝辞暮i6 小时前
VLA 系统学习第 20 课——Diffusion Policy 为什么要先给动作加噪,再学习把噪声去掉?
人工智能·python·深度学习·transformer·vla