Ejecutar miles de procesos de fondo curl en paralelo en script bash

14

Estoy ejecutando miles de procesos de fondo curl en paralelo en el siguiente script bash

START=$(date +%s)
for i in {1..100000}
do       
    curl -s "http://some_url_here/"$i  > $i.txt&
    END=$(date +%s)
    DIFF=$(( $END - $START ))
    echo "It took $DIFF seconds"
done

Tengo un servidor dedicado Corei7-920 de 49 Gb (no virtual).

Rastreo el consumo de memoria y la CPU a través del topcomando y están lejos de los límites.

Estoy usando ps aux | grep curl | wc -lpara contar la cantidad de procesos de rizo actuales . Este número aumenta rápidamente hasta 2-4 mil y luego comienza a disminuir continuamente.

Si agrego un análisis simple a través de la curvatura de la tubería a awk ( curl | awk > output), el número de procesos de curvatura aumenta a solo 1-2 mil y luego disminuye a 20-30 ...

¿Por qué el número de procesos disminuye tan dramáticamente? ¿Dónde están los límites de esta arquitectura?

zavg
fuente
2
Probablemente esté alcanzando uno de los límites de los procesos de ejecución máxima o los sockets abiertos máximos. ulimitmostrará algunos de esos límites.
HBruijn
66
También sugeriría usar parallel(1)para tales tareas: manpages.debian.org/cgi-bin/…
zhenech
Pruebe start=$SECONDSy end=$SECONDS- y use nombres de variables en minúsculas o en mayúsculas y minúsculas por hábito para evitar una posible colisión de nombres con variables de shell. Sin embargo, en realidad solo está obteniendo el intervalo de tiempo cada vez mayor del inicio de cada proceso. No está obteniendo cuánto tiempo llevó la descarga ya que el proceso está en segundo plano (y startsolo se calcula una vez). En Bash, puede (( diff = end - start ))dejar caer los signos de dólar y permitir que el espacio sea más flexible. Úselo pgrepsi lo tiene.
Pausado hasta nuevo aviso.
Estoy de acuerdo con HBruijn. Observe cómo su recuento de procesos se reduce a la mitad cuando duplica el número de procesos (agregando awk).
Pausado hasta nuevo aviso.
@zhenech @HBrujin Lancé parallely me dice que puedo ejecutar solo 500 tareas paralelas debido al límite del sistema de los identificadores de archivos. Aumenté el límite en limits.conf, pero ahora cuando trato de ejecutar 5000 trabajos simulados, instantáneamente se come toda mi memoria (49 Gb) incluso antes de comenzar porque cada parallel script perl consume 32Mb.
zavg

Respuestas:

12

Siguiendo la pregunta estricta:

mycurl() {
    START=$(date +%s)
    curl -s "http://some_url_here/"$1  > $1.txt
    END=$(date +%s)
    DIFF=$(( $END - $START ))
    echo "It took $DIFF seconds"
}
export -f mycurl

seq 100000 | parallel -j0 mycurl

Más corto si no necesita el texto repetitivo alrededor de los tiempos:

seq 100000 | parallel -j0 --joblog log curl -s http://some_url_here/{} ">" {}.txt
cut -f 4 log

Si desea ejecutar 1000 en paralelo, alcanzará algunos límites (como los identificadores de archivo). Levantar ulimit -n o /etc/security/limits.conf puede ayudar.

Ole Tange
fuente
Y si deseo ejecutar varios comandos como el de la versión de respuesta corta en paralelo, ¿cómo hago eso?
Guy Avraham
2
Citar que: seq 100 | parallel 'echo here is command 1: {}; echo here is command 2: {}'. Pase una hora caminando a través del tutorial. Su línea de comando lo amará por ello:man parallel_tutorial
Ole Tange
2
for i in {1..100000}

Solo hay 65536 puertos. Acelera esto.

for n in {1..100000..1000}; do   # start 100 fetch loops
        for i in `eval echo {$n..$((n+999))}`; do
                echo "club $i..."
                curl -s "http://some_url_here/"$i  > $i.txt
        done &
        wait
done

(editar: (editar: eliminar la afirmación con fecha severa sobre los límites del sistema operativo y agregar los que faltan )echocurl
wait

jthill
fuente
En realidad, el sistema operativo puede manejar esto muy bien. Esta es una limitación de TCP. Ningún sistema operativo, por especial que sea, podrá sortearlo. Pero las conexiones 4k de OP no están cerca de 64k (o el valor predeterminado de 32k de algunas distribuciones)
Patrick
@Patrick está bien, eliminé esa parte, es redundante con un límite de diseño irrecuperable, pero mira el comentario de zavg el día 7.
jthill