Exécution de milliers de processus d'arrière-plan curl en parallèle dans le script bash


14

J'exécute des milliers de processus d'arrière-plan curl en parallèle dans le script bash suivant

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

J'ai un serveur dédié 49Gb Corei7-920 (non virtuel).

Je surveille la consommation de mémoire et le processeur via la topcommande et ils sont loin des limites.

J'utilise ps aux | grep curl | wc -lpour compter le nombre de processus de curl actuels . Ce nombre augmente rapidement jusqu'à 2 à 4 milliers, puis commence à diminuer continuellement.

Si j'ajoute une analyse simple à l'aide de la tuyauterie curl à awk ( curl | awk > output), le nombre de processus de boucle augmente jusqu'à 1-2 milliers, puis diminue à 20-30 ...

Pourquoi le nombre de processus diminue-t-il si fortement? Où sont les limites de cette architecture?


2
Vous atteignez probablement l'une des limites du nombre maximal de processus en cours d'exécution ou du nombre maximal de sockets ouverts. ulimitmontrera certaines de ces limites.
HBruijn

6
Je suggère également d'utiliser parallel(1)pour de telles tâches: manpages.debian.org/cgi-bin/…
zhenech

Essayez start=$SECONDSet end=$SECONDS- et utilisez des noms de variables en minuscules ou en casse mixte par habitude afin d'éviter une éventuelle collision de noms avec des variables de shell. Cependant, vous n'obtenez vraiment que l'intervalle de temps sans cesse croissant du démarrage de chaque processus. Vous ne voyez pas combien de temps le téléchargement a pris depuis que le processus est en arrière-plan (et startn'est calculé qu'une seule fois). Dans Bash, vous pouvez (( diff = end - start ))supprimer les signes dollar et permettre un espacement plus flexible. Utilisez pgrepsi vous l'avez.
pause jusqu'à nouvel ordre.

Je suis d'accord avec HBruijn. Remarquez comment votre nombre de processus est divisé par deux lorsque vous doublez le nombre de processus (en ajoutant awk).
pause jusqu'à nouvel ordre.

@zhenech @HBrujin J'ai lancé parallelet il me dit que je peux exécuter seulement 500 tâches parallèles en raison de la limite système des descripteurs de fichiers. J'ai augmenté la limite dans limits.conf, mais maintenant, lorsque j'essaie d'exécuter 5000 travaux simulaneus, il mange instantanément toute ma mémoire (49 Go) avant même de démarrer car chaque parallel script perl mange 32 Mo.
zavg

Réponses:


12

Suite à la question stricte:

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

Plus court si vous n'avez pas besoin du texte passe-partout autour des horaires:

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

Si vous souhaitez exécuter des milliers en parallèle, vous atteindrez certaines limites (telles que les descripteurs de fichiers). Augmenter ulimit -n ou /etc/security/limits.conf peut aider.


Et si je souhaite exécuter plusieurs commandes comme celle de la version à réponse courte en parallèle, comment faire?
Guy Avraham

2
Citer: seq 100 | parallel 'echo here is command 1: {}; echo here is command 2: {}'. Passez une heure à parcourir le didacticiel. Votre ligne de commande vous aimera pour cela:man parallel_tutorial
Ole Tange

2
for i in {1..100000}

Il n'y a que 65536 ports. Limitez cela.

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

(edit: (edit: supprime les assertions sérieusement datées sur les limites du système d'exploitation et ajoute les manquantes )echocurl
wait


En fait, le système d'exploitation peut très bien gérer cela. Il s'agit d'une limitation de TCP. Aucun système d'exploitation, aussi spécial soit-il, ne pourra le contourner. Mais les connexions 4k d'OP sont loin de 64k (ou la valeur par défaut de 32k de certaines distributions)
Patrick

@ Patrick okay, j'ai retiré cette partie, c'est redondant avec une limite de conception irrémédiable, mais regardez le commentaire de zavg le 7.
jthill
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.