官方原文:

RDD Persistence

One of the most important capabilities in Spark is persisting (or caching) a dataset in memory across operations. When you persist an RDD, each node stores any partitions of it that it computes in memory and reuses them in other actions on that dataset (or datasets derived from it). This allows future actions to be much faster (often by more than 10x). Caching is a key tool for iterative algorithms and fast interactive use.

You can mark an RDD to be persisted using the persist() or cache() methods on it. The first time it is computed in an action, it will be kept in memory on the nodes. Spark’s cache is fault-tolerant – if any partition of an RDD is lost, it will automatically be recomputed using the transformations that originally created it.

In addition, each persisted RDD can be stored using a different storage level, allowing you, for example, to persist the dataset on disk, persist it in memory but as serialized Java objects (to save space), replicate it across nodes, or store it off-heap in Tachyon. These levels are set by passing aStorageLevel object (ScalaJavaPython) to persist(). The cache() method is a shorthand for using the default storage level, which is StorageLevel.MEMORY_ONLY (store deserialized objects in memory). The full set of storage levels is:

Storage Level Meaning
MEMORY_ONLY Store RDD as deserialized Java objects in the JVM. If the RDD does not fit in memory, some partitions will not be cached and will be recomputed on the fly each time they're needed. This is the default level.
MEMORY_AND_DISK Store RDD as deserialized Java objects in the JVM. If the RDD does not fit in memory, store the partitions that don't fit on disk, and read them from there when they're needed.
MEMORY_ONLY_SER Store RDD as serialized Java objects (one byte array per partition). This is generally more space-efficient than deserialized objects, especially when using a fast serializer, but more CPU-intensive to read.
MEMORY_AND_DISK_SER Similar to MEMORY_ONLY_SER, but spill partitions that don't fit in memory to disk instead of recomputing them on the fly each time they're needed.
DISK_ONLY Store the RDD partitions only on disk.
MEMORY_ONLY_2, MEMORY_AND_DISK_2, etc. Same as the levels above, but replicate each partition on two cluster nodes.
OFF_HEAP (experimental) Store RDD in serialized format in Tachyon. Compared to MEMORY_ONLY_SER, OFF_HEAP reduces garbage collection overhead and allows executors to be smaller and to share a pool of memory, making it attractive in environments with large heaps or multiple concurrent applications. Furthermore, as the RDDs reside in Tachyon, the crash of an executor does not lead to losing the in-memory cache. In this mode, the memory in Tachyon is discardable. Thus, Tachyon does not attempt to reconstruct a block that it evicts from memory. If you plan to use Tachyon as the off heap store, Spark is compatible with Tachyon out-of-the-box. Please refer to this page for the suggested version pairings.

Note: In Python, stored objects will always be serialized with the Pickle library, so it does not matter whether you choose a serialized level.

Spark also automatically persists some intermediate data in shuffle operations (e.g. reduceByKey), even without users calling persist. This is done to avoid recomputing the entire input if a node fails during the shuffle. We still recommend users call persist on the resulting RDD if they plan to reuse it.

Which Storage Level to Choose?

Spark’s storage levels are meant to provide different trade-offs between memory usage and CPU efficiency. We recommend going through the following process to select one:

  • If your RDDs fit comfortably with the default storage level (MEMORY_ONLY), leave them that way. This is the most CPU-efficient option, allowing operations on the RDDs to run as fast as possible.

  • If not, try using MEMORY_ONLY_SER and selecting a fast serialization library to make the objects much more space-efficient, but still reasonably fast to access.

  • Don’t spill to disk unless the functions that computed your datasets are expensive, or they filter a large amount of the data. Otherwise, recomputing a partition may be as fast as reading it from disk.

  • Use the replicated storage levels if you want fast fault recovery (e.g. if using Spark to serve requests from a web application). All the storage levels provide full fault tolerance by recomputing lost data, but the replicated ones let you continue running tasks on the RDD without waiting to recompute a lost partition.

  • In environments with high amounts of memory or multiple applications, the experimental OFF_HEAP mode has several advantages:

    • It allows multiple executors to share the same pool of memory in Tachyon.
    • It significantly reduces garbage collection costs.
    • Cached data is not lost if individual executors crash.

RDD持久性

Spark中最重要的功能之一是跨操作在内存中持久化(或缓存)数据集。当您持久保存RDD时,每个节点都会存储它在内存中计算的任何分区,并在该数据集(或从中派生的数据集)的其他操作中重用它们。这使得未来的行动更快(通常超过10倍)。缓存是迭代算法和快速交互使用的关键工具。

您可以使用persist()cache()方法标记要保留的RDD 。第一次在动作中计算它时,它将保留在节点的内存中。Spark的缓存是容错的 - 如果RDD的任何分区丢失,它将使用最初创建它的转换自动重新计算。

此外,每个持久化RDD可以使用不同的存储级别进行存储,例如,允许您将数据集保留在磁盘上,将其保留在内存中,但作为序列化Java对象(以节省空间),跨节点复制或存储它在Tachyon堆满了。通过传递StorageLevel对象(Scala, Java, Python)来设置这些级别 persist()。该cache()方法是使用默认存储级别的简写,即StorageLevel.MEMORY_ONLY(在内存中存储反序列化的对象)。完整的存储级别是:

存储级别 含义
MEMORY_ONLY 将RDD存储为JVM中的反序列化Java对象。如果RDD不适合内存,则某些分区将不会被缓存,并且每次需要时都会重新计算。这是默认级别。
MEMORY_AND_DISK 将RDD存储为JVM中的反序列化Java对象。如果RDD不适合内存,请存储不适合磁盘的分区,并在需要时从那里读取它们。
MEMORY_ONLY_SER 将RDD存储为序列化 Java对象(每个分区一个字节数组)。这通常比反序列化对象更节省空间,特别是在使用快速序列化器时,但读取CPU密集程度更高。
MEMORY_AND_DISK_SER 与MEMORY_ONLY_SER类似,但将不适合内存的分区溢出到磁盘,而不是每次需要时即时重新计算它们。
DISK_ONLY 仅将RDD分区存储在磁盘上。
MEMORY_ONLY_2,MEMORY_AND_DISK_2等 与上面的级别相同,但复制两个群集节点上的每个分区。
OFF_HEAP(实验性) Tachyon中以序列化格式存储RDD 。与MEMORY_ONLY_SER相比,OFF_HEAP减少了垃圾收集开销,并允许执行器更小并共享内存池,使其在具有大堆或多个并发应用程序的环境中具有吸引力。此外,由于RDD驻留在Tachyon中,执行程序的崩溃不会导致丢失内存缓存。在这种模式下,Tachyon中的内存是可丢弃的。因此,Tachyon不会尝试重建一个从记忆中驱逐的块。如果您打算使用Tachyon作为off堆存储,Spark可以与开箱即用的Tachyon兼容。 有关建议的版本配对,请参阅此页面

注意: 在Python中,存储对象将始终使用Pickle库进行序列化,因此选择序列化级别无关紧要。

reduceByKey即使没有用户调用,Spark也会在shuffle操作(例如)中自动保留一些中间数据persist。这样做是为了避免在shuffle期间节点出现故障时重新计算整个输入。我们仍然建议用户persist在计划重用RDD时调用生成的RDD。

选择哪种存储级别?

Spark的存储级别旨在提供内存使用和CPU效率之间的不同折衷。我们建议您通过以下流程选择一个:

  • 如果您的RDD与默认存储级别(MEMORY_ONLY)保持一致,请保持这种状态。这是CPU效率最高的选项,允许RDD上的操作尽可能快地运行。

  • 如果没有,请尝试使用MEMORY_ONLY_SER选择快速序列化库,以使对象更加节省空间,但仍然可以快速访问。

  • 除非计算数据集的函数很昂贵,否则它们不会溢出到磁盘,或者它们会过滤大量数据。否则,重新计算分区可能与从磁盘读取分区一样快。

  • 如果要快速故障恢复,请使用复制的存储级别(例如,如果使用Spark来处理来自Web应用程序的请求)。所有存储级别通过重新计算丢失的数据提供完全容错,但复制的存储级别允许您继续在RDD上运行任务,而无需等待重新计算丢失的分区。

  • 在具有大量内存或多个应用程序的环境中,实验OFF_HEAP 模式有几个优点:

    • 它允许多个执行程序在Tachyon中共享相同的内存池。
    • 它显着降低了垃圾收集成本。
    • 如果个别执行程序崩溃,缓存数据不会丢失。
package cn.rzlee.spark;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext; /**
* @Author ^_^
* @Create 2018/11/3
*/
public class Persist { public static void main(String[] args) { SparkConf conf = new SparkConf().setAppName("Persist").setMaster("local[2]");
JavaSparkContext sc = new JavaSparkContext(conf); JavaRDD<String> lines = sc.textFile("C:\\Users\\txdyl\\Desktop\\log\\in\\data.txt", 1).cache();
long beginTime = System.currentTimeMillis();
long count = lines.count();
System.out.println(count);
long endTime = System.currentTimeMillis();
System.out.println("cost "+(endTime - beginTime) + "millisecond"); beginTime = System.currentTimeMillis();
count = lines.count();
System.out.println(count);
endTime = System.currentTimeMillis();
System.out.println("cost "+(endTime - beginTime) + "millisecond"); sc.close();
}
}

什么时候进行 cache?

1.要求的计算速度快
2.集群的资源要足够大
3.重要: cache的数据会多次的触发 Action
4.先进行过滤,然后将缩小范围的数据在 cache到内存

//第一个参数,放到磁盘
//第二个参数,放到内存
//第三个参数,磁盘中的数据,不是以java对象的方式保存
//第四个参数,内存中的数据,以java对象的方式保存

val MEMORY_AND_DISK = new StorageLevel(true true, false, true)
0FF_HEAP:堆外内存( Tachyon,分布式内存存储系统)
Alluxio-Open Source Memory Speed Virtual Distributed Storage

cache使用unpersist(true)释放掉缓存在内存中的数据。

什么时候做 checkpoint?

1.迭代计算,要求保证数据安全
2.对速度要求不高(跟 cache到内存进行对比)
3.将中间结果保存到hdfs

步骤:
//设置 checkpoint目录(分布式文件系统的目录hdfs目录)
//经过复杂进行,得到中间结果
//将中间结果 checkpoint到指定的hdfs目录
//后续的计算,就可以使用前面ck的数据了

Spark- RDD持久化的更多相关文章

  1. Spark RDD持久化、广播变量和累加器

    Spark RDD持久化 RDD持久化工作原理 Spark非常重要的一个功能特性就是可以将RDD持久化在内存中.当对RDD执行持久化操作时,每个节点都会将自己操作的RDD的partition持久化到内 ...

  2. spark rdd持久化的简单对比

    未使用rdd持久化 使用后 通过对比可以发现,未使用RDD持久化时,第一次计算比使用RDD持久化要快,但之后的计算显然要慢的多,差不多10倍的样子 代码 public class PersistRDD ...

  3. Spark RDD持久化说明

    以上说明出自林大贵老师关于Hadoop.spark书籍,如有兴趣请自行搜索购买! 这是我的GitHub分享的一些笔记:https://github.com/mahailuo/pyspark_notes

  4. Spark RDD概念学习系列之rdd持久化、广播、累加器(十八)

    1.rdd持久化 2.广播 3.累加器 1.rdd持久化 通过spark-shell,可以快速的验证我们的想法和操作! 启动hdfs集群 spark@SparkSingleNode:/usr/loca ...

  5. 【Spark调优】:RDD持久化策略

    [场景] Spark对RDD执行一系列算子操作时,都会重新从头到尾计算一遍.如果中间结果RDD后续需要被被调用多次,可以显式调用 cache()和 persist(),以告知 Spark,临时保存之前 ...

  6. Spark练习之创建RDD(集合、本地文件),RDD持久化及RDD持久化策略

    Spark练习之创建RDD(集合.本地文件) 一.创建RDD 二.并行化集合创建RDD 2.1 Java并行创建RDD--计算1-10的累加和 2.2 Scala并行创建RDD--计算1-10的累加和 ...

  7. Spark的持久化简记

    摘要: 1.spark 提供的持久化方法 2.Spark的持久化级别 3.如何选择一种最合适的持久化策略 内容: 1.spark 提供的持久化方法 如果要对一个RDD进行持久化,只要对这个RDD调用c ...

  8. Spark RDD

    对RDD的学习进行一下整理 RDD:基于内存的集群计算容错抽象 分布式内存抽象的概念---弹性分布式数据集(RDD),它具备MapReduce等数据流模型的容错特性,并且允许开发人员在大型集群上执行基 ...

  9. spark RDD编程,scala版本

    1.RDD介绍:     RDD,弹性分布式数据集,即分布式的元素集合.在spark中,对所有数据的操作不外乎是创建RDD.转化已有的RDD以及调用RDD操作进行求值.在这一切的背后,Spark会自动 ...

  10. Spark RDD编程核心

    一句话说,在Spark中对数据的操作其实就是对RDD的操作,而对RDD的操作不外乎创建.转换.调用求值. 什么是RDD RDD(Resilient Distributed Dataset),弹性分布式 ...

随机推荐

  1. PHPMailer 使用 中文乱码

    WordPress在用. You'll find plenty more to play with in the examples folder. 中文乱码问题: $mail->CharSet ...

  2. 使用JMeter测试Java项目

    一. Apache JMeter工具 1)简介 JMeter——一个100%的纯Java桌面应用,它是Apache组织的开放源代码项目,它是功能和性能测试的工具.JMeter可以用于测试静态或者动态资 ...

  3. 中国版Office 365混合部署功能

    中国版Office 365混合部署功能已经正式上线了(原计划6月份推出),虽然支持的类型不如国际版的Office 365全面,但这也标志了该功能与之前相比,已经迈出了重要一步.目前中国版Office ...

  4. esper 附录A

    A2 select irstream symbol, volume, price from MarketDate.win.time(5.5 sec) seconds seconds seconds s ...

  5. cg语言的一些术语

    在Cg中,用uniform修饰符声明一个参数表明它的值是由外部的数据源初始化的,而且在给定这批向量的处理中保持不变. Uniform inputs,表示一些与三维渲染有关的离散信息数据,这些数据通常由 ...

  6. Spring MVC的视图解析器

    一.视图解析器简介 在Spring MVC中,当Controller将请求处理结果放入到ModelAndView中以后,DispatcherServlet会根据ModelAndView选择合适的视图进 ...

  7. 注册会计师带你用Python进行探索性风险分析(一)

    https://blog.csdn.net/BF02jgtRS00XKtCx/article/details/78519378

  8. rpc接口和http接口的区别和联系

    1 什么是http接口 http接口是基于http协议的post和get接口. 2 什么是rpc接口 rpc接口就相当于调用本地接口一样调用远程服务的接口. 3 常用的rpc框架 thrift 自动代 ...

  9. CentOS查看和修改MySQL字符集

    通过以下命令查看了MySQL的字符集 连接上mysql服务,输入以下命令 mysql>show variables like 'character_set%'; 显示如下: 为了让MySQL支持 ...

  10. 自定义弹窗 VS AlertDialog分享弹窗

    一.摘要 弹窗通常用于提示用户进行某种操作,比如:点击分享按钮,弹窗分享对话框:双击返回按钮,弹窗退出对话框:下载文件,提示下载对话框等等,分享对话框/退出对话框/下载对话框,都可以直接使用Alert ...