You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Parquet行组大小含义解析及合并优化技术咨询

Parquet Row-Group 合并优化与常见问题解答

背景与需求

  • 刚接触Parquet格式,Apache官方推荐Row-Group大小为512MB-1GB,部分资料显示默认值为128MB
  • 有一批将在AWS Glue PySpark中处理的Parquet文件,源文件Row-Group极小(例如一个85MB的snappy压缩文件,包含1115个Row-Group,每个约500KB,总未压缩大小约500MB)
  • 希望合并Row-Group以提升处理效率,假设Spark会逐Row-Group读取,过多小Row-Group会增加IO操作

核心问题解答

子问题1:pqrs报告的Row-Group大小是否为未压缩内存大小?

是的,pqrs工具展示的Row-Group大小为未压缩的内存大小,磁盘上的实际文件大小是压缩后的结果,因此会与计算的总未压缩大小存在差异。你提到的文件总未压缩大小约500MB,经snappy压缩后磁盘大小为85MB,符合snappy通常1:3~1:6的压缩比范围。

子问题2:官方推荐的Row-Group大小指未压缩还是压缩后?

Apache官方推荐的512MB-1GB(或默认128MB)Row-Group大小,指的是未压缩的内存大小,与pqrs报告的数值直接对应。选择该范围是为了平衡IO效率与内存占用:过大的Row-Group会增加内存压力,过小则会触发频繁的IO请求,降低处理效率。

Spark读取Row-Group的假设验证

你的假设正确:Spark读取Parquet时以Row-Group为基本IO单位,过多小Row-Group会导致大量小IO请求,增加磁盘开销与任务调度成本,合并为合适大小的Row-Group可有效提升处理效率。

合并Row-Group的代码优化与BatchSize设置

你当前使用的PyArrow合并代码如下:

import pyarrow.dataset as ds
import pyarrow.parquet as pq

def compact_parquet_in_batches(infile, outfile, batchsize):
    parquet_file = pq.ParquetFile(infile)
    ds.write_dataset(
        parquet_file.iter_batches(batch_size=batchsize), 
        outfile,
        schema=RSCHEMA,
        format='parquet'
    ) 

这里的核心问题是:iter_batches的batch_size是记录数,但ds.write_dataset写入Parquet时,会受PyArrow默认的未压缩Row-Group大小限制(默认128MB),仅靠记录数无法精准控制Row-Group大小。

正确的配置方式

要精准控制Row-Group大小,需在写入时直接指定未压缩的Row-Group字节数,而非仅依赖记录数:

方式1:使用ParquetWriter直接控制

import pyarrow.parquet as pq

def compact_parquet(infile, outfile, target_row_group_size):
    parquet_file = pq.ParquetFile(infile)
    schema = parquet_file.schema
    
    # 直接指定未压缩Row-Group大小(字节),例如128MB:128 * 1024 * 1024
    writer = pq.ParquetWriter(
        outfile,
        schema=schema,
        compression='snappy',
        row_group_size=target_row_group_size
    )
    
    for batch in parquet_file.iter_batches():
        writer.write_batch(batch)
    
    writer.close()

方式2:在ds.write_dataset中配置写入参数

import pyarrow.dataset as ds
import pyarrow.parquet as pq

def compact_parquet_in_batches(infile, outfile, target_row_group_size):
    parquet_file = pq.ParquetFile(infile)
    write_options = ds.ParquetWriteOptions(
        compression='snappy',
        row_group_size=target_row_group_size
    )
    ds.write_dataset(
        parquet_file.iter_batches(), 
        outfile,
        schema=parquet_file.schema,
        format='parquet',
        write_options=write_options
    ) 

为何设置60000条记录生成了2个Row-Group?

因为PyArrow默认的未压缩Row-Group大小为128MB,当写入的数据累积到128MB未压缩大小后,会自动生成一个Row-Group。你设置的60000条记录对应的未压缩大小超过了128MB,因此被拆分为两个Row-Group(第一个达到128MB,剩余数据作为第二个)。

内容的提问来源于stack exchange,提问作者teejay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 20:59:51