在PySpark

时间:2015-11-05 12:06:11

标签: java python apache-spark pyspark py4j

我正在尝试在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.

有人可以帮忙吗?感谢。

4 个答案:

答案 0 :(得分:2)

您所描述的问题通常表示org.foo.module不在驱动程序CLASSPATH上。一种可能的解决方案是使用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()

答案 1 :(得分:2)

在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

答案 2 :(得分:0)

而不是--jars您应该使用--packages将包导入spark-submit行动。

答案 3 :(得分:0)

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