CC00029.spark——|Hadoop&Spark.V03|——|Spark.v03|sparkcore|RDD编程高阶&RDD持久化&缓存|

一、RDD持久化/缓存
### --- 涉及到的算子:persist、cache、unpersist;都是 Transformation

~~~     缓存是将计算结果写入不同的介质,
~~~     用户定义可定义存储级别(存储级别定义了缓存存储的介质,目前支持内存、堆外内存、磁盘);
~~~     通过缓存,Spark避免了RDD上的重复计算,能够极大地提升计算速度;
~~~     RDD持久化或缓存,是Spark最重要的特征之一。
### --- 可以说,缓存是Spark构建迭代式算法和快速交互式查询的关键因素;

~~~     Spark速度非常快的原因之一,就是在内存中持久化(或缓存)一个数据集。
~~~     当持久化一个RDD后,每一个节点都将把计算的分片结果保存在内存中,
~~~     并在对此数据集(或者衍生出的数据集)进行的其他动作(Action)中重用。
### --- 这使得后续的动作变得更加迅速;

~~~     使用persist()方法对一个RDD标记为持久化。
~~~     之所以说“标记为持久化”,是因为出现persist()语句的地方,
~~~     并不会马上计算生成RDD并把它持久化,而是要等到遇到第一个行动操作触发真正计算以后,
~~~     才会把计算结果进行持久化;
二、RDD持久化/缓存执行流程
### --- RDD持久化/缓存

~~~     通过persist()或cache()方法可以标记一个要被持久化的RDD,持久化被触发,
~~~     RDD将会被保留在计算节点的内存中并重用;
~~~     什么时候缓存数据,需要对空间和速度进行权衡。
~~~     一般情况下,如果多个动作需要用到某个 RDD,而它的计算代价又很高,
~~~     那么就应该把这个 RDD 缓存起来;
~~~     缓存有可能丢失,或者存储于内存的数据由于内存不足而被删除。
~~~     RDD的缓存的容错机制保证了即使缓存丢失也能保证计算的正确执行。
~~~     通过基于RDD的一系列的转换,丢失的数据会被重算。
~~~     RDD的各个Partition是相对独立的,因此只需要计算丢失的部分即可,并不需要重算全部Partition。
~~~     persist()的参数可以指定持久化级别参数;
~~~     使用cache()方法时,会调用persist(MEMORY_ONLY),即:
cache() == persist(StorageLevel.1 Memeory_ONLY)
三、源码提取说明
### --- 使用unpersist()方法手动地把持久化的RDD从缓存中移除;

~~~     # 源码提取说明:RDD.scala
~~~     # 199行
   /**
   * Persist this RDD with the default storage level (`MEMORY_ONLY`).
   */
  def persist(): this.type = persist(StorageLevel.MEMORY_ONLY)

  /**
   * Persist this RDD with the default storage level (`MEMORY_ONLY`).
   */
  def cache(): this.type = persist()
~~~     # 源码提取说明:storagelevel.scala
~~~     # 38行

@DeveloperApi
class StorageLevel private(
    private var _useDisk: Boolean,
    private var _useMemory: Boolean,
    private var _useOffHeap: Boolean,
    private var _deserialized: Boolean,
    private var _replication: Int = 1)
~~~     # 源码提取说明:storagelevel.scala
~~~     # 152行

object StorageLevel {
  val NONE = new StorageLevel(false, false, false, false)
  val DISK_ONLY = new StorageLevel(true, false, false, false)
  val DISK_ONLY_2 = new StorageLevel(true, false, false, false, 2)
  val MEMORY_ONLY = new StorageLevel(false, true, false, true)
  val MEMORY_ONLY_2 = new StorageLevel(false, true, false, true, 2)
  val MEMORY_ONLY_SER = new StorageLevel(false, true, false, false)
  val MEMORY_ONLY_SER_2 = new StorageLevel(false, true, false, false, 2)
  val MEMORY_AND_DISK = new StorageLevel(true, true, false, true)
  val MEMORY_AND_DISK_2 = new StorageLevel(true, true, false, true, 2)
  val MEMORY_AND_DISK_SER = new StorageLevel(true, true, false, false)
  val MEMORY_AND_DISK_SER_2 = new StorageLevel(true, true, false, false, 2)
  val OFF_HEAP = new StorageLevel(true, true, true, false, 1)
四、存储级别
存储级别描述
MEMORY_ONLY将RDD 作为反序列化的对象存储JVM 中。如果RDD不能被内存装下,一些分区将不会被缓存,并且在需要的时候被重新计算。 默认的缓存级别
MEMORY_AND_DISK将RDD 作为反序列化的的对象存储在JVM 中。如果RDD不能被与内存装
下,超出的分区将被保存在硬盘上,并且在需要时被读取
MEMORY_ONLY_SER将RDD 作为序列化的的对象进行存储(每一分区一个字节数组)。 通常来说,这比将对象反序列化的空间利用率更高,读取时会比较占用CPU
MEMORY_AND_DISK_SER与MEMORY_ONLY_SER 相似,但是把超出内存的分区将存储在硬盘上而不是在每次需要的时候重新计算
DISK_ONLY只将RDD 分区存储在硬盘上
DISK_ONLY_2等带2的与上述的存储级别一样,但是将每一个分区都复制到集群的两个结点上
五、RDD持久化/缓存
### --- cache RDD 以 分区为单位;程序执行完毕后,系统会清理cache数据;

~~~     # RDD持久化/缓存实验示例
scala> val list = List("Hadoop","Spark","Hive")
list: List[String] = List(Hadoop, Spark, Hive)

scala> val rdd = sc.parallelize(list)
rdd: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[22] at parallelize at <console>:26
~~~     # 调用persist(MEMORY_ONLY)
~~~     # 但语句执行到这里,并不会缓存rdd,因为这时rdd还没有被计算生成

scala> rdd.cache()
res16: rdd.type = ParallelCollectionRDD[22] at parallelize at <console>:26
~~~     # 第一次Action操作,触发一次真正从头到尾的计算
~~~     # 这时才会执行上面的rdd.cache(),将rdd放到缓存中

rdd.count()
~~~     # 第二次Action操作,不需要触发从头到尾的计算
~~~     # 只需要重复使用上面缓存中的rdd

scala> rdd.collect().mkString(",")
res17: String = Hadoop,Spark,Hive
### --- job执行UI:http://hadoop02:4040/jobs/job/?id=8

~~~     被缓存的RDD在DAG图中有一个绿色的圆点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yanqi_vip

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值