2.1、从集合中创建rdd的分区个数
从源码角度分析集合(内存)创建rdd过程分区个数的生成。
-
代码案例
val conf = new SparkConf().setAppName("Simple Application").setMaster("local[*]") val sc = new SparkContext(conf) // 创建时指定分区 val rdd = sc.makeRDD(List(1,2,3,4,5),3)
-
源码解析
/* rdd 创建 seq: Seq[T] 数据集合 numSlices: Int = defaultParallelism 分区个数 */ def makeRDD[T: ClassTag]( seq: Seq[T], numSlices: Int = defaultParallelism): RDD[T] = withScope { parallelize(seq, numSlices) } /* numSlices: Int = defaultParallelism 分区个数不指定话会默认赋值为defaultParallelism 查看 defaultParallelism 的由来 */ /** Default level of parallelism to use when not given by user (e.g. parallelize and makeRDD). 用户未指定时使用的默认并行级别(例如并行化和 makeRDD)。 */ def defaultParallelism: Int = { assertNotStopped() taskScheduler.defaultParallelism // task任务调度器的 defaultParallelism } /* 进入 taskScheduler.defaultParallelism 发现 TaskScheduler是一个接口 defaultParallelism是下面这个抽象方法 */ def defaultParallelism(): Int /* ctrl + h 查看方法实现类 进入 private[spark] class TaskSchedulerImpl 查找 defaultParallelism 得到下面这个方法 */ override def defaultParallelism(): Int = backend.defaultParallelism() // backend:后端 /* backend.defaultParallelism() 点进去看见是一个 private[spark] trait SchedulerBackend 接口 ctrl + h 找到该接口实现类 主要有以下两个 */ private[spark] class LocalSchedulerBackend //本地模式 private[spark] class CoarseGrainedSchedulerBackend(scheduler: TaskSchedulerImpl, val rpcEnv: RpcEnv) // Mesos模式或者独立模式 /** 我们是使用本地获取sc 的 所以查看 LocalSchedulerBackend 中是如何实现的 */ override def defaultParallelism(): Int = scheduler.conf.getInt("spark.default.parallelism", totalCores) /* 上面这个方法中的 scheduler.conf 就是我们开始创建的SparkConf totalCores 服务器核数 getInt("spark.default.parallelism", totalCores) 如果我们没有指定 spark.default.parallelism 那么 将默认取集群申请的核数。 */
-
源码测试
// 1、通过配置文件 conf 指定分区数 val conf = new SparkConf().setAppName("Simple Application").setMaster("local[*]") conf.set("spark.default.parallelism","5") val rdd = sc.makeRDD(List(1,2,3,4,5)) val par = rdd.getNumPartitions println(s"partitions: $par") // 2、通过sc.makeRDD方法指定 val rdd = sc.makeRDD(List(1,2,3,4,5),4)
-
总结
集合中创建的RDD分区数如果指定分区个数使用指定分区个数,默认任务启动的核心数。