Spark RDD 弹性分布式数据集 简单理解

1.RDD

        RDD是Spark的最基本抽象,是对分布式内存的抽象使用,实现了以操作本地集合的方式来操作分布式数据集的抽象实现。RDD是Spark最核心的东西,它表示已被分区,不可变的并且能够被并行操作的数据集合,不同的数据集格式对应不同的RDD实现。RDD必须是可序列化的。 RDD可以cache到内存中,每次对RDD数据集的操作之后的结果,都可以存放到内存中,下一个操作可以直接从内存中输入,省去了MapReduce大量的磁盘IO操作。这对于迭代运算比较常见的机器学习算法,交互式数据挖掘来说,效率提升比较大。
(1)RDD的特点
  • 它是在集群节点上的不可变的、已分区的集合对象。
  • 通过并行转换的方式来创建如map,filter,join,etc。
  • 失败自动重建。
  • 可以控制存储级别(内存、磁盘等)来进行重用。
  • 必须是可序列化的。
  • 是静态类型
(2)RDD的好处
  • RDD只能从持久存储或通过Transformtions操作产生,相比于分布式共享内存(DSM)可以更高效实现容错,对于丢失部分数据分区只需根据它的lineage就可以重新计算出来,而不需要做特定的Checkpoint。
  • RDD的不变形,可以实现推测式执行
  • RDD的数据分区特性,可以通过数据的本地性来提高性能,这与Hadoop MapReduce是一样的。
  • RDD都是可序列化的,在内存不足时可自动降级为磁盘存储,把RDD存储于磁盘上,这时性能会有大的下降单不会差于现在的MapReduce。
(3)RDD的存储与分区
  • 用户可以选择不同的存储级别以便重用。
  • 当前RDD默认是存储于内存,但当内存不足时,RDD会spill到disk。
  • RDD在需要进行分区把数据分布于集群中时会根据每条记录Key进行分区(如Hash分区),以此保证两个数据集在Join时能高效。
(4)RDD的内部表示
在RDD的内部实现中每个RDD都可以使用5个方面的特性来表示:
  • 分区列表(数据块列表)
  • 计算每个分片的函数(根据父RDD计算出此RDD)
  • 对父RDD的依赖列表
  • 对key-value RDD的Partitioner
  • 每个数据分片的预定义地址列表
(5)存储级别
RDD根据useDisk、useMemory、deserialized、replication四个参数的组合

2.RDD创建

  • 通过读取外部数据集
  • 通过读取集合对象
  • 通过已有的RDD生成新的RDD

3.RDD操作

对于RDD可以有两种计算方式:
  • 转换(返回值还是一个RDD)
  • 行动(返回值不是一个RDD)
(1)转换操作(Transformations)
如map,filter,groupBy,join等,Transformations操作是Lazy的(惰性),也就是说从一个RDD转换生成另一个RDD的操作不是马上执行,Spark在遇到Transformations操作时只会记录需要这样的操作,并不会去执行,需要等到有Actions操作的时候才会真正启动计算过程进行计算。
(2)行动操作(Actions)
如:collect,count,save等,Actions操作会把返回结果或把RDD数据写到存储系统中。Actions是触发Spark启动计算的动因。

4.RDD操作实例

(1)单RDD转换函数
以{1,2,3,3}为例,f代表函数
函数名
目的
示例
结果
map(f)
将函数应用于每一个元素中,返回值构成新的RDD
rdd.map(x=>x+1)
{2,3,4,4}
flatMap(f)
将函数应用于每一个元素中,并把元素中迭代器内所有内容一并生成新的RDD,常用于切分单词
rdd.flatMap(x=>x.to(3))
{1,2,3,2,3,3,3}
filter(f)
过滤元素
rdd.filter(x=>x!=1)
 {2,3,3}
distinct()
元素去重
rdd.distinct()
 {1,2,3}
sample( withReplacement, fraction , [seed] )
元素采样,以及是否需要替换
rdd.sample(false,0.5)
 不确定值,不确定数目
(2)集合转换操作
以{1,2,3}{3,4,5}为例,rdd代表已生成的RDD实例
函数名
目的
示例
结果
union(rdd)
合并两个RDD所有元素(不去重)
rdd1.union(rdd2)
{1,2,3,3,4,5}
intersection(rdd)
求两个RDD的交集
rdd1.intersection(rdd2)
{3}
substract(rdd)
移除在RDD2中存在的RDD1元素
rdd1.substract(rdd2)
{1,2}
cartesian(rdd)
求两个RDD的笛卡尔积
rdd1.cartesian(rdd2)
{(1,3),(1,4),(1,5)...(3,5)}

5.宽依赖和窄依赖

不同的操作依据其特性,可能会产生不同的依赖RDD之间的依赖关系有以下两种:
(1)窄依赖
一个父RDD分区最多被一个子RDD分区引用,表现为一个父RDD的分区对应于一个子RDD的分区或多个父RDD的分区对应于一个子RDD的分区,也就是说一个父RDD的一个分区不可能对应一个子RDD的多个分区,如map,filter,union等操作则产生窄依赖。
(2)宽依赖
一个子RDD的分区依赖于父RDD的多个分区或所有分区,也就是说存在一个父RDD的一个分区对应一个子RDD的多个分区,如groupByKey等操作则产生宽依赖操作。

你可能感兴趣的:(大数据,Spark,spark,hadoop,大数据)