python - PyPI es lento. ¿Cómo ejecuto mi propio servidor?
caching pip (5)
Cuando un nuevo desarrollador se une al equipo, o Jenkins ejecuta una compilación completa, necesito crear un nuevo virtualenv. A menudo encuentro que establecer un virtualenv con Pip y un gran número (más de 10) de requisitos toma mucho tiempo para instalar todo desde PyPI. A menudo falla por completo con:
Downloading/unpacking Django==1.4.5 (from -r requirements.pip (line 1))
Exception:
Traceback (most recent call last):
File "/var/lib/jenkins/jobs/hermes-web/workspace/web/.venv/lib/python2.6/site-packages/pip-1.2.1-py2.6.egg/pip/basecommand.py", line 107, in main
status = self.run(options, args)
File "/var/lib/jenkins/jobs/hermes-web/workspace/web/.venv/lib/python2.6/site-packages/pip-1.2.1-py2.6.egg/pip/commands/install.py", line 256, in run
requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
File "/var/lib/jenkins/jobs/hermes-web/workspace/web/.venv/lib/python2.6/site-packages/pip-1.2.1-py2.6.egg/pip/req.py", line 1018, in prepare_files
self.unpack_url(url, location, self.is_download)
File "/var/lib/jenkins/jobs/hermes-web/workspace/web/.venv/lib/python2.6/site-packages/pip-1.2.1-py2.6.egg/pip/req.py", line 1142, in unpack_url
retval = unpack_http_url(link, location, self.download_cache, self.download_dir)
File "/var/lib/jenkins/jobs/hermes-web/workspace/web/.venv/lib/python2.6/site-packages/pip-1.2.1-py2.6.egg/pip/download.py", line 463, in unpack_http_url
download_hash = _download_url(resp, link, temp_location)
File "/var/lib/jenkins/jobs/hermes-web/workspace/web/.venv/lib/python2.6/site-packages/pip-1.2.1-py2.6.egg/pip/download.py", line 380, in _download_url
chunk = resp.read(4096)
File "/usr/lib64/python2.6/socket.py", line 353, in read
data = self._sock.recv(left)
File "/usr/lib64/python2.6/httplib.py", line 538, in read
s = self.fp.read(amt)
File "/usr/lib64/python2.6/socket.py", line 353, in read
data = self._sock.recv(left)
timeout: timed out
Soy consciente de la bandera de Pip --use-mirrors
, y algunas veces las personas de mi equipo han trabajado utilizando --index-url http://f.pypi.python.org/simple
(u otro espejo) hasta que hayan un espejo que responde de manera oportuna. Estamos en el Reino Unido, pero hay un espejo PyPI en Alemania, y no tenemos problemas para descargar datos de otros sitios.
Por lo tanto, estoy buscando formas de reflejar PyPI internamente para nuestro equipo.
Las opciones que he visto son:
Ejecutando mi propia instancia PyPI. Existe la implementación oficial de PyPI: CheeseShop así como varias implementaciones de terceros, tales como: djangopypi y pypiserver (ver nota al pie)
El problema con este enfoque es que no estoy interesado en la funcionalidad completa de PyPI con la carga de archivos, solo quiero duplicar el contenido que proporciona.
Ejecutando un espejo PyPI con pep381client o pypi-mirror .
Parece que podría funcionar, pero requiere que mi espejo descargue todo desde PyPI primero. Configuré una instancia de prueba de pep381client, pero mi velocidad de descarga varía entre 5 Kb / sy 200 Kb / s (bits, no bytes). A menos que haya una copia del archivo completo de PyPI en algún lugar, me llevará semanas tener un espejo útil.
Usando un proxy de round robin PyPI como yopypi .
Esto es irrelevante ahora que http://pypi.python.org se compone de varios servidores geográficamente distintos .
Copiando un virtualenv entre desarrolladores, o alojando una carpeta de las dependencias del proyecto actual .
Esto no escala: tenemos varios proyectos de Python diferentes cuyas dependencias cambian (lentamente) a lo largo del tiempo. Tan pronto como cambien las dependencias de cualquier proyecto, esta carpeta central debe actualizarse para agregar las nuevas dependencias. Sin embargo, copiar el virtualenv es peor que copiar los paquetes, ya que cualquier paquete Python con módulos C necesita ser compilado para el sistema objetivo. Nuestro equipo tiene usuarios de Linux y OS X.
(Esto todavía se ve como la mejor opción de un grupo malo).
Usando un proxy de caché de PyPI inteligente: collective.eggproxy
Parece que sería una muy buena solución, pero la última versión de PyPI data de 2009 y analiza mod_python.
¿Qué hacen otros equipos grandes de Python? ¿Cuál es la mejor solución para instalar rápidamente el mismo conjunto de paquetes de Python?
Notas al pie:
- He visto la pregunta ¿Cómo rodar mi propia PyPI? , pero esa pregunta se relaciona con el código privado de alojamiento.
- La wiki de Python enumera implementaciones alternativas de PyPI
- Recientemente también descubrí Crate.io pero no creo que eso me ayude cuando uso Pip.
- Hay un sitio web que monitorea el estado del espejo PyPI
- Algunos paquetes en PyPI tienen sus archivos alojados en otro lugar, por lo que incluso un espejo perfecto no ayudará a todas las dependencias
¿Tienes un sistema de archivos compartido?
Porque usaría la configuración de caché de pip. Es bastante simple. Cree una carpeta llamada pip-cache en / mnt por ejemplo.
mkdir /mnt/pip-cache
Entonces cada desarrollador pondría la siguiente línea en su configuración de pip (unix = $ HOME / .pip / pip.conf, win =% HOME% / pip / pip.ini)
[global]
download-cache = /mnt/pip-cache
Todavía revisa PyPi, busca la última versión. Luego verifica si esa versión está en el caché. Si es así, lo instala desde allí. Si no, lo descarga. Lo almacena en la caché y lo instala. Entonces, cada paquete solo se descargaría una vez por cada versión nueva.
Configure su servidor local y luego modifique el archivo de hosts de la computadora local para sobrescribir la URL real en lugar de apuntar al servidor local omitiendo así el DNS estándar. Luego, elimine la línea en el archivo de host si ya terminó.
O supongo que podrías encontrar la URL en pip y modificar eso.
Eche un vistazo al pip2pi de David pip2pi . Puede simplemente configurar un trabajo cron para mantener un espejo de los paquetes que necesita de toda la empresa o equipo, y luego señalar sus puntos hacia su espejo interno.
Recientemente instalé devpi en la configuración de Vagrant de mi equipo de desarrollo de manera que su caché de paquetes viva en el sistema de archivos del host. Esto permite que cada VM tenga su propio daemon devpi-server que usa como la url de índice para virtualenv / pip. Cuando las máquinas virtuales se destruyen y vuelven a aprovisionarse, no es necesario descargar los paquetes una y otra vez. Cada desarrollador los descarga una vez para construir su caché local mientras vivan en el sistema de archivos del host.
También tenemos un índice interno de PyPi para nuestros paquetes privados que actualmente es solo un directorio al que da servicio Apache. En última instancia, voy a convertir eso en un servidor proxy devpi también para que nuestro servidor de compilación también mantenga un caché de paquetes para nuestras dependencias de Python, además de alojar nuestras bibliotecas privadas. Esto creará un búfer adicional entre nuestro entorno de desarrollo, las implementaciones de producción y el PyPi público.
Esta parece ser la solución más sólida que he encontrado para estos requisitos hasta la fecha.
Si bien no resuelve su problema de PyPI, la entrega de virtualenvs creados a los desarrolladores (o implementaciones) se puede hacer con Terrarium .
Use el Terrarium para empaquetar, comprimir y guardar virtualenvs. Puede almacenarlos localmente o incluso almacenarlos en S3 . De la documentación en GitHub:
$ pip install terrarium
$ terrarium --target testenv --storage-dir /mnt/storage install requirements.txt
Después de crear un entorno nuevo, el terrario archivará y comprimirá el entorno y luego lo copiará en la ubicación especificada por el directorio de almacenamiento.
En instalaciones posteriores para el mismo conjunto de requisitos que especifican el mismo directorio de almacenamiento, terrario copiará y extraerá el archivo comprimido de / mnt / storage.
Para mostrar exactamente cómo terrario nombrará el archivo, puede ejecutar el siguiente comando:
$ terrarium key requirements.txt more_requirements.txt
x86_64-2.6-c33a239222ddb1f47fcff08f3ea1b5e1