无网络环境下PySpark如何将mmlspark依赖jar添加到类路径
问题根因说明
你之前三次尝试失败的原因分别为:
- 第一个
No main class set报错:使用--jars /path/*时shell会先把通配符展开成所有jar的路径列表,spark-submit会把最后一个路径参数误认为是你的用户应用jar,而不是依赖jar,因此抛出需要指定主类的错误。 - 第二个
ModuleNotFoundError报错:MMLSpark是JVM+Python混合实现的库,你仅配置了JVM端的jar依赖,没有把MMLSpark对应的Python模块加入Python解释器的搜索路径,因此Python端无法导入对应模块。 - 第三种用
--files的方案无效:--files参数的作用是将指定文件分发到每个Executor的工作目录,不会添加到JVM类路径或者Python搜索路径,因此无法加载依赖。
正确离线部署步骤
步骤1:提取MMLSpark的Python模块
MMLSpark的jar包中自带了对应的Python源码,你可以直接从下载的jar包中提取,执行以下命令即可:
cd /home/user/.m2/repository/com/microsoft/ml/spark/mmlspark_2.12/1.0.0-rc3-43-54379bf7-SNAPSHOT/ unzip mmlspark_2.12-1.0.0-rc3-43-54379bf7-SNAPSHOT.jar mmlspark -d /home/user/mmlspark_py_lib
执行完成后/home/user/mmlspark_py_lib路径下就会生成完整的mmlspark Python模块目录。
步骤2:选择对应的依赖加载方案
方案1:提交任务时显式指定依赖(无需修改镜像内置文件)
提交任务时按以下格式构造命令,规避通配符展开问题,同时配置Python搜索路径:
spark-submit \ --jars "$(echo /home/user/jar_files/*.jar | tr ' ' ',')" \ --conf spark.driverEnv.PYTHONPATH="/home/user/mmlspark_py_lib:${PYTHONPATH}" \ --conf spark.executorEnv.PYTHONPATH="/home/user/mmlspark_py_lib:${PYTHONPATH}" \ 你的应用脚本.py [其他业务参数]
这里通过$(echo ... | tr ' ' ',')将所有jar路径拼接为逗号分隔的字符串,避免shell展开通配符后参数识别错误。
方案2:打入镜像全局生效
如果要将依赖打包进Docker镜像,后续无需额外配置即可直接使用,按以下操作:
- 将所有下载的mmlspark相关jar包全部复制到Spark的jars目录,也就是你之前用到的
site-package/pyspark/jars/路径即可。 - 将步骤1提取的
/home/user/mmlspark_py_lib/mmlspark目录,复制到你环境Python的site-packages目录下,或者复制到$SPARK_HOME/python/lib/目录下,Spark启动时会自动将该路径加入Python搜索路径。
配置完成后直接正常执行spark-submit 你的应用脚本.py即可正常加载依赖。
内容的提问来源于stack exchange,提问作者Omniverse10
相关产品推荐
相关产品推荐

