Chạy song song hàng ngàn quy trình nền cuộn trong tập lệnh bash


14

Tôi đang chạy song song các quy trình nền curl song song trong tập lệnh bash sau

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

Tôi có máy chủ chuyên dụng 49Gb Corei7-920 (không ảo).

Tôi theo dõi mức tiêu thụ bộ nhớ và CPU thông qua toplệnh và chúng ở rất xa giới hạn.

Tôi đang sử dụng ps aux | grep curl | wc -lđể đếm số lượng các quy trình curl hiện tại . Con số này tăng nhanh lên tới 2-4 nghìn và sau đó bắt đầu giảm liên tục.

Nếu tôi thêm phân tích cú pháp đơn giản thông qua đường ống curl thành awk ( curl | awk > output) thì số quy trình curl tăng lên chỉ còn 1-2 nghìn và sau đó giảm xuống 20-30 ...

Tại sao số lượng quá trình giảm đáng kể? Đâu là giới hạn của kiến ​​trúc này?


2
Bạn có thể đạt một trong những giới hạn của quy trình chạy tối đa hoặc ổ cắm mở tối đa. ulimitsẽ chỉ ra một số giới hạn đó
HBruijn

6
Tôi cũng sẽ đề nghị sử dụng parallel(1)cho các tác vụ như vậy: manpages.debian.org/cgi-bin/
Kẻ

Hãy thử start=$SECONDSend=$SECONDS- và sử dụng các tên biến chữ thường hoặc chữ thường trong trường hợp để tránh xung đột tên tiềm năng với các biến shell. Tuy nhiên, bạn thực sự chỉ nhận được khoảng thời gian ngày càng tăng kể từ khi bắt đầu mỗi quy trình. Bạn sẽ không nhận được quá trình tải xuống mất bao lâu kể từ khi quá trình ở chế độ nền (và startchỉ được tính một lần). Trong Bash, bạn có thể (( diff = end - start ))bỏ các ký hiệu đô la và cho phép khoảng cách linh hoạt hơn. Sử dụng pgrepnếu bạn có nó.
Tạm dừng cho đến khi có thông báo mới.

Tôi đồng ý với HBruijn. Lưu ý cách số lượng quá trình của bạn giảm một nửa khi bạn nhân đôi số lượng quy trình (bằng cách thêm awk).
Tạm dừng cho đến khi có thông báo mới.

@zhenech @HBrujin Tôi đã khởi chạy parallelvà nó nói với tôi rằng tôi có thể chỉ chạy 500 tác vụ song song do giới hạn hệ thống xử lý tệp. Tôi đã tăng giới hạn trong giới hạn. Thông tin, nhưng bây giờ khi tôi cố gắng chạy 5000 công việc simulaneus, nó ngay lập tức ăn hết bộ nhớ của tôi (49 Gb) ngay cả trước khi bắt đầu vì mỗi parallel tập lệnh perl ăn 32Mb.
zavg

Câu trả lời:


12

Theo câu hỏi nghiêm ngặt:

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

Ngắn hơn nếu bạn không cần văn bản soạn sẵn xung quanh thời gian:

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

Nếu bạn muốn chạy 1000 giây song song, bạn sẽ đạt một số giới hạn (chẳng hạn như xử lý tệp). Tăng ulimit -n hoặc /etc/security/limits.conf có thể giúp ích.


Và nếu tôi muốn chạy song song một số lệnh trong phiên bản trả lời ngắn, tôi phải làm thế nào?
Guy Avraham

2
Trích dẫn nó : seq 100 | parallel 'echo here is command 1: {}; echo here is command 2: {}'. Dành một giờ đi bộ qua hướng dẫn. Dòng lệnh của bạn sẽ yêu bạn vì điều đó:man parallel_tutorial
Ole Tange

2
for i in {1..100000}

Chỉ có 65536 cổng. Điều tiết này.

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

(chỉnh sửa: (chỉnh sửa: dải xác nhận ngày nghiêm trọng về giới hạn hệ điều hành và thêm phần còn thiếu )echocurl
wait


Trên thực tế hệ điều hành có thể xử lý việc này tốt. Đây là một hạn chế của TCP. Không có hệ điều hành nào, dù đặc biệt đến đâu, sẽ có thể đi xung quanh nó. Nhưng các kết nối 4k của OP không ở gần 64k (hoặc mặc định 32k của một số bản phát hành)
Patrick

@Patrick không sao, tôi đã lấy phần đó ra, nó thừa với giới hạn thiết kế không thể khắc phục được, nhưng hãy xem nhận xét của zavg về phần 7.
jthill
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.