如何在EMR Serverless中配置LD_LIBRARY_PATH以使用pyodbc?
问题:EMR Serverless运行原生Python脚本时pyodbc依赖缺失报错
我尝试通过EMR Studio在EMR Serverless中直接运行现有原生Python脚本(非Spark)。我们的目标是在EMR Serverless上执行原生Python脚本,为此创建了Python虚拟环境并打包为tar文件“pyspark_ge.tar.gz”,与脚本一同存储在S3中。
但遇到以下错误:
import pyodbc ImportError : libodbc.so.2 : cannot open file: No such file or directory
恳请协助说明如何在Serverless环境中设置LD_LIBRARY_PATH环境变量,或提供其他解决方法?
我们已设置Spark属性,通过--archives使用S3上的tar文件。创建Python环境tar文件的Dockerfile代码片段如下:
FROM --platform=linux/arm64 public.ecr.aws/amazonlinux/amazonlinux:2023-minimal AS base RUN dnf install -y gcc python3 python3-devel ENV VIRTUAL_ENV=/opt/venv RUN python3 -m venv $VIRTUAL_ENV ENV PATH="$VIRTUAL_ENV/bin:$PATH" #Update package lists and install unixodbc without sudo RUN dnf install -y unixODBC-devel ENV LD_LIBRARY_PATH="/usr/lib64:/usr/lib:/usr/local/lib:/usr/lib/x86_64-linux-gnu/:$LD_LIBRARY_PATH" RUN python3 -m pip install --upgrade pip && \ python3 -m pip install \ openpyxl==3.1.2 \ packaging==23.2 \ pandas==2.1.4 \ msal==1.27.0 \ psycopg2-binary==2.9.9 \ py4j==0.10.9.7 \ pyarrow==15.0.2 \ pyodbc==5.1.0 \ venv-pack==0.2.0 RUN mkdir /output && venv-pack -o /output/pyspark_ge.tar.gz FROM scratch AS export COPY --from=base /output/pyspark_ge.tar.gz /
解决方法
方法1:打包虚拟环境时包含系统依赖库
venv-pack仅会打包Python虚拟环境内容,不会自动包含系统级的libodbc.so.2文件,需要手动将相关库复制到虚拟环境目录后再打包:
- 在Dockerfile中添加复制系统库的命令:
# 安装unixODBC后,复制相关库到虚拟环境lib目录 RUN cp /usr/lib64/libodbc.so.2 /usr/lib64/libodbc.so $VIRTUAL_ENV/lib/ - 重新构建镜像并生成tar包,此时tar文件会包含所需的依赖库。
方法2:在EMR Serverless任务中配置LD_LIBRARY_PATH
无需修改打包流程,可在提交任务时通过Spark配置指定环境变量:
- 提交任务时添加以下配置参数:
注:--conf spark.executorEnv.LD_LIBRARY_PATH=./venv/lib:$LD_LIBRARY_PATH --conf spark.driverEnv.LD_LIBRARY_PATH=./venv/lib:$LD_LIBRARY_PATH./venv为虚拟环境解压后的路径,需根据实际情况调整。 - 或在Python脚本开头手动设置:
import os venv_lib_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "venv", "lib") os.environ['LD_LIBRARY_PATH'] = f"{venv_lib_path}:{os.environ.get('LD_LIBRARY_PATH', '')}"
方法3:使用自定义容器镜像运行任务
若依赖关系复杂,直接基于EMR Serverless基础镜像构建自定义镜像更稳定:
- 以EMR Serverless官方基础镜像为基础,在镜像中预先安装
unixODBC及所有Python依赖; - 创建EMR Serverless应用时指定该自定义镜像,任务运行时会直接使用镜像中的依赖环境。
内容的提问来源于stack exchange,提问作者itzmenamita
相关产品推荐
相关产品推荐

