案例
默认shuffle 有200个分区
执行下面的代码:
import org.apache.spark.SparkConf
import org.apache.spark.sql.{DataFrame, SparkSession}
object Std1_sparksql {
def main(args: Array[String]): Unit = {
val sc = new SparkConf().setMaster("local[*]").setAppName("std")
//创建SparkSession
val ss: SparkSession = SparkSession.builder().config(sc).getOrCreate()
val df: DataFrame = ss.read
.option("header", "false") //默认为false,表示第一行不是表头
.option("sep", ",") //列分隔符
.csv("cdz.txt") //读取本地文件
.toDF("id","ele_num","time","start_time","end_time") //设置列名,默认列名不方便查询
//创建临时视图(只在当前session中可用,视图:只能查询不能修改)
df.createOrReplaceTempView("cdz")
println("统计各充电桩的充电量")
val frame: DataFrame = ss.sql("select id,sum(ele_num) as `充电量` from cdz group by id")
println("partitions num:",frame.rdd.partitions.length)
//不合并分区,会产生200个文件
//frame.rdd.coalesce(1).saveAsTextFile("res2")
ss.stop() //关闭
}
}
执行结果,显示 200 个分区,一个任务一个分区,也就是说有 200 个任务,保存文件也有 200 个
提出问题
默认 200个任务,有以下问题:
- 单机运行,开启这么多任务,效率反而低
- 集群运行,当数据量较小,开启这么多任务,浪费资源。而且任务执行时间较短,大部分时间都用在调度
- 集群运行,当数据量较大,开启任务较少,不能充分利用集群资源,效率低
解决
设置初始分区的 1.5-2倍之间
设置分区关键代码:
SparkSession对象.conf.set("spark.sql.shuffle.partitions",2)
例子
package com.std
import org.apache.spark.SparkConf
import org.apache.spark.sql.{DataFrame, SparkSession}
// 设置分区
object s4 {
def main(args: Array[String]): Unit = {
val sc = new SparkConf().setMaster("local[*]").setAppName("std")
//创建SparkSession
val ss: SparkSession = SparkSession.builder().config(sc).getOrCreate()
// 设置分区
ss.conf.set("spark.sql.shuffle.partitions",2)
val df: DataFrame = ss.read
.option("header", "false") //默认为false,表示第一行不是表头
.option("sep", ",") //列分隔符
.csv("cdz.txt") //读取本地文件
.toDF("id","ele_num","time","start_time","end_time") //设置列名,默认列名不方便查询
//创建临时视图(只在当前session中可用,视图:只能查询不能修改)
df.createOrReplaceTempView("cdz")
println("统计各充电桩的充电量")
val frame: DataFrame = ss.sql("select id,sum(ele_num) as `充电量` from cdz group by id")
println("partitions num:"+frame.rdd.partitions.length)
//不合并分区,会产生200个文件
// frame.rdd.coalesce(1).saveAsTextFile("res2")
ss.stop() //关闭
}
}