Spark之RDD持久化大全

RDD持久化是Spark性能优化的关键,通过缓存数据到内存或磁盘,减少重复计算,提高计算效率。本文详细介绍了RDD持久化的概念、好处、工作原理、使用场景、缓存策略选择以及12种缓存级别,揭示了如何正确运用持久化提升Spark应用性能。
摘要由CSDN通过智能技术生成

什么是持久化?

持久化的意思就是说将RDD的数据缓存到内存中或者持久化到磁盘上,只需要缓存一次,后面对这个RDD做任何计算或者操作,可以直接从缓存中或者磁盘上获得,可以大大加快后续RDD的计算速度。

为什么要持久化?

在之前的文章中讲到Spark中有tranformation和action两类算子,tranformation算子具有lazy特性,只有action算子才会触发job的开始,从而去执行action算子之前定义的tranformation算子,从hdfs中读取数据等,计算完成之后,Spark会将内存中的数据清除,这样处理的好处是避免了OOM问题,但不好之处在于每次job都会从头执行一边,比如从hdfs上读取文件等,如果文件数据量很大,这个过程就会很耗性能。这个问题就涉及到本文要讲的RDD持久化特性,合理的使用RDD持久化对Spark的性能会有很大提升。

持久化带来的好处及原理

Spark可以将RDD持久化在内存中,当对RDD执行持久化操作时,每个节点都会将自己操作的RDD的partition持久化到内存中,并且在之后对该RDD的反复使用中,直接使用内存缓存的partition。这样的话,对于针对一个RDD反复执行多个操作的场景,就只要对RDD读取一次即可,后面直接使用该RDD,而不需要反复计算多次该RDD。

Spark 中一个很重要的能力是将数据持久化(或称为缓存),在多个操作间都可以访问这些持久化的数据。当持久化一个 RDD 时,每个节点的其它分区都可以使用 RDD在内存中进行计算,在该数据上的其他 action 操作将直接使用内存中的数据。这样会让以后的 action 操作计算速度加快(通常运行速度会加速 10倍)。

巧妙使用RDD持久化,甚至在某些场景下,可以将spark应用程序的性能提升10倍。对于迭代式算法和快速交互式应用来说,RDD持久化,是非常重要的。

如果不进行RDD持久化会有哪些影响

假设有一份文件,数据量很大,我们需要对这份文件做聚合操作,功能实现其实很简单,利用下面的代码就可以实现

val lines = sc.textFile("hdfs://spark1:9000/***.txt")
val count = lines.count()

假设对这份文件做聚合操作之后我们又进行了某些操作,后面又需要对lines进行操作,看一下如果不使用RDD持久化会带来哪些问题.

默认情况下,针对大量数据的action操作是很耗时的。Spark应用程序中,如果对某个RDD后面进行了多次transmation或者action操作,那么,可能每次都要重新计算一个RDD,那么就会反复消耗大量的时间,从而降低Spark的性能。第一次统计之后获取到了hdfs文件的字数,但是lines RDD会被丢弃掉,数据也会被新的数据填充,下次执行job的时候需要重新从hdfs上读取文件,不使用RDD持久化可能会导致程序异常的耗时。

  • 一般来说对于大量数据的action操作都是非常耗时的。可能一个操作就耗时1个小时;
  • 在执行action操作的时候,才会触发之前的操作的执行,因此在执行第一次count操作时,就会从hdfs中读取一亿数据,形成lines RDD;
  • 第一次count操作之后,我们的确获取到了hdfs文件的行数。但是lines RDD其实会被丢弃掉,数据也会被新的数据丢失;
  • 所以,如果不用RDD的持久化机制,可能对于相同的RDD的计算需要重复从HDFS源头获取数据进行计算,这样会浪费很多时间成本;
    如下图所示:

持久化带来的好处及工作原理

对lines RDD执行持久化操作之后,虽然第一次统计操作执行完毕,但不会清除掉lines RDD中的数据,会将其缓存在内存中,或者磁盘上。
第二次针对lines RDD执行操作时,此时就不会重新从hdfs中读取数据形成lines RDD,而是会直接从lines RDD所在的所有节点的内存缓存中,直接取出lines RDD的数据,对数据进行操作,那么使用了RDD持久化之后,只有在其第一次计算时才会进行计算,此后针对这个RDD所做的操作,就是针对其缓存了,就不需要多次计算同一个RDD,可以提升Spark程序的性能。
如下图所示:
在这里插入图片描述

RDD持久化的使用场景

RDD持久化虽然可以提高性能,但会消耗内存空间,一般用在如下场景:

  1. 第一次加载大量的数据到RDD中
  2. 频繁的动态更新RDD Cache数据,不适合使用Spark Cache、Spark lineage

如何对RDD进行持久化操作

要持久化一个RDD,只要调用其cache()或者persist()方法即可。在该RDD第一次被计算出来时,就会直接缓存在每个节点中。
而且Spark的持久化机制还是自动容错的,如果持久化的RDD的任何partition丢失了,那么Spark会自动通过其源RDD,使用transformation操作重新计算该partition。

cache()和persist()的区别在于,cache()是persist()的一种简化方式,cache()的底层就是调用的persist()的无参版本,同时就是调用persist(MEMORY_ONLY)ÿ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值