问题
我在一次使用 Docker 的 Python 镜像升级 grpcio 包的时候,出现了卡在Installing build dependencies still running
非常久的问题,一开始没怎么管(卡就卡,可以喝杯茶慢慢等)。后来出于好奇心(其实上是来自媳妇的泪光闪闪🥺🥺🥺🥺🥺的目光),于是深入的研究了一下,并最终解决了这个问题。
原因
通常我们使用 pip 安装 Python 包的时候,pip 会根据 pip 版本及系统的一些特性去下载对应的 whl 包,比如下面的:grpcio-1.23.0-cp36-cp36m-manylinux1_x86_64.whl
。
root@818026d5c58b:/# pip install grpcio==1.23.0
Collecting grpcio==1.23.0
Downloading https://files.pythonhosted.org/packages/30/31/6397193572c081e0fd1fec86a7a6b7ac497c27226281e7cb32f8c3705069/grpcio-1.23.0-cp36-cp36m-manylinux1_x86_64.whl (2.2MB)
100% |████████████████████████████████| 2.2MB 3.5MB/s
Installing collected packages: grpcio
Successfully installed grpcio-1.23.0
这里面有几个比较重要的信息:
- Python 版本
- cp36
- CPython 3.6 的意思
- cp36
- 平台兼容性标记(重点)(有兴趣的可以参考 PEP425)
manylinux tag 和 pip version 关系表
manylinux tag | pip version |
---|---|
manylinux2014 | pip >= 19.3 |
manylinux2010 | pip >= 19.3 |
manylinux1 | pip >= 8.1.0 |
有一种情况就是,如果 pip 在安装包时,在 pypi 里找不到对应的 Python 版本或平台兼容标记(manylinux)时,pypi 会选择去下载包的源码压缩包进行安装。
比如下面的:我们 Python 是 3.6 版本(cp36),pip 18.1 版本(manylinux1),安装 grpcio 1.31.0 版本,由于在 PyPi 下载源里找不到对应的 wheel 包(grpcio 在早期版本是支持 manylinux1 的,后面就没了,很多包都有同样的问题),就会去下载 grpcio-1.31.0.tar.gz
源码压缩包进行安装。
root@818026d5c58b:/# python -V
Python 3.6.7
root@818026d5c58b:/# pip -V
pip 18.1 from /usr/local/lib/python3.6/site-packages/pip (python 3.6)
root@818026d5c58b:/# pip install grpcio==1.31.0
Collecting grpcio==1.31.0
Downloading https://files.pythonhosted.org/packages/e3/0e/f56aa1f8200ae3c5d38305e69f5920caa480c7ff54ae4d8a5f57d1d69fa4/grpcio-1.31.0.tar.gz (20.0MB)
100% |████████████████████████████████| 20.0MB 366kB/s
Building wheels for collected packages: grpcio
Running setup.py bdist_wheel for grpcio ...
Installing build dependencies still started
Installing build dependencies still running...
Installing build dependencies still running...
Installing build dependencies still running...
...
下载压缩包安装如果是纯 Python 代码,且没有依赖的情况下,速度其实还好,并不会感觉慢,但是如果在一些像 grpcio、pandas 这样的包,包里有很多是 C 代码实现,这就避免不了编译问题,编译本身就需要消耗不少时间,而且如果依赖多的话,时间会更长。这就是导致本文开始提的,卡在 Installing build dependencies still running
很慢的问题的根源(更气人的是,有些依赖如果管理不好的话,会直接导致编译安装失败😂)。
解决思路
- 首先去 PyPi 的包对应的 Download file 页面查询,主要看什么提供了什么 Python 版本、manylinux tag 的 whl 包
- 优先看是否能通过升级 pip 版本来找到对应的 manylinux tag 的包(参考上面的 manylinux tag 和 pip version 关系表)
- 如果不行,在不影响自己的其它业务代码的情况下,可以适当调整 Python 版本或者查找安装包的其它版本,看有没有支持现在 Python 版本的安装包版本(一定要做好测试)
- 都不行的话,可以考虑自己去下载源码编译或者等自动编译完成,去找对应包或者 whl 文件,保存起来,以便下载安装时,直接安装 whl 文件,以加速安装(不是很推荐,有些依赖管理很麻烦,坑很多)
注意
通常情况下,以上方法都能解决。有个更大的坑是:Alpine Linux 发行版,目前不支持 manylinux tag😈,所以看中 Alpine 小,而使用了 Python Alpine 镜像的同学,你懂的……😏
谢谢大牛,解决了
不客气,为人民服务😎
Thank you!!1
You’re welcome.😁