由于 parquet 文件损坏,Impala 无法创建分区表

Posted

技术标签:

【中文标题】由于 parquet 文件损坏,Impala 无法创建分区表【英文标题】:Impala fails at creating partitioned table because of corrupted parquet file 【发布时间】:2020-01-31 19:53:16 【问题描述】:

我正在使用 Dask 将分区 parquet 文件保存在 S3 存储桶上:

dd.to_parquet(
    dd.from_pandas(df, npartitions=1),
    path='s3a://test/parquet',
    engine='fastparquet',
    partition_on='country',
    object_encoding='utf8',
    compression="gzip",
    write_index=False,
)

Parquet 文件创建成功;这是目录结构: directory structure

我成功地用这个镶木地板创建了一个 Impala 表:

create external table tmp.countries_france
like parquet 's3a://test/parquet/_metadata'
partitioned by (country string)
stored as parquet location 's3a://test/parquet/'

以及向该表添加分区:

alter table tmp.countries_france add partition (sheet='belgium')

但是,当我执行select * from tmp.countries_france 时,出现以下错误:

文件 's3a://test/parquet/sheet=france/part.0.parquet' 已损坏:元数据指示行数为零,但至少有一个非空行组。

我猜这个问题来自 Dask,因为当我创建一个未分区的镶木地板时,它可以正常工作。我试过设置write_index=True,但没有成功。

【问题讨论】:

【参考方案1】:

我没有看到这个

df = pd.DataFrame('a': np.random.choice(['a', 'b', 'c'], size=1000),
                   'b': np.random.randint(0, 64000, size=1000),
                   'c': np.random.choice([True, False], size=1000))
writer.write(tempdir, df, partition_on=['a', 'c'], file_scheme=scheme)
df = dd.from_pandas(df, npartitions=1)
df.to_parquet('.', partition_on=['a', 'c'], engine='fastparquet')

pf = fastparquet.ParquetFile('_metadata')
pf.count  # 1000
len(pf.to_pandas())  # 1000
pf.row_groups[0].num_rows  # 171

pf = fastparquet.ParquetFile('a=a/c=False/part.0.parquet')
pf.count # 171
pf.row_groups[0].num_rows  # 171

显然,我不能说 impala 可能在做什么 - 但也许“喜欢”机制期望在 _metadata 文件中找到数据?

请注意,pandas 可以在没有 dask 的情况下使用相同的选项写入/写入 parquet。

【讨论】:

错误来自这里github.com/apache/impala/blob/… 是github.com/apache/parquet-format/blob/master/src/main/thrift/… 的num_rows 字段设置正确吗? 好像不是,会在fastparquet上记录一个bug。

以上是关于由于 parquet 文件损坏,Impala 无法创建分区表的主要内容,如果未能解决你的问题,请参考以下文章

Parquet 格式文件

Hive/Impala 中压缩 parquet 文件(例如 gz.parquet)的外部表

使用 Impala 在 HDFS 中查询 Parquet 文件

Parquet 支持的 Hive 表:Impala 中不可查询的数组列

为 impala 表无缝覆盖底层 parquet 数据

在 Impala 中使用外部创建的 Parquet 文件