【问题标题】:Running custom Java class in PySpark在 PySpark 中运行自定义 Java 类
【发布时间】:2016-02-06 06:15:43
【问题描述】:

我正在尝试在 PySpark 中运行自定义 HDFS 阅读器类。这个类是用 Java 编写的,我需要从 PySpark 访问它,无论是从 shell 还是使用 spark-submit。

在 PySpark 中,我从 SparkContext (sc._gateway) 中检索 JavaGateway。

假设我有一堂课:

package org.foo.module

public class Foo {

    public int fooMethod() {
        return 1;
    }

}

我尝试将其打包成一个 jar 并使用 --jar 选项将其传递给 pyspark,然后运行:

from py4j.java_gateway import java_import

jvm = sc._gateway.jvm
java_import(jvm, "org.foo.module.*")

foo = jvm.org.foo.module.Foo()

但我得到了错误:

Py4JError: Trying to call a package.

有人可以帮忙吗?谢谢。

【问题讨论】:

    标签: java python apache-spark pyspark py4j


    【解决方案1】:

    在 PySpark 中尝试以下操作

    from py4j.java_gateway import java_import
    java_import(sc._gateway.jvm,"org.foo.module.Foo")
    
    func = sc._gateway.jvm.Foo()
    func.fooMethod()
    

    确保您已将 Java 代码编译成可运行的 jar 并像这样提交 spark 作业

    spark-submit --driver-class-path "name_of_your_jar_file.jar" --jars "name_of_your_jar_file.jar" name_of_your_python_file.py
    

    【讨论】:

    • 另外,请记住,如果您要添加多个 jar,请确保使用 --driver-class-path 和逗号分隔 --jars 的类路径语法。
    • 添加 --driver-class-path 在 AWS / EMR 中给我带来了很多问题。只需添加 --jars 对我来说就足够了,并且修复了我在将相同的 jar 添加到 --driver-class-path 时看到的大量问题(这破坏了 Hive 和 S3 访问,仅举几例)。
    【解决方案2】:

    您描述的问题通常表明org.foo.module 不在驱动程序类路径中。一种可能的解决方案是使用spark.driver.extraClassPath 添加您的jar 文件。例如,它可以在conf/spark-defaults.conf 中设置或作为命令行参数提供。

    附注:

    • 如果您使用的类是自定义输入格式,则不需要使用 Py4j 网关。您可以简单地使用SparkContext.hadoop* / SparkContext.newAPIHadoop* 方法。

    • 使用java_import(jvm, "org.foo.module.*") 看起来是个坏主意。一般来说,您应该避免在 JVM 上进行不必要的导入。它不公开是有原因的,你真的不想惹它。特别是当您以一种使此导入完全过时的方式访问时。所以放弃java_import 并坚持使用jvm.org.foo.module.Foo()

    【讨论】:

    • 使用类路径选项确实有效,我可以使用 Spark 驱动程序中的类。但是,当我尝试在转换中使用它们时,会出现不同类型的错误。 SparkContext.hadoop* 的选项不适合我的用例。我想并行化一个路径列表,然后进行读取这些文件的转换。
    • 内部转换?这是不可能的(或者至少不使用这种方法)。
    • 如果您不想更改配置文件,也可以通过将其添加为 cmd-line 参数将其添加到类路径中:--driver-class-path
    【解决方案3】:

    如果你在IDE(PyCharm等)本地运行PySpark,要在jar中使用自定义类,你可以将jar放入$SPARK_HOME/jars,它会被添加到运行Spark的类路径,检查代码sn -p 在 $SPARK_HOME/bin/spark-class2.cmd 中了解详细信息。

    【讨论】:

      【解决方案4】:

      而不是--jars,您应该使用--packages 将包导入您的spark-submit 操作。

      【讨论】:

      • 这并不总是正确的。 --packages 搜索 Maven 包。如果用户尝试加载他们自己的 JAR,但该 JAR 不在 Maven 存储库中,--jars 是正确的。
      猜你喜欢
      • 2020-05-08
      • 1970-01-01
      • 1970-01-01
      • 2019-07-28
      • 1970-01-01
      • 2018-05-15
      • 1970-01-01
      • 2015-09-14
      相关资源
      最近更新 更多