Spark RDD学习笔记
一、学习Spark RDD
RDD是Spark中的核心数据模型,一个RDD代表着一个被分区(partition)的只读数据集。
RDD的生成只有两种途径:
一种是来自于内存集合或外部存储系统;
另一种是通过转换操作来自于其他RDD;
一般需要了解RDD的以下五个接口:
partition分区,一个RDD会有一个或者多个分区
dependencies()RDD的依赖关系
preferredLocations(p)对于每个分区而言,返回数据本地化计算的节点
compute(p,context)对于分区而言,进行迭代计算
partitioner()RDD的分区函数
一个RDD包含一个或多个分区,每个分区都有分区属性,分区的多少决定了对RDD进行并行计算的并行度。
在生成RDD时候可以指定分区数,如果不指定分区数,则采用默认值,系统默认的分区数,是这个程序所分配到的资源的CPU核数。
可以使用RDD的成员变量partitions返回RDD对应的分区数组:
scala> var file = sc.textFile("/tmp/lxw1234/1.txt")
file: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[5] at textFile at :21
scala> file.partitions
res14: Array[org.apache.spark.Partition] = Array(org.apache.spark.rdd.HadoopPartition@735, org.apache.spark.rdd.HadoopPartition@736)
scala> file.partitions.size
res15: Int = 2 //默认两个分区
//可以指定RDD的分区数
scala> var file = sc.textFile("/tmp/lxw1234/1.txt",4)
file: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[7] at textFile at :21
scala> file.partitions
res16: Array[org.apache.spark.Partition] = Array(org.apache.spark.rdd.HadoopPartition@787, org.apache.spark.rdd.HadoopPartition@788, org.apache.spark.rdd.HadoopPartition@789, org.apache.spark.rdd.HadoopPartition@78a)
scala> file.partitions.size
res17: Int = 4
由于RDD即可以由外部存储而来,也可以从另一个RDD转换而来,因此,一个RDD会存在一个或多个父的RDD,这里面也就存在依赖关系,
窄依赖:
每一个父RDD的分区最多只被子RDD的一个分区所使用,如图所示:
宽依赖
多个子RDD的分区会依赖同一个父RDD的分区,如图所示:
以下代码可以查看RDD的依赖信息:
scala> var file = sc.textFile("/tmp/lxw1234/1.txt")
file: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[9] at textFile at :21
scala> file.dependencies.size
res20: Int = 1 //返回RDD的依赖数量
scala> file.dependencies(0)
res19:
org.apache.spark.Dependency[_] = org.apache.spark.OneToOneDependency@33c5abd0
//返回RDD file的第一个依赖
scala> file.dependencies(1)
java.lang.IndexOutOfBoundsException: 1
//因为file只有一个依赖,想获取第二个依赖时候,报了数组越界
需要大数据学习资料和交流学习的同学可以加大数据学习群:724693112 有免费资料分享和一群学习大数据的小伙伴一起努力
再看一个存在多个父依赖的例子:
scala> var rdd1 = sc.textFile("/tmp/lxw1234/1.txt")
rdd1: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[11] at textFile at :21
scala> var rdd2 = sc.textFile("/tmp/lxw1234/1.txt")
rdd2: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[13] at textFile at :21
scala> var rdd3 = rdd1.union(rdd2)
rdd3: org.apache.spark.rdd.RDD[String] = UnionRDD[14] at union at :25
scala> rdd3.dependencies.size
res24: Int = 2 // rdd3依赖rdd1和rdd2两个RDD
//分别打印出rdd3的两个父rdd,即 rdd1和rdd2的内容
scala> rdd3.dependencies(0).rdd.collect
res29: Array[_] = Array(hello world, hello spark, hello hive, hi spark)
scala> rdd3.dependencies(1).rdd.collect
res30: Array[_] = Array(hello world, hello spark, hello hive, hi spark)
1.3 RDD优先位置(preferredLocations)
RDD的优先位置,返回的是此RDD的每个partition所存储的位置,这个位置和Spark的调度有关(任务本地化),Spark会根据这个位置信息,尽可能的将任务分配到数据块所存储的位置,以从Hadoop中读取数据生成RDD为例,preferredLocations返回每一个数据块所在的机器名或者IP地址,如果每一个数据块是多份存储的(HDFS副本数),那么就会返回多个机器地址。
看以下代码:
scala> var file = sc.textFile("/tmp/lxw1234/1.txt")
file: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[16] at textFile at :21
//这里的file为MappedRDD
scala> var hadoopRDD = file.dependencies(0).rdd
hadoopRDD: org.apache.spark.rdd.RDD[_] = /tmp/lxw1234/1.txt HadoopRDD[15] at textFile at :21 //这里获取file的父RDD,即hdfs文件/tmp/lxw1234/1.txt对应的HadoopRDD
scala> hadoopRDD.partitions.size
res31: Int = 2 //hadoopRDD默认有两个分区
//下面分别获取两个分区的位置信息
scala> hadoopRDD.preferredLocations(hadoopRDD.partitions(0))
res32: Seq[String] = WrappedArray(slave007.lxw1234.com, slave004.lxw1234.com)
scala> hadoopRDD.preferredLocations(hadoopRDD.partitions(1))
res33: Seq[String] = WrappedArray(slave007. lxw1234.com, slave004.lxw1234.com)
##
由于HDFS副本数设置为2,因此每个分区的位置信息中包含了所有副本(2个)的位置信息,这样Spark可以调度时候,根据任何一个副本所处的位置进行本地化任务调度。
基于RDD的每一个分区,执行compute操作。
对于HadoopRDD来说,compute中就是从HDFS读取分区中数据块信息。
对于JdbcRDD来说,就是连接数据库,执行查询,读取每一条数据。
目前Spark中实现了两种类型的分区函数,HashPartitioner(哈希分区)和RangePartitioner(区域分区)。
partitioner只存在于类型的RDD中,非类型的RDD的partitioner值为None.
partitioner函数既决定了RDD本身的分区数量,也可作为其父RDD Shuffle输出中每个分区进行数据切割的依据。
scala> var a = sc.textFile("/tmp/lxw1234/1.txt").flatMap(line => line.split("\\s+"))
a: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[19] at flatMap at :21
scala> a.partitioner
res15: Option[org.apache.spark.Partitioner] = None // RDD a为非类型
scala> var b = a.map(l => (l,1)).reduceByKey((a,b) => a + b)
b: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[21] at reduceByKey at :30
scala> b.partitioner
res16: Option[org.apache.spark.Partitioner] = Some(org.apache.spark.HashPartitioner@2)
//RDD b为类型,采用的是默认的partitioner- HashPartitioner
Spark RDD学习笔记的更多相关文章
- Spark 基本函数学习笔记一
Spark 基本函数学习笔记一¶ spark的函数主要分两类,Transformations和Actions. Transformations为一些数据转换类函数,actions为一些行动类函数: ...
- Hadoop/Spark入门学习笔记(完结)
Hadoop基础及演练 ---第1章 初识大数据 大数据是一个概念也是一门技术,是在以Hadoop为代表的大数据平台框架上进行各种数据分析的技术. ---第2章 Hadoop核心HDFS Hadoop ...
- Spark RDD学习
RDD(弹性分布式数据集)是Spark的核心抽象.它是一组元素,在集群的节点之间进行分区,以便我们可以对其执行各种并行操作. 创建RDD的两种方式: 并行化驱动程序中的现有数据: 引用外部存储系统中的 ...
- spark scala学习笔记
搞清楚几个概念: 闭包 柯里化 搭建了intellij idea 的scala 开发环境
- spark shell学习笔记
http://homepage.cs.latrobe.edu.au/zhe/ZhenHeSparkRDDAPIExamples.html
- Spark RDD设计学习笔记
本文档是学习RDD经典论文<Resilient Distributed Datasets: A Fault-Tolerant Abstraction for In-Memory Cluster ...
- Spark学习笔记3——RDD(下)
目录 Spark学习笔记3--RDD(下) 向Spark传递函数 通过匿名内部类 通过具名类传递 通过带参数的 Java 函数类传递 通过 lambda 表达式传递(仅限于 Java 8 及以上) 常 ...
- Spark学习笔记2——RDD(上)
目录 Spark学习笔记2--RDD(上) RDD是什么? 例子 创建 RDD 并行化方式 读取外部数据集方式 RDD 操作 转化操作 行动操作 惰性求值 Spark学习笔记2--RDD(上) 笔记摘 ...
- Spark学习笔记——RDD编程
1.RDD——弹性分布式数据集(Resilient Distributed Dataset) RDD是一个分布式的元素集合,在Spark中,对数据的操作就是创建RDD.转换已有的RDD和调用RDD操作 ...
随机推荐
- [MyBatis]浅谈如何实现事务处理
要实现事务处理,就得从SqlSession中取出connection来,然后对connection采用setAutoCommit,commit,rollback等操作,最后的时候,不能像JDBC一样关 ...
- 文件上传对servlet的要求
request.getParamter(String name)方法不能再使用了 需要使用request.getInputStream()获取输入流对象然后在进行读取数据 解析数据 ServletIn ...
- CCIE总结:路由器、交换机
bbs.spoto.net/forum--.html -----雏鹰部落 GNS3安装 .安装的所有目录不能使用中文 ISO如何操作 securecrt如何使用建立会话:之前总是连不上的原因是没有选 ...
- [转]德哥的PostgreSQL私房菜 - 史上最屌PG资料合集
链接地址:https://yq.aliyun.com/articles/59251
- Flutter 贝塞尔曲线切割
现在人们对于网站的美感要求是越来越高了,所以很多布局需要优美的曲线设计.当然最简单的办法是作一个PNG的透明图片,然后外边放一个Container.但其内容如果本身就不是图片,只是容器,这种放入图片的 ...
- jmeter5实现文件上传接口测试
背景:在公司做接口自动化编写过程中,遇到需要测试一个在线下载导入模板的接口,之前都没有接触过关于文件上传下载的接口测试,此处做个记录,为后续工作开展做个参考. 步骤: 打开浏览器按F12 手动进行文件 ...
- PHP中include、require、include_once、require_once的区别
include:使用include引用外部文件时,只有代码执行到include代码段时,调用的外部文件才会被引用并读取,当引用的文件发生错误时,系统只会给出个警告错误,而整个php文件会继续执行.re ...
- 《剑指offer》字符串专题 (牛客11.01)
字符串的题目难度不一,涉及到的考点有字符串处理.字符串匹配(自动机.正则).模拟,以及递归.动态规划等算法. 难度 题目 知识点 ☆ 02. 替换空格 从后往前 ☆☆ 27. 字符串的排列 回溯,St ...
- Blynk系列随笔
Blynk系列随笔 1.基于Blynk服务器搭建物联网测试Demo 2.本地 Blynk服务器搭建
- go string类型的特性
参考文章: http://c.biancheng.net/view/36.html 1. 获取ascii类型字符的长度个数和获取utf8类型字符长度的个数 a. len("咪咪") ...