Before sc.runJob
调用dagScheduler.runJob
,对 rdd 执行的 func 被“清理”为ClosureCleaner.clean
。
为什么 Spark 必须这样做?目的是什么?
Ankur Dave,一位 Spark 提交者,写了一篇Quora 上对 ClosureCleaner 的很好的解释,转载如下:
当 Scala 构造闭包时,它确定闭包将使用哪些外部变量,并将对它们的引用存储在闭包对象中。这使得闭包能够正常工作,即使它是从与创建它的作用域不同的作用域调用的。
Scala 有时会犯错误,会捕获太多外部变量(请参阅SI-1419)。这在大多数情况下是无害的,因为额外捕获的变量根本不会被使用(尽管这可以防止它们被 GC 回收)。但这给 Spark 带来了一个问题,它必须通过网络发送闭包,以便它们可以在从属设备上运行。当闭包包含不必要的引用时,就会浪费网络带宽。更重要的是,某些引用可能指向不可序列化的对象,Spark 将无法序列化闭包。
为了解决 Scala 中的这个错误,瓶盖清洁剂在运行时遍历对象并修剪不必要的引用。由于它在运行时执行此操作,因此它比 Scala 编译器更准确。然后 Spark 可以安全地序列化清理后的闭包。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)