我有一个系统,在Parquet的几个表中存储了250M行数据(和100多列)。系统的设计使得分析人员可以在Spark SQL中编写查询和转换,这些查询将批量执行。系统应该扩展以处理1,000个这样的查询/转换。
独立地,每个查询在Spark上运行得非常好。前几个查询在几秒钟内完成,但随着系统运行,查询开始需要更长时间。查询开始耗时60-90秒,最终整个系统因内存不足错误而崩溃。
Spark是否设计用于处理此类工作负载,如果是这样,我们在设计系统时可以做些什么?
我尝试将中间结果写入HDFS上的Hive表,并在每次查询后使用unpersist
释放RDD。然而,这似乎并没有回收任何记忆。我们可以做些什么来回收正在运行的火花系统的记忆?
我在每次查询后尝试count()
- 强制Spark执行计划,但同样,内存不会被回收。有没有办法对spark查询进行范围调整,确保它已执行并写入结果,然后回收该查询中使用的所有资源?
有没有办法监控内存使用情况?我查看了sparkContext.getExecutorStorageStatus
和sparkContext.getExecutorMemoryStatus
。它们都显示了足够的可用内存(25Gb)。但是,使用top
并查看Ganglia图表,我可以看到它是使用最多内存的hadoop
进程(非常快速地增长到超过50Gb),所以也许这两个访问器在Spark上下文中没有显示内存?
对于如何为长时间运行的火花作业构建系统有任何建议吗?