我有一个 Spark 应用程序(2.4.5),使用 Kafka 作为源,使用大批量窗口(5 分钟),在我们的应用程序中,我们只真正关心从该特定时间间隔的 RDD 来处理数据。
发生的事情是我们的应用程序不时崩溃,驱动程序上的 OutOfMemory 异常(在客户端模式下运行)或执行程序上的 GC OutOfMemory。经过大量研究,似乎我们没有正确处理状态,导致传承无限增长。我们考虑通过使用批处理方法来解决这个问题,我们控制从 Kafka 获取的偏移量并从中创建 RDD(这会截断谱系)或启用检查点。
在调查过程中,有人发现了一个不太相似的问题,通过调整一些 UI 参数 ( Yarn Heap usage growing over time ) 解决了这个问题:
因为这些是 UI 参数,所以我认为它们会影响应用程序的内存使用是没有意义的,除非它们影响应用程序存储信息以发送到 UI 的方式。早期测试表明,该应用程序确实运行时间更长,没有 OOM 问题。
谁能解释这些参数对应用程序的影响是什么?它们真的能影响应用程序的内存使用吗?是否还有其他参数需要我研究以获取全貌(我想知道是否有一个“因子”参数需要调整以便内存分配适合我们的情况)?
谢谢
最佳答案
经过大量测试,我们的团队设法将问题缩小到这个特定参数:
spark.sql.ui.retainedExecutions
我决定深入研究,所以我下载了 Spark 的代码。我发现有关 Parsed Logical Plan 的信息不仅保存在应用程序的内存中,而且还受此参数控制。
创建 SparkSession session 时,实例化的众多对象之一是 SQLAppStatusListener。这个类实现了两个方法:
onExecutionStart - 在每次执行时,创建一个新的 SparkPlanGraphWrapper,它将保存对解析逻辑计划的引用,并将其添加到一个 SharedState 对象,在这种情况下,该对象跟踪创建了多少个对象实例。
cleanupExecution - 如果存储的对象数量大于 spark.sql.ui.retainedExecutions 的值,则从 SharedState 对象 中删除 SparkPlanGraphWrapper,默认为 1000 。
在我们的例子中,逻辑计划占用了 4MB 的内存,所以以一种简单的方式,我们必须分配 4GB 的内存来容纳保留的执行。
关于apache-spark - spark UI 对应用程序的内存使用有什么影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64469221/