RDD 持久化
原文地址: http://spark.apache.org/docs/latest/programming-guide.html
仅限交流使用,转载请注明出处。如有错误,欢迎指出!
Henvealf/译
Spark中一个很重要的能力就是可以将一个数据集通过操作持久化(或者说缓存)到内存中。实例化每一节点会存储数据集的任何分区的内容,这样其他的 action 就能在内存中重新利用并执行计算。这样就能让之后的 action 操作变得飞快。这也是 迭代逻辑和快速的交互 所使用的关键工具。
使用 persist() 或者 cache() 函数来标记一个 RDD 是持久化的。当这个 RDD 在首次被一个 action 计算后,他就会一直保持在内存中。Spark 的缓存是具有容错能力的,如果 RDD 中的任何分区丢失了,他会重新调用生成该 RDD 的transformations以修复。
另外,每一个持久化的 RDD 能够使用不同的存储水平来持久化。使用 StorageLevel 对象在 persist 上。而 cache() 函数是持久化在内存(StorageLevel.MEMORY_ONLY)的快速写法。
所有的持久化水平如下:
MEMORY_ONLY
MEMORY_AND_DISK
MEMORY_ONLY_SER
(Java and Scala)
MEMORY_AND_DISK_SER
(Java and Scala)
DISK_ONLY
MEMORY_ONLY_2, MEMORY_AND_DISK_2, 等等.
OFF_HEAP (试验中)
注意: 在 Python 中,存储对象总是使用 Pickie 库来进行序列化,所以你不需要忧虑是否使用序列化水平。这样做时为了避免 shuffle 过程失败后重新计算所有的输入。这里建议用户希望重新利用 RDD时 使用 presist()。
选择使用何种水平的存储
Spark 的存储水平的选择需要在 内存使用率 与 CPU效率之间进行衡量选择,这里建议使用下面的流程来选择他:
如果你的 RDDs 能够被内存容纳,就使用 MEMORY_ONLY,会得到很高的 CPU 效率。
如果不是,就使用 MEMORY_ONLY_SER 并选择一个速度快的序列化库,来让对象在足够省空间的同事,能够得到理想的存取速度(Java and Scala)。
除非计算你的数据集的方法开销很大,或者他们会过滤大量的数据,就不要溢写到磁盘中。不然,重新进计算一个分区会和从磁盘中读取的速度一样慢。
如果你想很快的从失败中恢复,就需要使用备份存储。所有的存储水平都会通过重新计算出丢失的数据提供充分的失败容忍力,只有使用备份的时候不需要重新计算。
去除数据
Spark 会自动使用最近最少使用算法来对每个节点上的缓存的使用进行自动的监视。如果你想手动的立刻的去除缓存,就使用 RDD 的 unpersist() 函数。