การเรียกใช้หลายพันกระบวนการพื้นหลังขดในแบบคู่ขนานในสคริปต์ทุบตี


14

ฉันกำลังใช้งาน thounsand ของกระบวนการ background curlขนานในสคริปต์ทุบตีต่อไป

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

ฉันมีเซิร์ฟเวอร์เฉพาะ 49Gb Corei7-920 (ไม่ใช่เสมือน)

ฉันติดตามการใช้หน่วยความจำและ CPU ผ่านtopคำสั่งและพวกเขาอยู่ไกลจากขอบเขต

ฉันกำลังใช้ps aux | grep curl | wc -lเพื่อนับจำนวนกระบวนการcurlปัจจุบัน ตัวเลขนี้เพิ่มขึ้นอย่างรวดเร็วมากถึง 2-4 พันจากนั้นเริ่มลดลงอย่างต่อเนื่อง

หากฉันเพิ่มการแยกวิเคราะห์อย่างง่าย ๆ ผ่าน pipl curl ไปยัง awk ( curl | awk > output) กว่ากระบวนการจำนวน curl เพิ่มขึ้นเป็น 1-2 พันจากนั้นลดลงเป็น 20-30 ...

ทำไมจำนวนกระบวนการลดลงอย่างมาก? ขอบเขตของสถาปัตยกรรมนี้อยู่ที่ไหน


2
คุณอาจกดหนึ่งในข้อ จำกัด ของกระบวนการทำงานสูงสุดหรือซ็อกเก็ตเปิดสูงสุด ulimitจะแสดงข้อ จำกัด บางอย่าง
HBruijn

6
ฉันขอแนะนำให้ใช้parallel(1)สำหรับงานดังกล่าว: manpages.debian.org/cgi-bin/…
zhenech

ลองstart=$SECONDSและend=$SECONDS- และใช้ตัวพิมพ์เล็กหรือชื่อตัวแปรตัวพิมพ์เล็กโดยนิสัยเพื่อหลีกเลี่ยงการชนกันของชื่อที่อาจเกิดขึ้นกับตัวแปรเชลล์ อย่างไรก็ตามคุณจะได้รับช่วงเวลาที่เพิ่มมากขึ้นจากการเริ่มต้นของแต่ละกระบวนการเท่านั้น คุณไม่ได้รับระยะเวลาที่ดาวน์โหลดนานเนื่องจากกระบวนการอยู่ในพื้นหลัง (และstartคำนวณเพียงครั้งเดียว) ใน Bash คุณสามารถ(( diff = end - start ))ทิ้งเครื่องหมายดอลลาร์และอนุญาตให้ระยะห่างมีความยืดหยุ่นมากขึ้น ใช้pgrepถ้าคุณมีมัน
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

ฉันเห็นด้วยกับ HBruijn สังเกตว่าการนับกระบวนการของคุณลดลงครึ่งหนึ่งเมื่อคุณเพิ่มจำนวนกระบวนการเป็นสองเท่า (โดยการเพิ่มawk)
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

@zhenech @HBrujin ฉันเปิดตัวparallelและมันบอกว่าฉันอาจทำงานเพียง 500 ขนานเนื่องจากข้อ จำกัด ของระบบในการจัดการไฟล์ ฉันเพิ่มขีด จำกัด ใน limit.conf แต่ตอนนี้เมื่อฉันพยายามรัน 5,000 simulaneus งานมันกินหน่วยความจำทั้งหมดของฉันทันที (49 Gb) ก่อนที่จะเริ่มเพราะทุกparallel สคริปต์ perl กิน 32Mb
zavg

คำตอบ:


12

ทำตามคำถามที่เข้มงวด:

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

สั้นลงถ้าคุณไม่ต้องการข้อความสำเร็จรูปในการกำหนดเวลา:

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

หากคุณต้องการใช้งาน 1,000 ครั้งในแบบคู่ขนานคุณจะมีขีด จำกัด บางอย่าง (เช่นตัวจัดการไฟล์) การเพิ่ม ulimit -n หรือ /etc/security/limits.conf อาจช่วยได้


และถ้าฉันต้องการรันคำสั่งหลายคำในคำตอบสั้น ๆ แบบคู่ขนานฉันจะทำอย่างไร
Guy Avraham

2
seq 100 | parallel 'echo here is command 1: {}; echo here is command 2: {}'พูดมัน ใช้เวลาหนึ่งชั่วโมงในการสอน บรรทัดคำสั่งของคุณจะรักคุณ:man parallel_tutorial
Ole Tange

2
for i in {1..100000}

มีเพียง 65536 พอร์ต เค้นสิ่งนี้

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

(แก้ไข: (แก้ไข: ตัดการยืนยันวันที่อย่างเข้มงวดเกี่ยวกับขีด จำกัด ของระบบปฏิบัติการและเพิ่มการขาดหายไป)echocurl
wait


จริงๆแล้วระบบปฏิบัติการสามารถจัดการกับสิ่งนี้ได้ดี นี่เป็นข้อ จำกัด ของ TCP ไม่มี OS ไม่ว่าจะพิเศษแค่ไหน แต่การเชื่อมต่อ 4k ของ OP ไม่มีที่ไหนเลยใกล้ 64k (หรือค่าเริ่มต้นของ distros 32k)
Patrick

@ แพทริกเอาล่ะฉันเอาส่วนนั้นมามันซ้ำซ้อนกับข้อ จำกัด การออกแบบที่เอาคืนไม่ได้ แต่ดูที่ความคิดเห็นของ zavgเมื่อวันที่ 7
jthill
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.