Spark性能优化:清除全部缓存

Spark算子是分为行动子算子和转换算子的,只有遇到行动算子,计算任务才会生成一个Job任务,当算子行动算子多起来,并且交织复杂的时候,Spark去追溯数据血缘就会比较耗时了,通常我们都会直接通过persist算子存储中间的计算结果,减少数据的重复计算。

// 存储中间计算结果,避免Spark重复计算

val frame_model_transformation: DataFrame = model_transformation(spark, jdbcDF, tmp_table, connection)
frame_model_transformation.persist(StorageLevel.MEMORY_AND_DISK)


// 想释放这些缓存时可以通过unpersist算计进行释放
frame_model_transformation.unpersist()

当我们persist算子用多了,或者需要循环处理一些数据时,单个调用unpersist又不太现实(麻烦)

方式一:通过SparkContext
Spark官方是有提供getPersistentRDDs算子去追踪每一个缓存到内存中的RDD的

  • 看看源码
/**
* Returns an immutable map of RDDs that have marked themselves as persistent via cache() call.
*
* @note This does not necessarily mean the caching or computation was successful.
*/
def getPersistentRDDs: Map[Int, RDD[_]] = persistentRdds.toMap




// Keeps track of all persisted RDDs
private[spark] val persistentRdds = {
  val map: ConcurrentMap[Int, RDD[_]] = new MapMaker().weakValues().makeMap[Int, RDD[_]]()
  map.asScala
}

可以看到,返回的是一个Map集合,我们只要循环调用unpersist算子就能实现清除当前状态下的全部缓存了。

val allPersistent: collection.Map[Int, RDD[_]] = spark.sparkContext.getPersistentRDDs
allPersistent.foreach((map: (Int, RDD[_])) => {
  map._2.unpersist()
})

方式二:通过SparkSession
spark自2.X引入了catalog,它支持创建、删除、修改或查询底层数据库、表、函数等。

//构建sparkSession环境
var builder: SparkSession.Builder = SparkSession.builder()
if (isWindow) builder = builder.master("local[8]")

val sparkSession = builder
  .appName("ProcessDataDetail")
  .getOrCreate()

sparkSession.sparkContext.setLogLevel("WARN")

//参数格式: 07 2022-04-01 2022-04-05
val Array(flagCode, startTime, endTime) = args

//获取日期列表
val dateArr = getDayList(startTime, endTime, Calendar.DAY_OF_YEAR)

dateArr.foreach(dateStr => {

  loadBaseData(sparkSession, flagCode, dateStr)

  sparkSession.catalog.clearCache()

})

sparkSession.stop()
posted @ 2024-07-17 10:59  MrSponge  Views(60)  Comments(0Edit  收藏  举报