【大数据】【Spark】 RDD

一 RDD基础

1 sparkContext

每个Spark应用都由一个驱动器程序来发起集群上的各种并行操作,驱动器程序通过一个SparkContext对象访问Spark。有了SparkContext,我们就可以用它创建RDD。如何初始化sparkContext: 我们只需要两个参数,集群URL和应用名。

2 RDD

弹性分布式数据集,一个不可变的分布式对象集合,每个RDD都被分为多个分区,这些分区运行在集群中的不同节点上。在Spark中,对数据的所有操作就是创建RDD,转化已有RDD,调用RDD操作进行求值。

用户可以有两种方式创建RDD
  • ⑴读取一个外部数据集
  • ⑵在驱动器程序分布驱动器程序中的对象集合(比如list和set)
RDD支持两种类型的操作
  • ⑴转换操作(transformation) 由一个RDD生成一个新的RDD,转化操作的计算必须得等到有了行动操作才行。我们可以使用简单的action操作,比如count来计划转化操作。
  • ⑵行动操作(action) 对RDD计算出一个结果,并把结果返回到驱动器程序中,或者把结果存储到外部系统(如HDFS中)。每当我们调用一个新的行动操作时,整个RDD都会从头开始计算,为了避免这种低效行为,我们可以将中间结果持久化。action 默认是fifo,我们也可以选择fair,job0 job1并行,有的时候job0的结果还没算出缓存,job1就找不到缓存,就找job0的上一个,直到hdfs.

二 创建RDD

  • 1 读取外部数据集
  • 2 在驱动器程序中对一个集合进行并行化

三 持久化

我们希望能多次使用同一个RDD,这时候我们就可以使用持久化方式,很多初学的同学认为调用了cache或者persist的那一刻就是在缓存了,这是完全不对的,真正的缓存执行指挥在action被触发,job被提交开始计算,在计算的中间过程中才会执行。

1. 持久化persist()
持久化策略:
  • ⑴MEMORY_ONLY
    使用未序列化的Java对象格式,将数据保存在内存中。如果内存不够存放所有的数据,那么下次对这个RDD执行算子操作时,那些没有被持久化的数据,需要从源头处重新计算一遍。这是默认的持久化策略,使用cache()方法时,实际就是使用的这种持久化策略。
  • ⑵MEMORY_AND_DISK
    使用未序列化的Java对象格式,优先尝试将数据保存在内存中。如果内存不够存放所有的数据,会将数据写入磁盘文件中
  • ⑶MEMORY_ONLY_SER
    会将RDD中的数据进行序列化。
  • ⑷MEMORY_AND_DISK_SER
    会将RDD中的数据进行序列化。
  • ⑸DISK_ONLY
    使用未序列化的Java对象格式,将数据全部写入磁盘文件中。
  • ⑹MEMORY_ONLY_2, MEMORY_AND_DISK_2等等
    对于上述任意一种持久化策略,如果加上后缀_2,代表的是将每个持久化的数据,都复制一份副本,并将副本保存到其他节点上。这种基于副本的持久化机制主要用于进行容错。
数据淘汰机制
  • 若我们都存在内存中,内存中放不下,会使用LRU策略,把最近最少使用的缓存移除
2. 反持久化unpersist()

手动把持久化的RDD从缓存中移除。

四 partition

spark中的partition 是弹性分布式数据集RDD的最小单元,RDD是由分布在各个节点上的partition 组成的。partition 是指的spark在计算过程中,生成的数据在计算空间内最小单元,同一份数据(RDD)的partition 大小不一,数量不定,是根据application里的算子和最初读入的数据分块数量决定的,这也是为什么叫“弹性分布式”数据集的原因之一。
partition带来的好处是并行化,计算资源足够则时间明显缩短。
我们需要注意的是,只有Key-Value类型的RDD才有分区的,非Key-Value类型的RDD分区的值是None的。

1.partition与block的关系
  • block位于存储空间、partition 位于计算空间
  • block的大小是固定的、partition 大小是不固定的
  • block是有冗余的、不会轻易丢失,partition(RDD)没有冗余设计、丢失之后重新计算得到
  • Spark从HDFS读入文件的分区数默认等于HDFS文件的块数(blocks),HDFS中的block是分布式存储的最小单元。如果我们上传一个30GB的非压缩的文件到HDFS,HDFS默认的块容量大小128MB,因此该文件在HDFS上会被分为235块(30GB/128MB);Spark读取SparkContext.textFile()读取该文件,默认分区数等于块数即235
2.分区函数
  • HashPartition 弊端是数据不均匀,容易导致数据倾斜
  • RangePartitioner 会对key值进行排序,然后将key值被划分成分区份数key值集合。数据均匀,而且分区之间有序,但是分区内的元素是不能保证顺序的。
  • CustomPartitioner 自定义分区

你可能感兴趣的:(hadoop)