[转]Spark SQL repartition 为啥生成的文件变大了?

1.问题

原表数据1400MB左右;

spark sql查询后对dataframe使用reparation,再写入结果表;

结果表有12个800多MB的parquet文件,严重膨胀。

2.结论

先说明两个函数区别:

repartition : 把record完全打乱最终随机插入到10个文件 有Shuffle
coalesce : 把相邻的分区的数据捏在一起,没有Shuffle

为啥shuffle打乱数据会让最终的表输出文件变大

猜测可能是因为parquet格式编码问题,parquet列式存储,repartition完全打乱后导致本来在一个文件的相同记录分布到12个文件,压缩比降低,最终文件就变大了。

所以推荐使用 coalesce 接口来做类似的事情。

 

如果在reparation时指定partition key字段,结果表可能会正常(待验证

 3.类似案例

原链接:Spark写parquet文件时,经过shuffle和不shuffle数据量 不同,shuffle后parquet文件压缩比降低

Spark写parquet文件时,经过shuffle和不shuffle数据量 不同,shuffle后parquet文件压缩比降低 最近在做测试时遇到一个奇怪的问题,不能理解,问题描述如下:   对相同的一份数据进行读取并写出为parquet文件时,对数据集进行shuffle和不进行shuffle后生成的parquet文件大小不同,且相差较多。具体操作如下: 原始数据集为snappy压缩的46G parquet文件,文件大小从11M~1.5G不等,共100个文件,对文件读取后写出为不压缩的parquet文件: val productDF = spark.read.parquet("/ingest/product/20180202/22-43/") //读取结果集后直接写出,不进行shuffle productDF   .write.mode(org.apache.spark.sql.SaveMode.Overwrite)   .option("compression", "none")   .parquet("/processed/product/20180215/04-37/read_repartition_write/nonewithoutshuffle") //读取结果集后,repartition为500个文件,shuffle后写出 productDF..repartition(500).write.mode(org.apache.spark.sql.SaveMode.Overwrite)   .option("compression", "none")   .parquet("/processed/product/20180215/04-37/read_repartition_write/nonewithshuffle") 两次程序执行写出的结果文件,大小不同。其中第一次不经过shuffle直接写出,生成parquent文件为80G,而第二次经过shuffle后生成文件总大小为283G。   同时我对80G的文件再次进行读取并repartition(500),生成283G文件。有两个问题不太明白: 第一个是为什么spark在repartitioning/shuffle写出parquet文件后文件总大小会增大 第二个问题是如何有效地shuffle spark中的数据,才能有效地对parquent文件进行编码/压缩?

posted @ 2022-09-01 15:18  江东邮差  阅读(582)  评论(0编辑  收藏  举报