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.
fuente
Respuestas:
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.
fuente
Intentamos hacer algo similar, y aquí están mis 5 centavos:
Obtenga 2-3 servidores baratos no medidos, por ejemplo, no pague por el ancho de banda.
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).
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 .
fuente