spark3.0教程-SparkSQL:默认shuffle 有200个分区,设置分区数(spark.sql.shuffle.partitions)

案例

默认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() //关闭
  }
}

原文出处:/show_1IX3FehffWrH.html