spark sql/hive小文件问题
针对hive on mapreduce
1:我们可以通过一些配置项来使Hive在执行结束后对结果文件进行合并:
参数详细内容可参考官网:https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties
1 2 3 4 | hive.merge.mapfiles 在 map-only job后合并文件,默认 true hive.merge.mapredfiles 在map-reduce job后合并文件,默认 false hive.merge.size.per.task 合并后每个文件的大小,默认256000000 hive.merge.smallfiles.avgsize 平均文件大小,是决定是否执行合并操作的阈值,默认16000000 |
2:如果结果表使用了压缩格式,则必须配合Sequence File来存储,否则无法进行合并
3:Hadoop的归档文件格式也是解决小文件问题的方式之一。而且Hive提供了原生支持,如果使用的不是分区表,则可创建成外部表,并使用har://协议来指定路径
4:对于通常的应用,使用Hive结果合并就能达到很好的效果。如果不想因此增加运行时间,可以自行编写一些脚本,在系统空闲时对分区内的文件进行合并,也能达到目的。
5:Reducer数量的减少也即意味着结果文件的减少,从而解决产生小文件的问题。
但是,对于通过sparksql来处理数据的话,在conf里添加上面参数调整是没有作用的,不过可以通过下面的方式来规避小文件:
1.通过使用repartition重分区动态调整文件输出个数
比如 spark.sql("sql").repartition(1).write().mode(SaveMode.Overwrite).saveAsTable("test");
2.使用Adaptive Execution动态设置shuffle partition
1 2 3 4 5 6 7 8 9 10 11 12 13 | SparkConf conf = new SparkConf(); conf.set( "spark.sql.adaptive.enabled" , "true" ); conf.set( "spark.sql.adaptive.shuffle.targetPostShuffleInputSize" , "67108864b" ); conf.set( "spark.sql.adaptive.join.enabled" , "true" ); conf.set( "spark.sql.autoBroadcastJoinThreshold" , "20971520" ); SparkSession spark = SparkSession .builder() .appName( "JointSitePlan" ) .master( "local" ) .config(conf) .enableHiveSupport() .getOrCreate(); |
shuffle partition是通过参数spark.sql.shuffle.partitions来指定的,默认是200,但是对于数据不大,或者数据倾斜的情况,会生成很多的小文件,几兆甚至几KB大小,自适应执行则会根据参数 spark.sql.adaptive.shuffle.targetPostShuffleInputSize 动态调整reducer数量,详细可见 上一篇文章
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!
· 用 C# 插值字符串处理器写一个 sscanf