grpcio、pandas: Installing build dependencies still running 原因及解决方案

内容纲要

问题

file

我在一次使用 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 的意思
  • 平台兼容性标记(重点)(有兴趣的可以参考 PEP425
    • manylinux1_x86_64
      • 它的作用在于区分不同的系统及 CPU 架构(对不同的系统及 CPU 架构,发布不同的 pip wheel 安装包)
      • 这里面有两个信息:manylinux 和 x86_64
        • x86_64 这个比较眼熟,即 CPU 架构(除了 x86_64 外,也可以是 i686)
        • manylinux 目前有 manylinxu1(PEP513)、manylinux2010(PEP571)、manylinux2014(PEP599),对应不同的 pip 版本等信息(详情可以参考 PEP)
          • 区别见 manylinux tag 和 pip version 关系表

manylinux tag 和 pip version 关系表

manylinux tagpip version
manylinux2014pip >= 19.3
manylinux2010pip >= 19.3
manylinux1pip >= 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 镜像的同学,你懂的……😏

Tags: ,

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注