spark-sql 分区小文件合并

时间:2024-05-21 18:57:35

spark-sql执行任务小文件生成规则

示例数据

元数据 : {数据库名称:mydb,   表名称:t30,    字段列表: a int, b int c int  }

主数据: [1,4,2  ;  3,4,6  ;  4,6,7 ]

1.使用spark-sql查询表数据 任务的task数与小文件数保持一致

例如下图所示 :  表t30中保存的是主数据,其中有17个文件,每一个文件的大小都小于块大小(64M)

启动spark任务

                        示例spark-sql语句:  select  *  from  t30;

启动spark任务读取文件,文件大小小于块设定的空间,不会再被切分,即每一个文件都是一个task任务(大文件会自动划分成块文件,每一个块文件一个task),task任务可以在多个服务器之间并发执行,每一个task都会生成一个文件  查询阶段将会生成17个task 

如果查询的结果需要写入其他表中, 每一个task都会生成一个文件写入新的表

                      示例spark-sql语句:  insert  into t31 select  *  from  t30  where a > 10

执行sql语句中有过滤条件,task读取文件过滤之后,文件会变得更小,即生成17个更小的文件

spark-sql 分区小文件合并

为了合并小文件块,可以使用分发的方式 即task查询完成之后,在进行shuffle, 重新分区,分发的关键词为 distribute by rand()

            示例spark-sql语句:  select  *  from  t30 distribute by rand();

上面的sql表示根据所有数据随机分发,分发后,每一个分区的数据量大致相等,分发的分区总数默认200个,可以设置自动分区                  示例spark-sql语句:  set spark.sql.adaptive.enabled=true;

设置之后 每一个分区尽可能靠近一个块文件大小(64M)