最近在工作上遇到一個問題,我們的程式碼在 push 上 gitlab 後,CI 會自動的做 unittest 來檢查這次的 changes。同時環境是使用 virtualenv + python3。
用 pip 來管理相依套件不是什麼問題,但放上 CI 後就出現了一個很大的問題,CI 在建構 unittest virtualenv 的環境時,每次會把 workspace 清空,重新建立環境,在這個過程中花費最多的是步驟是在 pip 下載所有需要的套件以及編譯上。以我的狀況為例,整個 pip.require/base 中的套件安裝需要 209 秒的時間,如果在需要編譯套件的 slave 上,那就需要更久的時間。
每次推送後都需要等待過久的時間 (7+ min) 來執行 unittest 實在是忍無可忍,對於開發效率實在影響很大,因此去找了一些加速的方式。
1. 加速套件下載
pip 預設的下載方式是將相依的套件全部重新下載,這可以說是最花時間的一個步驟 (即便你有公司的 pypi server),要避免這個狀況,可以在 pip config file 中設定 cache 的使用。
首先建立這個檔案:
1 |
~/.pip/pip.conf |
接著在裡面加上這些設定:
1 2 |
[global] download–cache=/path/to/your/download–cache |
你可以任意設定 path,通常會直接放在 .pip 之下
1 |
download–cache=~/.pip/download–cache/ |
補充:自 8.0 版開始,已經將 download-cache 給移除,預設已經有 cache。
2. 加速編譯
好的,就算除去了 pip download 的時間,遇到了需要編譯的套件,還是會把整個流程給擋住,這時候可以透過一個套件叫做 pip-accel
來做 binary cache,從而省去編譯套件的時間。
3. 實際運用
在實際的運用上,我們使用 gitlab + jenkins 來做 CI,原始的 job scirpt 如下:
1 2 3 4 5 6 |
virtualenv –p python3 .venv source .venv pip install –r pip.require/base pip install –r pip.require/develop ... |
這時後我們透過 pip-accel,即可以縮減 pip install 的時間:
1 2 3 4 5 6 7 |
virtualenv –p python3 .venv source .venv pip install pip–accel pip–accel install –r pip.require/base pip–accel install –r pip.require/develop ... |
實際狀況測驗,可以讓時間從 209 秒縮減到 6 秒安裝完畢。很好,人生又多了 200 秒可以使用,讚!
Reference:
- John Williams, Build Time Optimization With Pip and Virtualenv, http://roverdotcom.github.io/blog/2014/06/09/build-time-optimization-with-pip-and-virtualenv/
- pip release notes, https://pip.pypa.io/en/stable/news/
Leave a Reply