Docker环境下Django+Celery+PySpark组合使用时,创建SparkSession抛出SystemExit:1和NoSuchFileException异常
我之前也踩过几乎一模一样的坑!在Docker里用Celery跑PySpark任务创建SparkSession时,worker动不动就突然崩掉,看日志就是SystemExit:1加NoSuchFileException,还有那个NativeCodeLoader的警告,折腾了好一阵才捋清楚几个关键解决方向,给你分享下:
先搞定Spark依赖与环境变量的问题
那个NativeCodeLoader的警告其实已经是明确信号——Spark的本地原生库加载失败了。首先得确保Docker容器里正确设置了SPARK_HOME环境变量,还要把$SPARK_HOME/lib/native路径加到LD_LIBRARY_PATH里。另外,Docker镜像里别忘了装Spark依赖的系统库,比如libc6-dev、libgomp1这些,不然原生库根本跑不起来。还有Java环境必须和PySpark版本匹配,比如PySpark 3.x对应Java 8或11,别乱装新版本,记得在Dockerfile里明确设置JAVA_HOME。避开Celery Fork模式的坑
Celery默认用fork模式启动worker,但SparkSession初始化会加载全局资源,fork后的进程没法正确继承这些资源,甚至会触发Spark的退出逻辑导致SystemExit。最简单的临时解决方法是启动Celery worker时加上--pool=solo参数,用单进程模式运行,虽然性能会受点影响,但能直接绕开fork带来的冲突。如果要兼顾性能,也可以试试在每个Celery任务内部单独创建SparkSession,用完就调用spark.stop()销毁,避免资源残留。解决NoSuchFileException:检查路径与权限
这个异常大概率是Spark找不到临时目录或者没权限写入。可以在创建SparkSession时手动指定临时目录,比如:from pyspark.sql import SparkSession def init_spark(): return SparkSession.builder \ .appName("DjangoCelerySpark") \ .config("spark.local.dir", "/opt/spark-temp") \ .getOrCreate()然后在Dockerfile里提前创建这个目录并设置好权限,比如:
RUN mkdir -p /opt/spark-temp && chown -R celery:celery /opt/spark-temp这里的
celery要换成你实际运行worker的用户,别图省事用777权限,安全第一。额外小提示:SparkSession初始化要延迟
别在Celery任务的全局代码里初始化SparkSession,一定要等到任务执行的时候才创建,不然worker启动时就会触发初始化,很容易因为资源没准备好直接崩掉。
内容来源于stack exchange

