我试图用PEX打包一个pyspark作业,以便在谷歌云数据处理器上运行,但我得到了一个Permission Denied
错误。
我已经将第三方和本地依赖项打包到env.pex
中,并将使用这些依赖项的入口点打包到main.py
中,然后将这两个文件gsutil cp
到gs://<PATH>
,并运行下面的脚本。
from google.cloud import dataproc_v1 as dataproc
from google.cloud import storage
def submit_job(project_id: str, region: str, cluster_name: str):
job_client = dataproc.JobControllerClient(
client_options={"api_endpoint": f"{region}-dataproc.googleapis.com:443"}
)
operation = job_client.submit_job_as_operation(
request={
"project_id": project_id,
"region": region,
"job": {
"placement": {"cluster_name": cluster_name},
"pyspark_job": {
"main_python_file_uri": "gs://<PATH>/main.py",
"file_uris": ["gs://<PATH>/env.pex"],
"properties": {
"spark.pyspark.python": "./env.pex",
"spark.executorEnv.PEX_ROOT": "./.pex",
},
},
},
}
)
我得到的错误是
Exception in thread "main" java.io.IOException: Cannot run program "./env.pex": error=13, Permission denied
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at org.apache.spark.deploy.PythonRunner$.main(PythonRunner.scala:97)
at org.apache.spark.deploy.PythonRunner.main(PythonRunner.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.spark.deploy.JavaMainApplication.start(SparkApplication.scala:52)
at org.apache.spark.deploy.SparkSubmit.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:951)
at org.apache.spark.deploy.SparkSubmit.doRunMain$1(SparkSubmit.scala:180)
at org.apache.spark.deploy.SparkSubmit.submit(SparkSubmit.scala:203)
at org.apache.spark.deploy.SparkSubmit.doSubmit(SparkSubmit.scala:90)
at org.apache.spark.deploy.SparkSubmit$$anon$2.doSubmit(SparkSubmit.scala:1039)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:1048)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
Caused by: java.io.IOException: error=13, Permission denied
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
at java.lang.ProcessImpl.start(ProcessImpl.java:134)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 14 more
我应该期望像这样打包我的环境吗?我没有看到一种方法来改变pyspark作业配置中包含的file_uris
文件的权限,我也没有在google云上看到任何关于使用PEX打包的文档,但是PySpark官方文档包含了这个指南。
任何帮助都很感激-谢谢!
3条答案
按热度按时间vxbzzdmp1#
你总是可以使用一个兼容的解释器来运行PEX文件。所以你可以尝试使用
python env.pex
来代替指定./env.pex
的程序。这并不要求env.pex
是可执行的。von4xj4u2#
最后我无法直接运行pex,但现在确实得到了一个变通方案,这是pants slack community中的一个用户建议的(谢谢!)
解决方法是在集群初始化脚本中将pex解压缩为venv。
将初始化脚本gsutil复制到
gs://<PATH TO INIT SCRIPT>
:要启动群集并运行初始化脚本以将pex解压缩到群集上的venv中,请执行以下操作:
要启动作业并使用解压缩的pex venv运行pyspark作业,请执行以下操作:
kg7wmglp3#
下面@megabits的答案是适合我的基于bash的工作流
1.将初始化脚本(从answer)复制到GCS,作为
gs://BUCKET/pkg/cluster-env-init.bash
1.构建PEX,提供初始化脚本所需的
--include-tools
参数,例如1.将PEX文件放入GCS
1.使用PEX文件创建群集以设置环境
1.运行作业