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()