设置 parquet snappy 输出文件大小是 hive?

Posted

技术标签:

【中文标题】设置 parquet snappy 输出文件大小是 hive?【英文标题】:Set parquet snappy output file size is hive? 【发布时间】:2015-06-15 15:13:15 【问题描述】:

我正在尝试在 dfs.block.size 边界上拆分由 hive INSERT OVERWRITE TABLE... 创建的 parquet/snappy 文件,因为当分区中的文件大于块大小时,impala 会发出警告。

impala 记录以下警告:

Parquet files should not be split into multiple hdfs-blocks. file=hdfs://<SERVER>/<PATH>/<PARTITION>/000000_0 (1 of 7 similar)

代码:

CREATE TABLE <TABLE_NAME>(<FILEDS>)
PARTITIONED BY (
    year SMALLINT,
    month TINYINT
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\037'
STORED AS PARQUET TBLPROPERTIES ("parquet.compression"="SNAPPY");

至于INSERT hql 脚本:

SET dfs.block.size=134217728;
SET hive.exec.reducers.bytes.per.reducer=134217728;
SET hive.merge.mapfiles=true;
SET hive.merge.size.per.task=134217728;
SET hive.merge.smallfiles.avgsize=67108864;
SET hive.exec.compress.output=true;
SET mapred.max.split.size=134217728;
SET mapred.output.compression.type=BLOCK;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
INSERT OVERWRITE TABLE <TABLE_NAME>
PARTITION (year=<YEAR>, month=<MONTH>)
SELECT <FIELDS>
from <ANOTHER_TABLE> where year=<YEAR> and month=<MONTH>;

问题是文件被占用的地方到处都是:

partition 1: 1 file: size = 163.9 M 
partition 2: 2 file: size = 207.4 M, 128.0 M
partition 3: 3 file: size = 166.3 M, 153.5 M, 162.6 M
partition 4: 3 file: size = 151.4 M, 150.7 M, 45.2 M

无论dfs.block.size 设置(以及上述其他设置)增加到256M512M1G(针对不同的数据集),问题都是一样的。

有没有办法/设置来确保输出 parquet/snappy 文件的拆分刚好低于 hdfs 块大小?

【问题讨论】:

我最终使用 pyspark 破解了解决方案。检查原始数据的大小并得出从原始数据到 parquet snappy 压缩的“良好比率”(从 gz 约为 1.4)n = int(math.ceil(size * 1.4 / hdfs_block_size)) df.repartition(n)。 write.parquet(some_path) (这是 2015 年有效的解决方案) 【参考方案1】:

一旦文件增长到单个 HDFS 块的大小并启动​​新文件,就无法关闭文件。这与 HDFS 通常的工作方式背道而驰:文件跨越许多块。

正确的解决方案是 Impala 将其任务安排在本地块的位置,而不是抱怨文件跨越多个块。这是最近以IMPALA-1881 完成的,将在Impala 2.3 中发布。

【讨论】:

感谢 Ryan,这对于非复杂类型的列非常有效。有没有其他方法可以在 Impala 中使用 INSERT INTO...SELECT 来处理复杂事件?另外,如果 HDFS 的块大小配置为 128MB,那么将 parquet 块大小设置为 256MB 是否有意义?每个文件减少一个块是理想的情况吗?谢谢!【参考方案2】:

您需要同时设置 parquet 块大小和 dfs 块大小:

SET dfs.block.size=134217728;  
SET parquet.block.size=134217728; 

两者都需要设置为相同,因为您希望 parquet 块 适合 hdfs 块。

【讨论】:

谢谢,刚试了没用,估计是parquet/snappy。 mapred.max.split.size 怎么样?我认为这也很重要。 从 Parquet 1.8.0 开始,如果块大小小于行组大小 (parquet.block.size),它将自动设置为行组大小。这样,如果您忘记设置,就不会出现此错误。【参考方案3】:

在某些情况下,您可以通过设置 mapred.max.split.size(parquet 1.4.2+)来设置 parquet 块大小,您已经这样做了。您可以将其设置为低于 hdfs 块大小以增加并行度。 Parquet 会尽可能与 hdfs 块对齐:

https://github.com/Parquet/parquet-mr/pull/365

2015 年 11 月 16 日编辑: 根据 https://github.com/Parquet/parquet-mr/pull/365#issuecomment-157108975 这也可能是在 Impala 2.3 中修复的 IMPALA-1881。

【讨论】:

以上是关于设置 parquet snappy 输出文件大小是 hive?的主要内容,如果未能解决你的问题,请参考以下文章

文件格式对比ORC-Parquet,存储格式对比Gzip-Bzip2-Snappy

parquet常用操作

Spark + Parquet + Snappy:spark shuffle 数据后整体压缩率下降

Flink 实战系列Flink 同步 Kafka 数据到 HDFS parquet 格式存储 snappy 压缩

Flink 实战系列Flink 同步 Kafka 数据到 HDFS parquet 格式存储 snappy 压缩

Parquet vs ORC vs ORC with Snappy