《Spark大数据分析:核心概念、技术及实践》一3.7 缓存

简介:
 本节书摘来自华章出版社《Spark大数据分析:核心概念、技术及实践》一书中的第3章,第3.7节,作者[美] 穆罕默德·古勒(Mohammed Guller),更多章节内容可以访问云栖社区“华章计算机”公众号查看。


3.7 缓存

除了将数据驻留在内存中以外,缓存在RDD中也扮演了另外一个重要的角色。就像之前所说的,创建RDD有两种方式,从存储系统中读取数据或者应用其他现存RDD的转换操作。默认情况下,当一个RDD的操作方法被调用时,Spark会根据它的父RDD来创建这个RDD,这有可能导致父RDD的创建。如此往复,这个过程一直持续到Spark找到根RDD,而后Spark通过从过存储系统读取数据的方式创建根RDD。操作方法被调用一次,上面说的过程就会执行一遍。每次调用操作方法,Spark都会遍历这个调用者RDD的血统树,执行所有的转换操作来创建它。

考虑下面的例子。

0ea2cd16061447b9a7c0ac9870a3164618c5158a 

尽管上面的代码只调用了一次textFile方法,但是日志文件会被从硬盘中读取两次。这是因为调用了两次操作方法count。在调用errorLogs.count时,日志文件第一次被读取,调用warningLogs.count时,日志文件被再次读取。这只是个简单的例子,现实世界中的应用会有更多的各种转换和操作。

如果一个RDD缓存了,Spark会执行到目前为止的所有转换操作并为这个RDD创建一个检查点。具体来说,这只会在第一次在一个缓存的RDD上调用某操作的时候发生。类似于转换方法,缓存方法也是惰性的。

如果一个应用缓存了RDD,Spark并不是立即执行计算并把它存储在内存中。Spark只有在第一次在缓存的RDD上调用某操作的时候才会将RDD物化在内存中。而且这第一次操作并不会从中受益,后续的操作才会从缓存中受益。因为它们不需要再执行从存储系统中读取数据开始的一系列操作。它们通常都运行得快多了。还有,那些只使用一次数据的应用使用缓存也不会有任何好处。只有那些需要对同样数据做多次迭代的应用才能从缓存中受益。

如果一个应用把RDD缓存在内存中,Spark实际上是把它存储在每个worker节点上执行者的内存中了。每个执行者把它所计算的RDD分区缓存在内存中。

3.7.1 RDD的缓存方法

RDD类提供了两种缓存方法:cache和persist。

cache

cache方法把RDD存储在集群中执行者的内存中。它实际上是将RDD物化在内存中。

下面的例子展示了怎么利用缓存优化上面的例子。

ae16ef6f9bc1eefe11217d30d10ec0b10df904e0 

persist

persist是一个通用版的cache方法。它把RDD存储在内存中或者硬盘上或者二者皆有。它的输入参数是存储等级,这是一个可选参数。如果调用persist方法而没有提供参数,那么它的行为类似于cache方法。

2f0a8562030b9dda581f850d5c9cfa86d01db6fc 

persist方法支持下列常见的存储选项。

MEMORY_ONLY:当一个应用把 MEMORY_ONLY作为参数调用persist方法时,Spark会将RDD分区采用反序列化Java对象的方式存储在worker节点的内存中。如果一个RDD分区无法完全载入worker节点的内存中,那么它将在需要时才计算。

088b46f2d600f9647f3c3c6e1374838600a12e12

DISK_ONLY:如果把DISK_ONLY作为参数调用persist方法,Spark会物化RDD分区,把它们存储在每一个worker节点的本地文件系统中。这个参数可以用于缓存中间的RDD,这样接下来的一系列操作就没必要从根RDD开始计算了。

MEMORY_AND_DISK:这种情况下,Spark会尽可能地把RDD分区存储在内存中,如果有剩余,就把剩余的分区存储在硬盘上。

MEMORY_ONLY_SER:这种情况下,Spark会采用序列化Java对象的方式将RDD分区存储在内存中。一个序列化的Java对象会消耗更少的内存,但是读取是CPU密集型的操作。这个参数是在内存消耗和CPU使用之间做的一个妥协。

MEMORY_AND_DISK_SER:Spark会尽可能地以序列化Java对象的方式将RDD分区存储在内存中。如果有剩余,则剩余的分区会存储在硬盘上。

3.7.2 RDD缓存是可容错的

在分布式环境中可容错性是相当重要的。之前我们就已经知道了当节点出故障的时候Spark是怎么自动把计算作业转移到其他节点的。Spark的RDD机制同样也是可容错的。

即使一个缓存RDD的节点出故障了,Spark应用也不会崩溃。Spark会在另外节点上自动重新创建、缓存出故障的节点中存储的分区。Spark利用RDD的血统信息来重新计算丢失的缓存分区。

3.7.3 缓存内存管理

Spark采用LRU算法来自动管理缓存占用的内存。只有在必要时,Spark才会从缓存占用的内存中移除老的RDD分区。而且,RDD还提供了名为unpersist的方法。应用可以调用这个方法来从缓存占用的内存中手动移除RDD分区。

相关文章
|
7天前
|
数据采集 存储 缓存
如何使用缓存技术提升Python爬虫效率
如何使用缓存技术提升Python爬虫效率
|
11天前
|
存储 缓存 负载均衡
从零到一:分布式缓存技术初探
分布式缓存通过将数据存储在多个节点上,利用负载均衡算法提高访问速度、降低数据库负载并增强系统可用性。常见产品有Redis、Memcached等。其优势包括性能扩展、高可用性、负载均衡和容错性,适用于页面缓存、应用对象缓存、状态缓存、并行处理、事件处理及极限事务处理等多种场景。
32 1
|
5月前
|
存储 缓存 Java
Java本地高性能缓存实践问题之如何定义Caffeine的缓存
Java本地高性能缓存实践问题之如何定义Caffeine的缓存
|
2月前
|
缓存 NoSQL Redis
Redis 缓存使用的实践
《Redis缓存最佳实践指南》涵盖缓存更新策略、缓存击穿防护、大key处理和性能优化。包括Cache Aside Pattern、Write Through、分布式锁、大key拆分和批量操作等技术,帮助你在项目中高效使用Redis缓存。
327 22
|
2月前
|
存储 分布式计算 Hadoop
数据湖技术:Hadoop与Spark在大数据处理中的协同作用
【10月更文挑战第27天】在大数据时代,数据湖技术凭借其灵活性和成本效益成为企业存储和分析大规模异构数据的首选。Hadoop和Spark作为数据湖技术的核心组件,通过HDFS存储数据和Spark进行高效计算,实现了数据处理的优化。本文探讨了Hadoop与Spark的最佳实践,包括数据存储、处理、安全和可视化等方面,展示了它们在实际应用中的协同效应。
130 2
|
2月前
|
存储 分布式计算 Hadoop
数据湖技术:Hadoop与Spark在大数据处理中的协同作用
【10月更文挑战第26天】本文详细探讨了Hadoop与Spark在大数据处理中的协同作用,通过具体案例展示了两者的最佳实践。Hadoop的HDFS和MapReduce负责数据存储和预处理,确保高可靠性和容错性;Spark则凭借其高性能和丰富的API,进行深度分析和机器学习,实现高效的批处理和实时处理。
93 1
|
3月前
|
存储 缓存 数据库
缓存技术有哪些应用场景呢
【10月更文挑战第19天】缓存技术有哪些应用场景呢
|
3月前
|
存储 缓存 运维
缓存技术有哪些优缺点呢
【10月更文挑战第19天】缓存技术有哪些优缺点呢
|
3月前
|
存储 缓存 NoSQL
保持HTTP会话状态:缓存策略与实践
保持HTTP会话状态:缓存策略与实践
|
3月前
|
存储 缓存 分布式计算
大数据-89 Spark 集群 RDD 编程-高阶 编写代码、RDD依赖关系、RDD持久化/缓存
大数据-89 Spark 集群 RDD 编程-高阶 编写代码、RDD依赖关系、RDD持久化/缓存
50 4