由于 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 无法创建分区表的主要内容,如果未能解决你的问题,请参考以下文章
Hive/Impala 中压缩 parquet 文件(例如 gz.parquet)的外部表
使用 Impala 在 HDFS 中查询 Parquet 文件