Spark性能调优系列:(一)开发调优(将重复使用的RDD进行持久化)

为什么调优?

由于Spark的计算本质是基于内存的,所以Spark性能程序的性能可能因为集群中的任何因素出现瓶颈:CPU、网络带宽、或者是内存。
情况一:内存大能够容纳所有数据,那么网络传输和通信就会导致性能出现瓶颈。
情况二:内存小不能容纳所有数据(10亿级以上数据量),则需要对内存的使用进行性能优化。

调优:将重复使用的RDD进行持久化

Spark单个RDD多次执行原理:每次执行RDD进行算子操作时,都会重新从源头处计算一遍,计算出RDD,再对RDD执行算子操作。

调优建议:

对多次使用的RDD进行持久化,Spark会根据持久化策略将RDD中的数据保存到内存或磁盘中,以后对该RDD进行算子操作时,都是直接从内存或磁盘中提取持久化的RDD数据,然后执行算子。(减少多次计算该RDD)

cache机制:每计算出一个要cache的partition就直接cache到内存。(计算一次)
checkpoint:第一次计算时不会存储,会等job结束后启动专门的job去完成checkpoint。(计算两次)
改进:

使用checkpoint时加上cache,这样第二次运行的job则不再计算该RDD,而是直接读取cache可写入磁盘。

persist:cache则是persist的简化方式,cache底层是调用persist的无参构造器,无参构造器调用的是persist(StorageLevel.MEMORY_ONLY)。

persist的存储级别:

MEMORY_ONLY

默认选项,RDD的(分区)数据直接以Java对象的形式存储于JVM的内存中,如果内存空间不足,某些分区的数据将不会被缓存,需要在使用的时候根据世代信息重新计算。

MYMORY_AND_DISK

RDD的数据直接以Java对象的形式存储于JVM的内存中,如果内存空间不中,某些分区的数据会被存储至磁盘,使用的时候从磁盘读取。

MEMORY_ONLY_SER

RDD的数据(Java对象)序列化之后存储于JVM的内存中(一个分区的数据为内存中的一个字节数组),相比于MEMORY_ONLY能够有效节约内存空间(特别是使用一个快速序列化工具的情况下),但读取数据时需要更多的CPU开销;如果内存空间不足,处理方式与MEMORY_ONLY相同。

MEMORY_AND_DISK_SER

相比于MEMORY_ONLY_SER,在内存空间不足的情况下,将序列化之后的数据存储于磁盘。

DISK_ONLY

仅仅使用磁盘存储RDD的数据(未经序列化)。

MEMORY_ONLY_2,

MEMORY_AND_DISK_2, etc.

以MEMORY_ONLY_2为例,MEMORY_ONLY_2相比于MEMORY_ONLY存储数据的方式是相同的,不同的是会将数据备份到集群中两个不同的节点,其余情况类似。

OFF_HEAP(experimental)

RDD的数据序例化之后存储至Tachyon。相比于MEMORY_ONLY_SER,OFF_HEAP能够减少垃圾回收开销、使得Spark Executor更“小”更“轻”的同时可以共享内存;而且数据存储于Tachyon中,Spark集群节点故障并不会造成数据丢失,因此这种方式在“大”内存或多并发应用的场景下是很有吸引力的。需要注意的是,Tachyon并不直接包含于Spark的体系之内,需要选择合适的版本进行部署;它的数据是以“块”为单位进行管理的,这些块可以根据一定的算法被丢弃,且不会被重建。


cache与checkpoint的区别

rdd.persist(StorageLevel.DISK_ONLY) 与 checkpoint 也有区别。前者虽然可以将 RDD 的 partition 持久化到磁盘,但该 partition 由 blockManager 管理。
一旦 driver program 执行结束,也就是 executor 所在进程 CoarseGrainedExecutorBackend stop,blockManager 也会 stop,被 cache 到磁盘上的 RDD 也会被清空(整个 blockManager 使用的 local 文件夹被删除)。
而 checkpoint 将 RDD 持久化到 HDFS 或本地文件夹,如果不被手动 remove 掉,是一直存在的,也就是说可以被下一个 driver program 使用,而 cached RDD 不能被其他 dirver program 使用。

案例:

package com.kevin.scala.tuning

import org.apache.spark.{SparkConf, SparkContext}

/**
  * 将重复使用的RDD进行持久化
  */
object Persistence {

  def main(args: Array[String]): Unit = {
    val file = "DTSparkCore\\src\\main\\resources\\records.txt"
    // 1.创建SparkConf
    val conf = new SparkConf().setAppName("Persistence").setMaster("local")
    // 2.创建SparkContext
    val sc = new SparkContext(conf)
    // 3.checkpoint持久化的存放路径
    sc.setCheckpointDir("C:\\Users\\caonanqing\\Desktop\\persistence")
    // 4.textFile读取文件数据,flatMap对每行数据初始化次数值为1,以K,V的形式返回,将数据放到缓存
    val rdd = sc.textFile(file).flatMap(value => (List(value,1))).cache()
    // 5.将rdd存储起来
    rdd.checkpoint()
    // 6.cache和checkpoint都是转换算子,需要执行算子来执行该操作
    rdd.collect()
    println("isCheckPointed: "+rdd.isCheckpointed)
    println("checkpoint: "+rdd.getCheckpointFile)
    // 7.关闭
    sc.stop()

  }

}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值