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. 多节点集群
  • 更快的开发:更易于设置和调试
  • 足够的性能:通常对于分析工作负载来说足够快

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

参考资料

相关推荐
Agent产品评测局几秒前
离散制造业生产流程优化,AI落地实操步骤详解:从传统自动化到企业级智能体的技术范式跃迁
运维·人工智能·ai·自动化
rainbow724244几秒前
零基础职场人线上学习AI,是否支持线上考试?
人工智能·学习
2301_775639892 分钟前
mysql如何查看服务器支持的存储引擎_使用SHOW ENGINES命令
jvm·数据库·python
360亿方智能3 分钟前
走向Agent-Native!360AI知识库打通业务底座,让人与AI自然协同
人工智能
love530love4 分钟前
Python 3.12 解决 MediaPipe “no attribute ‘solutions‘” 终极方案:基于全版本硬核实测的避坑指南
开发语言·人工智能·windows·python·comfyui·mediapipe·solutions
a7963lin4 分钟前
html标签怎样表示搜索框_input type=search语义优化【操作】
jvm·数据库·python
a7963lin8 分钟前
Python数据分析如何识别异常值_IQR四分位距检测法实战
jvm·数据库·python
fengyehongWorld9 分钟前
AI 专有名词释义
人工智能
RkxI7soAM9 分钟前
冷钱包选购的安全标准答案:锁定Ledger官方授权店铺
人工智能·安全
<-->10 分钟前
sglang-omni [多模态大语言模型的推理与评测框架]
人工智能·语言模型·自然语言处理