我正在尝试在运行 Spark 作业时使用外部本机库(.so 文件)。首先,我使用提交文件--files
争论。
加载我正在使用的库System.load(SparkFiles.get(libname))
创建后SparkContext
(确保;确定SparkFiles
已填充)。
问题是该库仅由驱动程序节点加载,当任务尝试访问我得到的本机方法时
WARN TaskSetManager: Lost task 0.0 in stage 2.0 (TID 2, 13.0.0.206, executor 0): java.lang.UnsatisfiedLinkError
唯一对我有用的就是复制.so
在运行 Spark 应用程序之前将文件发送给所有工作人员,并创建一个 Scala 对象,该对象将在每个任务之前加载库(可以使用以下命令进行优化)mapPartitions
).
我尝试使用
--conf "spark.executor.extraLibraryPath=/local/path/to/so" \
--conf "spark.driver.extraLibraryPath=/local/path/to/so"
试图避免这种情况,但没有成功。
现在,由于我使用 EMR 来运行 Spark 作业,而不是一致的集群,
我想避免在运行作业之前将文件复制到所有节点。
有什么建议么?
解决方案比我想象的要简单 - 我所需要的只是每个 JVM 加载一次库
所以基本上我需要的是使用添加库文件--files
并创建一个 Loader 对象:
object LibraryLoader {
lazy val load = System.load(SparkFiles.get("libname"))
}
并在每个任务之前使用它(map
, filter
etc.)
例如
rdd.map { x =>
LibraryLoader.load
// do some stuff with x
}
惰性将确保在填充 SparkFiles 后创建对象,并且每个 JVM 进行单一评估。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)