深入源码理解Spark RDD的数据分区原理
通过内存创建RDD的分区设置
1、示例代码
在创建RDD的时候,我们可以从内存中进行创建;输出保存为文件。为了演示效果,我们的示例代码如下:
import org.apache.spark.{SparkConf, SparkContext} object Spark02RddParallelizeSet {
def main(args: Array[String]): Unit = {
System.setProperty("hadoop.home.dir", "C:\\Hadoop\\")
val spark = new SparkConf().setMaster("local[*]").setAppName("RddParallelizeSet")
val context = new SparkContext(spark) val list = List(1, 2, 3, 4) // TODO: 从内存创建RDD,并且设置并行执行的任务数量
// numSlices: Int = defaultParallelism
val memoryRDD = context.makeRDD(list, 1)
memoryRDD.saveAsTextFile("output") val memoryRDD1 = context.makeRDD(list, 2)
memoryRDD1.saveAsTextFile("output1") val memoryRDD2 = context.makeRDD(list, 3)
memoryRDD2.saveAsTextFile("output2") val memoryRDD3 = context.makeRDD(list, 4)
memoryRDD3.saveAsTextFile("output3") val memoryRDD4 = context.makeRDD(list, 5)
memoryRDD4.saveAsTextFile("output4") // TODO: 结束
context.stop()
}
}
上面的代码里,我们从内存中创建了5个RDD,每个RDD设置了不同的分区数。
2、执行结果
(1)1个分区的RDD,效果如下图所示:
在output文件夹中,只包含了一个分区文件 part-00000 ,其文件内容如下图所示:
(2)2个分区的RDD,效果如下图所示:
在output1文件夹中,包含了两个分区文件 part-00000 以及 part-00001,二者文件内容如下图所示:
(3)3个分区的RDD,效果如下图所示:
在output2文件夹中,包含了三个分区文件 part-00000 、part-00001、part-00002,三者文件内容如下图所示:
(4)4个分区的RDD,效果如下图所示:
在output3文件夹中,包含了四个分区文件 part-00000、part-00001、part-00002、part-00003,四者文件内容如下图所示:
在output4文件夹中,包含了五个分区文件 part-00000、part-00001、part-00002、part-00003、part-00004,五者文件内容如下图所示:
3、分析结果
仔细看看上面图片中的结果,不难发现其中肯定深藏猫腻。不同分区数的设置,都存在不同的输出效果。要想深究其中缘由,有必要去了解Spark的在这一块的源码实现。进入到 makeRDD( ) 这个方法中,可以看到如下源码:
在图片中用红色方框框起来的部分,是一个方法,其中传入了两个参数,第一个 seq 就是在我们自己写的代码中,自己定义的那个 List;第二个 numSlices 就是我们自己写的代码中的那个分区数。
再点进 parallelize( seq, numSlices) 这个方法中去,可以看到如下源码:

红色线框框出的这个名为 getPartitions 的方法,返回的是一个分区的数组,ParallelCollectionRDD.slice( ) 调用的是 ParallelCollectionRDD 伴生对象里面的一个方法,看样子应该是这个方法里的代码规定了怎么进行分区的划分了,于是,进到这个方法里面,果不其然,可以看到如下代码块:
在 slice[T: ClassTag](seq: Seq[T], numSlices: Int): Seq[Seq[T]] 这个方法中,我们可以看到一个关于 seq 这个传入的参数的模式匹配:
在上图的这一段代码中,模式匹配第一个匹配的是 Range 类型,很明显与我们传入的 List 类型不一致,因此 case r: Range 这一块的匹配代码可以跳过。第二个匹配的也是Range,相比于第一个匹配的Range 整形类型 而言,第二个则可以匹配更多种类型的 Range。当然第二个case也不是我们要看的。那么就剩下第三个 "case _" 这种情况了。
在第三个情况中,首先将 我们传入的 List 转换为了一个 array,为什么要有这一步,源码中也给出了注释:To prevent O(n ^ 2) operations for List etc。之后调用了positions( ) 方法,将转换后的数组的长度以及分区数量传入,该方法源码如下:
我的分析过程如下,数据是(1,2,3,4),分区数量是1的情况:
4、小结
深入源码理解Spark RDD的数据分区原理的更多相关文章
- Caffe源码理解2:SyncedMemory CPU和GPU间的数据同步
目录 写在前面 成员变量的含义及作用 构造与析构 内存同步管理 参考 博客:blog.shinelee.me | 博客园 | CSDN 写在前面 在Caffe源码理解1中介绍了Blob类,其中的数据成 ...
- 基于SpringBoot的Environment源码理解实现分散配置
前提 org.springframework.core.env.Environment是当前应用运行环境的公开接口,主要包括应用程序运行环境的两个关键方面:配置文件(profiles)和属性.Envi ...
- Pytorch学习之源码理解:pytorch/examples/mnists
Pytorch学习之源码理解:pytorch/examples/mnists from __future__ import print_function import argparse import ...
- [源码解析] PyTorch 分布式(1) --- 数据加载之DistributedSampler
[源码解析] PyTorch 分布式(1) --- 数据加载之DistributedSampler 目录 [源码解析] PyTorch 分布式(1) --- 数据加载之DistributedSampl ...
- [源码解析] PyTorch 分布式(2) --- 数据加载之DataLoader
[源码解析] PyTorch 分布式(2) --- 数据加载之DataLoader 目录 [源码解析] PyTorch 分布式(2) --- 数据加载之DataLoader 0x00 摘要 0x01 ...
- HashMap源码理解一下?
HashMap 是一个散列桶(本质是数组+链表),散列桶就是数据结构里面的散列表,每个数组元素是一个Node节点,该节点又链接着多个节点形成一个链表,故一个数组元素 = 一个链表,利用了数组线性查找和 ...
- Fresco源码解析 - DataSource怎样存储数据
Fresco源码解析 - DataSource怎样存储数据 datasource是一个独立的 package,与FB导入的guava包都在同一个工程内 - fbcore. datasource的类关系 ...
- jedis的源码理解-基础篇
[jedis的源码理解-基础篇][http://my.oschina.net/u/944165/blog/127998] (关注实现关键功能的类) 基于jedis 2.2.0-SNAPSHOT ...
- HDFS源码分析心跳汇报之数据块汇报
在<HDFS源码分析心跳汇报之数据块增量汇报>一文中,我们详细介绍了数据块增量汇报的内容,了解到它是时间间隔更长的正常数据块汇报周期内一个smaller的数据块汇报,它负责将DataNod ...
随机推荐
- Ghost-无损DDL
目录 一.什么是DDL? 二.表级锁和元数据锁 2.1.什么是表锁? 2.2.什么是MDL? 三.什么是无损DDL? 四.DDL重建表 Mysql5.5之前重建表 Mysql5.6之后重建表 五.gh ...
- Spring+hibernate+JSP实现Piano的数据库操作---1.目录结构+展示
目录结构 界面
- 【前端】H5,底边按钮吸边,但是覆盖了列表循环的内容
我的说情况大致类似于: PS:因为底边那个模块 绝对是浮动的,所有会遮住列表最下面一条现实的一部分, 解决:这个时候把body的底边的内边距调整到可显示的就可以了: body { background ...
- 【保姆级教学】新手第一次搭建vue项目和初始化
前端项目初始化步骤 安装vue脚手架 通过vue脚手架创建项目 配置vue路由 配置Element-UI组件库 配置axios库 初始化git远程仓库 将本地项目托管到github或者码云上 通过vu ...
- Skill 计算两点距离
https://www.cnblogs.com/yeungchie/ code procedure(ycHowFar(a b) prog((xAB yAB sAB) xAB = xCoord(a) - ...
- day20:正则表达式
单个字符的匹配 findall(正则表达式,字符串) 把符合正则表达式的字符串存在列表中返回 预定义字符集(8) \d 匹配数字 \D 匹配非数字 \w 匹配数字字母下划线 \W 匹配非数字或字母或下 ...
- linux的存储管理(RALD) LVM 逻辑卷管理 虚拟阵列
磁盘存储管理 LVM 逻辑卷 虚拟阵列 1.Linux系统中 磁盘使用 存在3个大问题: 1.灵活性 2.安全性 3.性能 2.解决办法RAID独立磁盘冗余阵列 RAID(Redundant Arra ...
- RocketMQ文章
实战:RocketMQ削峰,这一篇就够了 https://juejin.im/post/5ea159e4f265da47f0794da5
- 面试官:怎么做JDK8的内存调优?
面试官:怎么做JDK8的内存调优? 看着面试官真诚的眼神,心中暗想看起来年纪轻轻却提出如此直击灵魂的问题.擦了擦额头上汗,我稍微调整了一下紧张的情绪,对面试官说: 在内存调优之前,需要先了解JDK8的 ...
- sql developer连接mysql数据库
1 首先打开sql developer ,选择上方菜单,工具(tools)--->首选项,如下图 2 数据库(database)--->第三方 JDBC驱动程序 ; “添加条目”,选择m ...