在同一个JVM中运行多个Spark任务有哪些好处?

10
不同的来源(例如12)声称Spark 可以从在同一个JVM中运行多个任务中获益。但他们没有解释为什么。
这些好处是什么?
2个回答

6

如前所述,广播变量是一件事。

另一个问题是并发性。看一下这段代码:

var counter = 0
var rdd = sc.parallelize(data)

rdd.foreach(x => counter += x)

println(counter)

无论是在本地执行还是在部署在集群上的Spark(使用不同的JVM)上执行,结果可能会有所不同。在后一种情况下,parallelize方法将计算分配给执行器。闭包(每个节点执行任务所需的环境)被计算,这意味着每个执行器都会收到counter的副本。每个执行器都只能看到自己的变量副本,因此计算结果为0,因为没有一个执行器引用正确的对象。另一方面,在同一个JVM中,counter对于每个工作进程都是可见的。
当然,有一种方法可以避免这种情况——使用Acumulator(请参阅这里)。
最后,在内存中持久化RDD时(默认cache方法的存储级别为MEMORY_ONLY),它将在单个JVM中可见。这也可以通过使用OFF_HEAP来解决(在2.4.0中尝试性实现)。更多信息请点击这里

5

最大的优势是共享内存,特别是处理广播对象。因为这些对象被认为是只读的,所以可以在多个线程之间共享。

在使用单个任务/执行程序的情况下,您需要为每个 JVM 复制一份,因此对于 N 个任务,有 N 个副本。对于大型对象,这可能是一个严重的开销。

相同的逻辑也适用于其他共享对象。


我在这个上下文中看到了广播变量的提及这里。然而,我很难相信这只是关于广播变量的问题。 - Marek Grzenkowicz
1
在同一个JVM中运行的线程能否共享缓存数据(分区)?这可能会优化洗牌,因为单个执行器处理的分区可以在内存中进行洗牌,而无需将它们写入磁盘。但这只是我个人的猜测,我不知道是否可能实现。 - Marek Grzenkowicz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接