首页 > 代码库 > spark的调优

spark的调优

一、持久化

1、概念

一个RDD,执行多次操作,每次操作都需要计算得到这个RDD,

持久化就是第一次计算的时候,把这个执行多次的RDD持久化到内存或磁盘,这个RDD就只计算一次,以后的多次操作都只需要从内存或磁盘读取这个RDD就可以了

那么我们就不需要多次计算同一个RDD,从而在很多场景下,可以大幅度提升我们spark应用程序的性能

官方文档说,合理使用RDD持久化机制,甚至可以提升spark应用程序的性能,10倍

2、实现持久化的方法

RDD.cache() cache()的底层就是调用了persist()方法的无参版本

RDD.persist(StorageLevel.MEMORY_ONLY) MEMORY_ONLY----持久化的级别

3、持久化级别

spark提供的多种持久化级别,主要是为了在cpu和内存消耗之间进行取舍

(1)、MEMORY_ONLY,persist()方法默认的策略,也是持久化优先选择的策略,如果可以缓存所有数据的话,那么就使用这种策略。因为纯内存速度最快,而且没有序列化,不需要消耗cpu进行反序列化操作。

(2)、MEMORY_ONLY_SER,这种策略如果缓存不了所有数据的话,会进行序列化存储,纯内存操作还是非常快的,只是要消耗cpu进行反序列化

(3)、后缀为_2,这种策略会进行数据的备份,可以进行快速的失败恢复,这样在失败时,就不需要重新计算了

(4)、DISK,持久化到磁盘,能不使用DISK相关的策略,就不用使用,有的时候,从磁盘读取数据,还不如重新计算一次

二、广播变量

1、广播变量的使用场景

如果在rdd中使用了外部变量,那么每个task都会拷贝外部变量的一个副本到executor上去执行。

例如,一个job会产生100个task,这100个task加入都发送到同一个executor上去执行,那么意味着每个task都需要带一个外部变量的副本到executor上执行,如果这个外部变量大小是1G,就意味着总共会有100G的数据通过网络传输到executor上执行,这样会大大

消耗网络流量和浪费executor的内存,降低Spark的运行效率,增加了spark作业的运行时间

2、使用广播变量的优点

如果把外部变量做成广播变量,同样的一个job产生的100个task,发送到executor上执行,此时spark会将这个广播变量保存到每个executor的blockManager中,那么当task执行的时候就不需要从driver上拉取这个外部变量,这样的话会大大降低传输到executor上

的数据(100G--->1G),降低网络传输流量和降低executor的内存消耗

3、广播变量的运行机制

(1)、当executor上的第一个task运行的时候,首先去executor的blockManager上获取这个广播变量,如果不存在,会去邻居的executor的blockManager中获取,如果都获取不到,就会去Driver端拉取这个广播变量,然后将其保存到executor的blockManager中

(2)、当executor在执行之后的task任务时,则直接从executor的blockManager中获取这个广播变量

4、注意

广播变量是只读的,不可进行修改


三、Checkpoint(容错机制)

1、Chcekpoint的原理剖析

(1)、RDD.checkpoint(),对RDD调用checkpoint()方法之后,它就接受RDDCheckpointData对象的管理

(2)、RDDCheckpointData对象,会负责将调用了checkpoint()方法的RDD的状态,设置为MarkedForCheckpoint

(3)、RDD所在job运行结束了,会调用job中,最后一个RDD的doCheckpoint()方法,该方法沿着finalRDD的lineage(RDD血缘关系,依赖链条)向上查找,标记为MarkedForCheckpoint的RDD,并将其标记为CheckpointingInProgress

(4)、启动一个单独的job,来将lineage中,标记为CheckpointingInProgress的RDD,进行checkpoint操作,也就是,将其数据,写入SparkContext.setCheckpointDir()方法设置的文件系统中。

(5)、将RDD的数据进行checkpoint之后,会改变RDD的lineage。也就是说,会清除掉rdd所有的依赖rdd,并强行将其父rdd设置为一个CheckpointRDD,而且RDD状态变成Checkpointed

2、Checkpoint和持久化的区别

(1)、血缘关系

持久化,只是把数据持久化到内存或磁盘中,rdd的血缘关系是不变的。但是checkpoint执行完之后,rdd已经没有之前所谓的依赖rdd了,而只有一个强行为其设置的CheckpointRDD,那么也就是说,checkpoint之后,rdd的lineage就改变了

(2)、数据丢失

持久化的数据丢失的可能性更大,磁盘,或者是内存,可能丢失,但是checkpoint的数据,通常是保存在容错、高可用的文件系统,所以checkpoint的数据丢失的可能性非常低。

spark的调优