11.5 Spark SQL

1,示例

(1) 给DataFrame设置别名(一行代码一行代码运行)

val rdd=sc.makeRDD(Seq(("Jack",24),("Mary",34)));

val df1 = rdd.toDF();

val df2 = rdd.toDF("name","age");

df1.show();

df2.show();

运行结果:

 

(2)使用SqlContext执行SQL语句 (继续上面的代码运行)

df2.createOrReplaceTempView("person");

val sqlContext = spark.sqlContext

sqlContext.sql("select * from person").show();

运行结果:

(3)Scala代码将RDD转成Bean

在D:/a路径下面,创建stud.txt文件,文件内容:

4 Jack 34 男

1 Mike 23 女

2 刘长友 45 男

3 雪丽 27 女

在pom.xml文件中添加依赖

<dependency>

        <groupId>org.apache.spark</groupId>

        <artifactId>spark-sql_2.12</artifactId> <version>3.1.1</version>

</dependency>

运行代码 

package org.hadoop.spark
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.SparkSession
object RddToBean1 {
  def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf();
    conf.setMaster("local[*]");
    conf.setAppName("RDDToBean");
    val spark: SparkSession = SparkSession.builder().config(conf).getOrCreate();
    val sc: SparkContext = spark.sparkContext;
    //读取文件
    import spark.implicits._;
    //步2:读取文件
    val rdd: RDD[String] = sc.textFile("file:///D:/a/stud.txt");
    //步3:第一次使用map对每一行进行split,第二次使用map将数据封装到Bean中,最后使用toDF转换成DataFrame
    val df = rdd.map(_.split("\\s+")).map(arr => {
      Stud(arr(0).toInt, arr(1), arr(2).toInt, arr(3));
    }).toDF();
    //步4:显示或是保存数据
    df.show();
    spark.close();
  }
  /** 步1:声明JavaBean,并直接声明主构造方法 * */
  case class Stud(id: Int, name: String, age: Int, sex: String) {
    /** 声明无参数的构造,调用主构造方法 * */
    def this() = this(-1, null, -1, null);
  }
}

 运行结果

 (4)WordCount示例

  •  直接使用groupBy进行count计算

val rdd = sc.textFile("hdfs://localhost:9000/input/notes.txt")

val df3 = rdd.flatMap(_.split("\\s+")).toDF("str");

df3.groupBy("str").count().show();//运行结果见1图

运行结果

  • 指定排序规则

df3.groupBy("str").count().sort("str").show();//对字符进行排序

  • 直接使用SQL语句 

df3.createOrReplaceTempView("words");

spark.sql("select count(str),str from words group by str").show

 

(5)Scala代码示例

  • 运行SparkSQL.scala

  • 运行SparkSQL2.scala 

2,Read和Write

read方法介绍

通用 Load/Save 函数 - Spark 3.5.2 文档 (apache.org)

可以读取的数据类型

csv format jdbc json load option options

orc parquet schema table text textFile 

<think>好的,用户想了解如何在Spark中确定Executor的核心数分配。我需要根据提供的引用资料来整理回答。首先,用户提供的引用中有四个相关的内容,涉及Executor的cores、内存配置以及性能调优的建议。 先回忆一下Spark的基本架构。每个Executor是一个JVM进程,负责运行task。核心数(cores)决定了Executor并行执行task的能力。每个core同一时间只能处理一个task,所以cores越多,并行能力越强。但配置过高可能导致资源竞争,过少则可能资源利用不足。 根据引用[4],参数`spark.executor.cores`设置每个Executor的CPU core数量,直接影响task的并行能力。需要结合集群资源和任务特性来调整。比如,如果每个Executor有3个core,就能同时跑3个task。 然后看引用[3],提到Tiny executors方案,每个Executor配1个core。这种情况下,总Executor数等于集群总core数。比如16个节点,每个节点16 core,总共有160 core,那么Executor数量就是160,每个1 core,内存4GB。但可能这种配置不适合需要较高并行度的任务,因为每个Executor只能处理一个task,可能影响效率。 引用[1]中的例子是每个Executor配3 core,共5个Executor,内存13GB。这说明实际配置需要权衡core数和内存,同时考虑总资源的情况。比如,总核心数是3*5=15,可能集群总core数为15或更高,允许这样的分配。 引用[2]建议`spark.sql.shuffle.partitions`设置为总core数的2~3倍。这说明并行度与总cores相关,而总cores由`num-executors` * `executor-cores`决定。所以配置cores时需要考虑后续的并行参数。 接下来需要整理配置时的考虑因素: 1. **总集群资源**:每个节点的core数和内存,总节点数。例如,每个节点有16 cores和64GB内存,总共有10个节点,总cores是160,总内存640GB。 2. **Executor的cores选择**: - 每个Executor的core数通常在1到5之间。太多会导致内存不足,GC压力大;太少则并行度低。 - 例如,如果选择3 cores,每个Executor内存13GB(引用[1]),那么每个Executor的内存分配需足够每个task使用,避免OOM。 3. **内存分配**:每个Executor的内存需要分配给堆内存、堆外内存、以及Spark内部开销。例如,内存分为`executor-memory`,其中堆外内存可能需要通过参数调整,如`spark.executor.memoryOverhead`。如果配置13GB,可能实际可用堆内存为13 - 1(overhead)=12GB左右。 4. **Executor数量计算**: - `num-executors` = (总集群cores / 每个Executor的cores) - 预留的cores(比如给ApplicationMaster和其他进程)。 - 例如,总cores 160,每个Executor 3 cores,预留1 core,则`num-executors`=(160-1)/353,但实际可能需要根据节点分布调整,比如每个节点分配固定数量的Executors,避免跨节点资源竞争。 5. **性能调优考虑**: - 数据本地性和任务调度:较多的Executors可能提升数据本地性,但管理开销增加。 - Shuffle操作:需要足够的并行度,调整shuffle partitions参数。 - 避免资源浪费:确保cores和内存的平衡,避免内存不足或cores闲置。 另外,用户提供的示例中,引用[3]提到Tiny executors可能适合某些场景,但通常推荐使用适量cores的配置,比如每个Executor 3-5 cores,以平衡并行度和资源利用率。 总结步骤可能包括: 1. 确定集群总资源。 2. 根据任务类型(CPU密集型或内存密集型)决定每个Executor的cores和内存。 3. 计算可行的Executors数量,考虑预留资源。 4. 调整相关参数如shuffle partitions。 5. 测试并监控性能,进行优化调整。 需要确保回答结构清晰,分步骤说明,并引用相关资料中的例子和参数建议。同时,生成相关问题,可能涉及优化方法、内存配置、参数调优等。</think>在Spark中合理配置Executor核心数(cores)是性能调优的关键环节,需综合考虑集群资源、任务特性和并行需求。以下是具体配置方法和计算步骤: --- ### **一、核心参数关系** 1. **总资源公式** $$总核心数 = num\text{-}executors \times executor\text{-}cores$$ 需确保总核心数不超过集群可用核心数(预留1-2个核心给系统进程)[^3]。 2. **内存分配公式** $$executor\text{-}memory = \frac{节点总内存}{每个节点的executor数量}$$ 需预留10%内存给操作系统和Spark管理开销[^1]。 --- ### **二、配置步骤** 1. **确定集群资源** - 假设集群有10个节点,每个节点16核心、64GB内存。 2. **选择单个Executor的cores** - **推荐范围**:3-5 cores/executor[^1] - **过高风险**:内存不足导致GC时间长;**过低风险**:并行度不足。 - 示例选择3 cores/executor。 3. **计算Executor数量** $$num\text{-}executors = \lfloor \frac{总核心数 - 预留核心}{executor\text{-}cores} \rfloor$$ 若预留2核心: $$num\text{-}executors = \lfloor \frac{10 \times 16 - 2}{3} \rfloor = 52$$ 4. **计算Executor内存** $$executor\text{-}memory = \frac{节点内存}{每个节点的executor数量} \times 0.9$$ 每个节点运行5 executors(总executors=52,约每个节点5-6个): $$executor\text{-}memory = \frac{64GB}{5} \times 0.9 \approx 11.5GB$$ 实际配置为`--executor-memory 11g`[^1]。 --- ### **三、配置优化建议** 1. **CPU密集型任务**:增加`executor-cores`(4-5 cores),减少executor数量。 2. **内存密集型任务**:降低`executor-cores`(2-3 cores),提升单个executor内存。 3. **动态分配**:启用`spark.dynamicAllocation.enabled`自动调整资源[^2]。 4. **Shuffle调优**:设置`spark.sql.shuffle.partitions`为总核心数的2-3倍[^2]。 --- ### **四、示例配置** ```bash spark-submit \ --num-executors 52 \ --executor-cores 3 \ --executor-memory 11g \ --conf spark.sql.shuffle.partitions=300 \ ... ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值