我正在从DStreams Spark应用程序迁移到结构化流应用程序。在测试期间,我发现Spark用户界面的“执行器”选项卡中的存储内存在不断增长。它甚至超过了分配的内存,而不会浪费到磁盘,并且缓存的RDD仅为几MB。我正在使用Spark版本2.4.3,并使用Kafka版本2.1中的数据。
下面的示例显示了一个具有驱动程序和一个执行程序的应用程序。驱动程序分配了3 GB的内存,执行程序分配了5 GB(和3个内核)。
如您所见,UI显示每个进程(执行程序和驱动程序)消耗大约8 GB的内存,而分配的值要小得多。它还表明没有溢出到磁盘。下图还显示了缓存的RDD的大小约为100 MB:
我试图用系统的值来验证UI报告的内存使用情况。我使用了ps命令,该命令显示驱动程序消耗了大约2 GB的内存,而执行程序消耗了5 GB,这在分配的值之内。
我还使用了Spark的REST API来获取执行程序的状态。响应显示“ memoryUsed”值是UI中显示的值。这是JSON响应:
{
"id": "driver",
"hostPort": "ip:41214",
"isActive": true,
"rddBlocks": 0,
"memoryUsed": 7909526598,
"diskUsed": 0,
"totalCores": 0,
"maxTasks": 0,
"activeTasks": 0,
"failedTasks": 0,
"completedTasks": 0,
"totalTasks": 0,
"totalDuration": 0,
"totalGCTime": 0,
"totalInputBytes": 0,
"totalShuffleRead": 0,
"totalShuffleWrite": 0,
"isBlacklisted": false,
"maxMemory": 1529452953,
"addTime": "2019-05-31T14:46:51.563GMT",
"executorLogs": {},
"memoryMetrics": {
"usedOnHeapStorageMemory": 7909526598,
"usedOffHeapStorageMemory": 0,
"totalOnHeapStorageMemory": 1529452953,
"totalOffHeapStorageMemory": 0
},
"blacklistedInStages": []
},
{
"id": "0",
"hostPort": "ip:40787",
"isActive": true,
"rddBlocks": 24,
"memoryUsed": 7996553955,
"diskUsed": 0,
"totalCores": 3,
"maxTasks": 3,
"activeTasks": 0,
"failedTasks": 0,
"completedTasks": 710401,
"totalTasks": 710401,
"totalDuration": 306845440,
"totalGCTime": 8128264,
"totalInputBytes": 733395681216,
"totalShuffleRead": 475652972265,
"totalShuffleWrite": 354298278067,
"isBlacklisted": false,
"maxMemory": 2674812518,
"addTime": "2019-05-31T14:46:53.680GMT",
"executorLogs": {
"stdout": "http://ip:8081/logPage/?appId=app-20190531164651-0027&executorId=0&logType=stdout",
"stderr": "http://ip:8081/logPage/?appId=app-20190531164651-0027&executorId=0&logType=stderr"
},
"memoryMetrics": {
"usedOnHeapStorageMemory": 7996553955,
"usedOffHeapStorageMemory": 0,
"totalOnHeapStorageMemory": 2674812518,
"totalOffHeapStorageMemory": 0
},
"blacklistedInStages": []
}
似乎“ memoryUsed”和“ usedOnHeapStorageMemory”值与用户界面中显示的值相同。
那么,Spark如何显示结构化流的已用内存是否存在错误?报告的值与系统值不一致。
请注意,在我的应用程序中,我对水印和附加模式使用聚合。我认为这可能是问题所在,状态没有正确清理。但是,我使用了query.lastProgress方法来监视流查询的状态,它表明该状态确实已清除。我什至删除了聚合并使用了追加模式,以便查询是无状态的并且行为是相同的。
谢谢。