Paralleles Ausführen von Tausenden von Curl-Hintergrundprozessen im Bash-Skript

13

Ich führe im folgenden Bash-Skript Tausende von Curl- Hintergrundprozessen parallel aus

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

Ich habe 49 GB Corei7-920 dedizierten Server (nicht virtuell).

Ich verfolge Speicherverbrauch und CPU durch topBefehl und sie sind weit weg von Grenzen.

Ich benutze, ps aux | grep curl | wc -lum die Anzahl der aktuellen Curl- Prozesse zu zählen. Diese Zahl steigt schnell auf 2-4 Tausend an und beginnt dann kontinuierlich abzunehmen.

Wenn ich awk ( curl | awk > output) ein einfaches Parsing durch Pipe-Curl hinzufüge, dann erhöht sich die Anzahl der Curl-Prozesse nur auf 1-2 Tausend und verringert sich dann auf 20-30 ...

Warum sinkt die Anzahl der Prozesse so dramatisch? Wo liegen die Grenzen dieser Architektur?

zavg
quelle
2
Wahrscheinlich stoßen Sie an die Grenzen der maximalen Anzahl laufender Prozesse oder der maximalen Anzahl offener Sockets. ulimitwird einige dieser Grenzen zeigen.
HBruijn
6
Ich würde auch mit vorschlagen parallel(1)für solche Aufgaben: manpages.debian.org/cgi-bin/...
zhenech
Versuchen Sie start=$SECONDSund end=$SECONDS- und verwenden Sie gewohnheitsmäßig klein oder gemischt geschriebene Variablennamen, um mögliche Namenskollisionen mit Shell-Variablen zu vermeiden. In Wirklichkeit erhalten Sie jedoch nur das immer größer werdende Zeitintervall, in dem die einzelnen Prozesse gestartet werden. Sie können nicht feststellen, wie lange der Download gedauert hat, da sich der Vorgang im Hintergrund befindet (und startnur einmal berechnet wird). In Bash können Sie (( diff = end - start ))die Dollarzeichen löschen und den Abstand flexibler gestalten. Verwenden pgrepSie, wenn Sie es haben.
Bis auf weiteres angehalten.
Ich stimme HBruijn zu. Beachten Sie, wie sich Ihre Prozessanzahl halbiert, wenn Sie die Anzahl der Prozesse verdoppeln (durch Hinzufügen awk).
Bis auf weiteres angehalten.
@zhenech @HBrujin Ich habe gestartet parallelund es heißt, dass ich aufgrund der Systembeschränkung der Dateihandles möglicherweise nur 500 parallele Tasks ausführen kann. Ich habe limit in limits.conf erhöht, aber jetzt, wenn ich versuche, 5000 simulaneus-Jobs auszuführen, wird sofort mein ganzer Speicher (49 GB) parallel aufgebraucht, noch bevor ich beginne, da jedes Perl-Skript 32 MB belegt.
Zavg

Antworten:

11

Befolgen Sie die Frage streng:

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

Kürzere, wenn Sie den Text auf dem Kesselschild nicht benötigen:

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

Wenn Sie 1000s parallel ausführen möchten, stoßen Sie an einige Grenzen (z. B. Dateizugriffsnummern). Das Erhöhen von ulimit -n oder /etc/security/limits.conf kann hilfreich sein.

Ole Tange
quelle
Und wenn ich mehrere Befehle wie in der Kurzantwort-Version parallel ausführen möchte, wie mache ich das?
Guy Avraham
2
Zitiere es: seq 100 | parallel 'echo here is command 1: {}; echo here is command 2: {}'. Gehen Sie eine Stunde lang durch das Tutorial. Ihre Kommandozeile wird Sie dafür lieben:man parallel_tutorial
Ole Tange
2
for i in {1..100000}

Es gibt nur 65536 Ports. Drossle das.

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: Streng datierte Behauptung über Betriebssystemgrenzen entfernen und die fehlenden hinzufügen )echocurl
wait

jdoch
quelle
Tatsächlich kann das Betriebssystem damit gut umgehen. Dies ist eine Einschränkung von TCP. Kein Betriebssystem, egal wie speziell, wird es umgehen können. Aber die 4k-Verbindungen von OP sind nicht annähernd 64k (oder der 32k-Standard einiger Distributionen)
Patrick
@Patrick okay, ich habe diesen Teil herausgenommen, er ist überflüssig mit einer unwiederbringlichen Designbeschränkung, aber sieh dir Zavgs Kommentar zum siebten an.
23.