scala - Spark缓存RDD计算n次
问题描述
我遇到了 Spark 应用程序的问题。这是我的代码的简化版本:
def main(args: Array[String]) {
// Initializing spark context
val sc = new SparkContext()
val nbExecutors = sc.getConf.getInt("spark.executor.instances", 3)
System.setProperty("spark.sql.shuffle.partitions", nbExecutors.toString)
// Getting files from TGZ archives
val archivesRDD: RDD[(String,PortableDataStream)] = utils.getFilesFromHDFSDirectory("/my/dir/*.tar.gz") // This returns an RDD of tuples containing (filename, inpustream)
val filesRDD: RDD[String] = archivesRDD.flatMap(tgzStream => {
logger.debug("Getting files from archive : "+tgzStream._1)
utils.getFilesFromTgzStream(tgzStream._2)
})
// We run the same process with 3 different "modes"
val modes = Seq("mode1", "mode2", "mode3")
// We cache the RDD before
val nb = filesRDD.cache().count()
logger.debug($nb + " files as input")
modes.map(mode => {
logger.debug("Processing files with mode : " + mode)
myProcessor.process(mode, filesRDD)
})
filesRDD.unpersist() // I tried with or without this
[...]
}
生成的日志是(例如以 3 个档案作为输入):
从存档中获取文件:a
从存档中获取文件:b
从存档中获取文件:c
3个文件作为输入
使用模式处理文件:mode1
从存档中获取文件:a
从存档中获取文件:b
从存档中获取文件:c
使用模式处理文件:mode2
从存档中获取文件:a
从存档中获取文件:b
从存档中获取文件:c
使用模式处理文件:mode3
从存档中获取文件:a
从存档中获取文件:b
从存档中获取文件:c
我的 Spark 配置:
- 版本:1.6.2
- 执行器:20 x 2CPU x 8Go RAM
- 每个执行器的纱线开销内存:800Mo
- 驱动程序:1CPU x 8Go RAM
我从这些日志中了解到,文件提取执行了 4 次插入!这显然导致我出现堆空间问题和性能泄漏......
难道我做错了什么 ?
编辑:我也尝试使用modes.foreach(...)
而不是地图,但没有任何改变......
解决方案
好的,经过大量测试,我终于解决了这个问题。实际上有两个问题:
我低估了输入数据的大小:如果 RDD 太大而无法完全存储在总内存的 60% 中,Spark
cache
或函数效率低下,我知道但认为我的输入数据不是那么大,但实际上我的 RDD 是persist
80GB。但是我 60% 的内存(即 160GB)仍然超过 80GB,那么发生了什么?回答第 2 题...我的分区太大:在我的代码中,我的 RDD 的分区数设置为 100,所以我有 100 个分区,每个 1.6GB。问题是我的数据是由几十个兆的字符串组成的,所以我的分区没有满,10GB 的已用内存实际上只包含 7 或 8GB 的真实数据。
为了解决这些问题,我不得不使用persist(StorageLevel.MEMORY_SER)
增加计算时间但显着减少内存使用(根据this benchmark)并将分区号设置为1000(根据Spark文档推荐~128MB的分区)
推荐阅读
- c++ - 使用 libcurl 下载功能,但它工作不完整
- r - 我想在 for 循环中为每次迭代分配和存储一个新值
- python - 如何使用 Chalice 处理 DynamoDB 流事件
- reactjs - Reactjs - 主细节导航 - 回去时主应该在同一个位置
- android - 如何在后台设置警报或通知作为服务并使其即使在应用程序关闭时也能运行
- html - 在 html 中使用太多插槽有哪些性能影响以及如何测试每个插槽的性能?
- php - sqlsrv_has_rows() 返回 FALSE 但有记录 [PHP]
- node.js - Node 与 Docker 中的集群
- mongodb - Mongodb聚合框架性能
- java - (getClass() != obj.getClass()) 对象 obj