GCP Dataflow Pipeline抛出UnicodeDecodeError及依赖安装失败排查
解决Kubeflow Pipeline调用Dataflow时的两类依赖问题
我来帮你拆解这两个问题,其实它们是相关联的,而且可以通过调整依赖配置和Dataflow参数来解决:
一、根源问题:rsa==4.0.0的UnicodeDecodeError
你遇到的UnicodeDecodeError确实是rsa 4.0.0版本的已知bug——它的setup.py在读取README文件时没有指定UTF-8编码,而Python 3.6默认会用系统locale的编码(通常是ASCII)来读取文件,导致包含非ASCII字符的内容解码失败。虽然这个bug已经修复,但你还在使用未修复的旧版本。
解决方法:
- 直接升级你的requirements文件中的rsa版本到4.7.0或更高(这是修复该编码问题的首个版本),替换掉
rsa==4.0.0。 - 如果必须使用旧版本,可以在requirements文件中添加临时补丁,或者在Dataflow的worker启动时设置环境变量:
PYTHONIOENCODING=utf-8,强制Python用UTF-8编码读取文件。
二、subprocess.CalledProcessError的关联解决
你看到的pip download命令返回非零状态码1,并不是pip不支持download选项(这个选项一直是pip的标准功能),而是因为rsa 4.0.0的egg_info生成失败(就是上面的UnicodeDecodeError导致的),进而让整个pip download流程中断。
不过,也可以通过调整Dataflow的参数来优化依赖处理:
- 检查你的
requirements.txt路径是否正确:确保{REQUIREMENTS_LOCAL}指向的文件在Kubeflow Pipeline的容器中是可访问的,并且路径没有权限问题。 - 添加
--python_version参数:明确指定worker使用的Python版本(比如--python_version=3.6),避免Dataflow默认使用的版本和你的本地环境不匹配。 - 移除
--no-binary :all:(如果不是必须的):这个参数会强制所有包从源码编译,不仅会增加部署时间,还可能触发更多编码或编译相关的问题。如果你的依赖不需要源码编译,建议去掉这个参数(Dataflow默认会优先使用二进制包)。
三、调整后的Dataflow参数示例
结合上面的建议,你可以更新你的pipeline_args配置:
pipeline_args.extend( [ "--runner=DataflowRunner", "--project={PROJECT_ID}", "--staging_location={STAGE_BUCKET}", "--temp_location={TEMP_BUCKET}", f"--job_name={JOB_NAME}-{str(uuid.uuid4())[:6]}", f"--requirements_file={REQUIREMENTS_LOCAL}", "--region={}".format(REGION), "--python_version=3.6", # 明确指定Python版本 "--worker_env=PYTHONIOENCODING=utf-8", # 强制UTF-8编码 ] )
最后验证步骤
- 更新requirements.txt中的rsa版本到>=4.7.0;
- 测试本地pip download命令:
/usr/bin/python3 -m pip download --dest /tmp/test-cache -r requirements.txt --exists-action i,确认没有报错; - 重新提交Kubeflow Pipeline任务,观察Dataflow的worker日志是否正常。
内容的提问来源于stack exchange,提问作者Claudio Davi
相关产品推荐
相关产品推荐

