¿La forma más eficiente (tiempo, costo) de raspar 5 millones de páginas web?

8

Tengo una lista de páginas web que necesito para raspar, analizar y luego almacenar los datos resultantes en una base de datos. El total es de alrededor de 5,000,000.

Mi suposición actual de la mejor manera de abordar esto es implementar ~ 100 instancias EC2, proporcionar a cada instancia 50,000 páginas para raspar y luego dejar que se ejecute, luego, una vez que se complete el proceso, combine las bases de datos. La suposición es que tomaría alrededor de un día en ejecutarse (600 ms para cargar, analizar y guardar cada página).

¿Alguien tiene experiencia en hacer un volumen tan grande de raspado de página en un tiempo limitado? He hecho grandes cantidades antes (1,5 m), pero eso fue de una sola máquina y tardé poco más de una semana en completarse.

El cuello de botella en mi situación es la descarga de las páginas, el análisis es algo que no toma más de 2 ms, por lo que algo que puede agilizar el proceso de descarga de las páginas es lo que estoy buscando.

sam
fuente
Cuando dice una lista de páginas web, ¿es solo una página web simple o sitios completos como un foro o algo así? Además, incluso si va de plano, ¿hay reglas establecidas para los sitios que desea raspar (¿o esto es solo la teoría primero?)
tombull89
Tengo varias instancias en las que esta respuesta es relevante para mí, por el bien de la pregunta, di una cifra arbitraria que podría visualizarse fácilmente y el tipo de página web varía, pero para la pregunta se puede suponer que es un foro que se está descartando Si te gusta. Sea o no el sitio permite el raspado es un problema ninguno (para la pregunta de todos modos)
sam
Para aclarar el punto sobre el tipo de páginas web: cada página web es independiente de cualquier otra, se pueden eliminar en cualquier orden y no confiar en que se elimine otra. Podría hacerse hacia adelante, hacia atrás, al azar, eso no importa.
sam
Veo. No sé cómo manejaría EC2 las descargas, pero algunos usuarios más experimentados de SF pueden tener algunas ideas. Además, fuera de tema, pero ¿es este el cítricoquid de los foros de Minecraft? Es un nombre bastante ... único ...
tombull89
mmhmm eso soy yo
sam

Respuestas:

7

Trabajando con la suposición de que el tiempo de descarga (y, por lo tanto, el uso del ancho de banda) es su factor limitante, haría las siguientes sugerencias:

En primer lugar, elija instancias m1.large. De los tres 'niveles' de rendimiento de E / S (que incluye ancho de banda), las instancias m1.large y m1.xlarge ofrecen un rendimiento de E / S 'alto'. Dado que su tarea no está vinculada a la CPU, la opción preferible será la menos costosa.

En segundo lugar, su instancia podrá descargarse mucho más rápido de lo que cualquier sitio puede servir páginas; no descargue una sola página a la vez en una instancia determinada, ejecute la tarea al mismo tiempo; debería poder hacer al menos 20 páginas simultáneamente (aunque , Supongo que probablemente puedas hacer 50-100 sin dificultad). (Tome el ejemplo de la descarga de un foro desde su comentario, que es una página dinámica que le tomará tiempo al servidor generar, y hay otros usuarios que usan el ancho de banda de ese sitio, etc.). Continúe aumentando la concurrencia hasta llegar a los límites del ancho de banda de la instancia. (Por supuesto, no haga múltiples solicitudes simultáneas al mismo sitio).

Si realmente está tratando de maximizar el rendimiento, puede considerar lanzar instancias en zonas geográficamente apropiadas para minimizar la latencia (pero eso requeriría geolocalizar todas sus URL, lo que puede no ser práctico).

Una cosa a tener en cuenta es que el ancho de banda de la instancia es variable, a veces obtendrá un rendimiento más alto y otras veces obtendrá un rendimiento más bajo. En las instancias más pequeñas, la variación en el rendimiento es más importante porque los enlaces físicos son compartidos por más servidores y cualquiera de ellos puede disminuir su ancho de banda disponible. Entre las instancias m1.large, dentro de la red EC2 (misma zona de disponibilidad), debe obtener un rendimiento teórico de gigabits cercano.

En general, con AWS, casi siempre es más eficiente ir con una instancia más grande en lugar de múltiples instancias más pequeñas (a menos que esté buscando específicamente algo como la conmutación por error, etc., donde necesita múltiples instancias).

No sé qué implica su configuración, pero cuando lo intenté anteriormente (entre 1 y 2 millones de enlaces, actualizado periódicamente), mi enfoque fue mantener una base de datos de los enlaces agregando nuevos enlaces a medida que se encontraban, y bifurcando procesos raspar y analizar las páginas. Se recuperaría una URL (al azar) y se marcaría como en progreso en la base de datos, la secuencia de comandos descargaría la página y, si tenía éxito, marcaría la URL como descargada en la base de datos y enviaría el contenido a otra secuencia de comandos que analizara la página, nuevos enlaces fueron agregados a la base de datos a medida que fueron encontrados. La ventaja de la base de datos aquí era la centralización: múltiples scripts podían consultar la base de datos simultáneamente y (siempre y cuando las transacciones fueran atómicas) se podía asegurar que cada página solo se descargaría una vez.

Un par de puntos adicionales de mención: hay límites (creo que 20) en la cantidad de instancias bajo demanda que puede tener ejecutándose al mismo tiempo; si planea exceder esos límites, deberá solicitar AWS para aumentar su cuenta límites Sería mucho más económico para usted ejecutar instancias spot y escalar sus números cuando el precio spot es bajo (tal vez una instancia a pedido para mantener todo organizado y las instancias spot restantes).

Si el tiempo tiene mayor prioridad que el costo para usted, las instancias de cómputo del clúster ofrecen un ancho de banda de 10 Gbps, y deberían producir el mayor ancho de banda de descarga.

Resumen: pruebe algunas instancias grandes (en lugar de muchas instancias pequeñas) y ejecute múltiples descargas simultáneas en cada instancia: agregue más instancias si se encuentra con un ancho de banda limitado, vaya a instancias más grandes si se encuentra limitado a la CPU / memoria.

cyberx86
fuente
4

Intentamos hacer algo similar, y aquí están mis 5 centavos:

  1. Obtenga 2-3 servidores baratos no medidos, por ejemplo, no pague por el ancho de banda.

  2. Utiliza python con asyncore. Asyncore es la forma antigua de hacer las cosas, pero descubrimos que funciona más rápido que cualquier otro método. La desventaja es que la búsqueda de DNS está bloqueando, es decir, no "en paralelo". Usando asyncore logramos raspar URL de 1M durante 40 minutos, usando núcleos XEON 4 individuales, 8 GB de RAM. El promedio de carga en el servidor fue de menos 4 (que es excelente para 4 núcleos).

  3. Si no te gusta el asyncore, prueba gevent. Incluso hace DNS sin bloqueo. Usando gevent, 1M se descargó durante aproximadamente 50 minutos en el mismo hardware. El promedio de carga en el servidor fue enorme.

Tenga en cuenta que probamos muchas bibliotecas de Python, tales grequests, curl, liburl / liburl2, pero no probamos Twisted .

  1. Probamos PHP + curl + varios procesos, hizo el trabajo durante aproximadamente una hora, pero el promedio de carga en el servidor fue enorme.
Mella
fuente
"No medido" generalmente significa "te desconectamos cuando tenemos ganas", en mi experiencia.
ceejayoz
en mi experiencia, "No medido" significa limitado a 100 MBit más o menos
Nick