Spark—关于RDD的并行度和分区(Local环境下测试)
本文将会跟大家一起简单探讨Spark 中RDD的并行度和分区
文章目录
前言
默认情况下,Spark 可以将一个作业切分多个任务后,发送给 Executor 节点并行计算,而能够并行计算的任务数量我们称之为并行度。这个数量可以在构建 RDD 时指定。切记,这里的并行执行的任务数量(Executor计算节点执行的),并不是指的切分任务的数量(Task任务)
提示:以下是本篇文章正文内容,下面案例可供参考
一、并发、并行和并行度
并发:是指有多个任务去抢占一个cpu核,即一个处理器处理多个任务
并行:是指多个任务有多个cpu核多同时处理,实现并行
有关并发与并行不做过多探讨,可以戳下面链接学习,毕竟每个人理解不同
可以看知乎上各路大神的解释 >> 戳这里
并行度:在分布式计算框架中一般都是多个任务同时执行,由于任务分布在不同的计算节点进行
计算,所以能够真正地实现多任务并行执行,记住,这里是并行,而不是并发。这里我们将整个集群并行执行任务的数量称之为并行度。那么一个作业到底并行度是多少呢?这个取决于框架的默认配置。应用程序也可以在运行过程中动态修改。
二、分区
- 我第一次了解到分区,是kafka中对消息的分区,为了达到负载均衡,提升性能,可以对消息进行分区,因为如果一个topic内的消息只存于一个broker,那这个broker会成为瓶颈,无法做到水平扩展;
- spark 在创建RDD时可以指定分区的数量,提升性能,因为通过分区可以实现并行计算,当然也可以对不同分区进行不同逻辑的计算
关于spark创建RDD的方式可以 >> Spark—RDD的创建(Local环境)
1. 从集合(内存)中创建 RDD时的分区
使用 makeRDD(seq, numSlices) 方法(如下):
通过源码可以发现,makeRDD()方法可以传入两个参数,一个是序列对象,一个分区数量。对于第二个参数有以下说明:
- 第二个参数可以不传递的,那么makeRDD方法会使用默认值 : defaultParallelism(默认并行度)
spark在默认情况下,从配置对象中获取配置参数:spark.default.parallelism
scheduler.conf.getInt(“spark.default.parallelism”, totalCores); - 如果获取不到配置参数,那么使用totalCores属性,这个属性取值为当前运行环境的最大可用cpu核数
设置配置参数(假设设置10个分区),代码测试如下(示例):
// 准备环境
val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
// 设置分区数量
sparkConf.set("spark.default.parallelism", "10")
val sc = new SparkContext(sparkConf)
// 创建RDD
val rdd = sc.makeRDD(List(1,2,3,4))
// 将处理的数据保存成分区文件
rdd.saveAsTextFile("output")
// 关闭环境
sc.stop()
效果:
代码测试如下(示例):
// 准备环境
val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
val sc = new SparkContext(sparkConf)
测试1:
// 创建RDD
// 【】代表一个分区
// seq:List(1,2,3,4), numSlices:2
// result:【1,2】,【3,4】
val rdd = sc.makeRDD(List(1,2,3,4), 2)
效果:
测试2:
// seq:List(1,2,3,4), numSlices:3
// result:【1】,【2】,【3,4】
val rdd = sc.makeRDD(List(1,2,3,4), 3)
效果:
测试3:
// seq:List(1,2,3,4,5), numSlices:3
// result:【1】,【2,3】,【4,5】
val rdd = sc.makeRDD(