如何添加第三方 Java JAR 文件以在 PySpark 中使用
Posted
技术标签:
【中文标题】如何添加第三方 Java JAR 文件以在 PySpark 中使用【英文标题】:How to add third-party Java JAR files for use in PySpark 【发布时间】:2015-02-26 04:26:14 【问题描述】:我有一些 Java 中的第三方数据库客户端库。我想通过
java_gateway.py
例如:使客户端类(不是 JDBC 驱动程序!)通过 Java 网关对 Python 客户端可用:
java_import(gateway.jvm, "org.mydatabase.MyDBClient")
不清楚将第三方库添加到 JVM 类路径的位置。我试图添加到文件 compute-classpath.sh,但这似乎不起作用。我明白了:
Py4jError: 试图调用一个包
此外,与 Hive 相比:hive JAR 文件不是通过文件 compute-classpath.sh 加载的,所以这让我很怀疑。似乎有一些其他机制正在发生来设置 JVM 端类路径。
【问题讨论】:
【参考方案1】:您可以将外部 jars 作为参数添加到 pyspark
pyspark --jars file1.jar,file2.jar
【讨论】:
目前无法检查 - 但这听起来是正确的。我们遇到的错误实际上与此无关,但无论如何都会使您的答案无效。 注意逗号后面不能有空格!如果您在其中放置空格,它将失败。【参考方案2】:您可以在运行时使用 Spark 配置添加 jar 文件的路径。
这是一个例子:
conf = SparkConf().set("spark.jars", "/path-to-jar/spark-streaming-kafka-0-8-assembly_2.11-2.2.1.jar")
sc = SparkContext( conf=conf)
请参阅document 了解更多信息。
【讨论】:
这是否需要将 jar 上传并部署到驱动程序和工作人员? “/path-to-jar/..”是驱动节点上的路径吗? @justincress 嗨,我将它作为独立集群运行,但我觉得驱动程序是 jar 文件需要存在的地方,因为工作人员/执行程序按照驱动程序的指示进行操作。【参考方案3】:您可以在使用 spark-submit 时添加--jars xxx.jar
./bin/spark-submit --jars xxx.jar your_spark_script.py
或者设置环境变量SPARK_CLASSPATH
SPARK_CLASSPATH='/path/xxx.jar:/path/xx2.jar' your_spark_script.py
your_spark_script.py
由 pyspark API 编写
【讨论】:
@stanislav 感谢您的修改。 我有 spark-1.6.1-bin-hadoop2.6 和 --jars 对我不起作用。第二个选项(设置 SPARK_CLASSPATH)有效。任何人都知道为什么第一个选项不起作用?【参考方案4】:以上所有答案都不适合我
我必须用 pyspark 做的是
pyspark --py-files /path/to/jar/xxxx.jar
对于 Jupyter 笔记本:
spark = (SparkSession
.builder
.appName("Spark_Test")
.master('yarn-client')
.config("spark.sql.warehouse.dir", "/user/hive/warehouse")
.config("spark.executor.cores", "4")
.config("spark.executor.instances", "2")
.config("spark.sql.shuffle.partitions","8")
.enableHiveSupport()
.getOrCreate())
# Do this
spark.sparkContext.addPyFile("/path/to/jar/xxxx.jar")
链接到我找到它的来源: https://github.com/graphframes/graphframes/issues/104
【讨论】:
addPyFile 用于 python 依赖项,而不是 jars spark.apache.org/docs/0.7.2/api/pyspark/…【参考方案5】:-
解压下载的jar文件。
编辑系统环境变量
添加一个名为 SPARK_CLASSPATH 的变量并将其值设置为 \path\to\the\extracted\jar\file。
例如:您已将 C 盘中名为 sparkts 的文件夹中的 jar 文件提取出来 它的值应该是:C:\sparkts
-
重新启动您的集群
【讨论】:
【参考方案6】:除了接受的答案,您还有以下选择:
如果你在虚拟环境中,那么你可以把它放在
例如lib/python3.7/site-packages/pyspark/jars
如果您希望 java 发现它,那么您可以将 jre 的安装位置放在 ext/
目录下
【讨论】:
【参考方案7】:您可以做的另一件事是在安装 pyspark 的 pyspark jar 文件夹中添加 Jar。通常 /python3.6/site-packages/pyspark/jars
如果你使用的是虚拟环境,jar 需要转到虚拟环境中的 pyspark 安装时要小心。
这样您就可以使用 jar 而无需在命令行中发送它或在代码中加载它。
【讨论】:
我在谷歌搜索“将 jar 添加到现有 sparksession”后偶然发现了这里,所以如果这可行,我会很高兴。将在今天晚些时候试用。 是的。将 jar 添加到 jars 目录有效。然后我可以在我的 jar 中调用一个函数,该函数需要一个org.apache.spark.sql.DataFrame
,如下所示:spark._sc._jvm.com.mypackage.MyObject.myFunction(myPySparkDataFrame._jdf)
【参考方案8】:
我已经解决了这个问题,方法是将 jar 放入目录驱动程序,然后在 conf 文件夹中创建 spark-defaults.conf 文件。要遵循的步骤;
To get the conf path:
cd $SPARK_HOME/conf
vi spark-defaults.conf
spark.driver.extraClassPath /Users/xxx/Documents/spark_project/drivers/*
运行您的 Jupyter 笔记本。
【讨论】:
【参考方案9】:来自 pyspark 的 java/scala 库 --jars
和 spark.jars
在 2.4.0 和更早的版本中都不起作用(我没有检查较新的版本)。我很惊讶有多少人声称它有效。
主要问题是类加载器的检索方式如下:
jvm = SparkSession.builder.getOrCreate()._jvm
clazz = jvm.my.scala.class
# or
clazz = jvm.java.lang.Class.forName('my.scala.class')
仅当您将 jar 文件复制到 $SPARK_HOME/jars 时它才有效(这个适用于我)。
但是当您唯一的方法是使用--jars
或spark.jars
时,会在当前线程中设置另一个类加载器(即子类加载器)。所以你的python代码需要看起来像:
clazz = jvm.java.lang.Thread.currentThread().getContextClassLoader().loadClass(f"object_name$")
希望它能解释您的烦恼。如果没有,请大声喊叫。
【讨论】:
以上是关于如何添加第三方 Java JAR 文件以在 PySpark 中使用的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Gradle 将 jar 文件添加到 libgdx 项目