Apa yang terjadi jika saya memulai terlalu banyak pekerjaan latar belakang?

13

Saya perlu melakukan beberapa pekerjaan pada 700 perangkat jaringan menggunakan skrip harapan. Saya bisa menyelesaikannya secara berurutan, tetapi sejauh ini runtime sekitar 24 jam. Ini sebagian besar disebabkan oleh waktu yang diperlukan untuk membuat koneksi dan keterlambatan dalam output dari perangkat ini (yang lama). Saya dapat membuat dua koneksi dan menjalankannya secara paralel dengan baik, tetapi seberapa jauh saya bisa mendorongnya?

Saya tidak membayangkan saya bisa melakukan 700 semuanya sekaligus, pasti ada batasan untuk tidak. koneksi telnet yang dapat dikelola VM saya.

Jika saya memang mencoba memulai 700 di antaranya dalam semacam lingkaran seperti ini:

for node in `ls ~/sagLogs/`; do  
    foo &  
done

Dengan

  • CPU 12 CPU x Intel (R) Xeon (R) CPU E5649 @ 2.53GHz

  • Memori 47,94 GB

Pertanyaanku adalah:

  1. Mungkinkah ke-700 instance tersebut dapat berjalan secara bersamaan?
  2. Seberapa jauh saya bisa sampai server saya mencapai batasnya?
  3. Ketika batas itu tercapai, apakah hanya menunggu untuk memulai iterasi berikutnya fooatau akankah kotak macet?

Sayangnya, saya menjalankan dalam lingkungan produksi perusahaan, jadi saya tidak dapat benar-benar mencoba dan melihat apa yang terjadi.

KuboMD
sumber
3
Saya sudah beruntung parallel, menggunakan sekitar 50 pekerjaan bersamaan. Ini adalah media yang bagus antara paralelisme 1 dan 700. Yang menyenangkan lainnya adalah batchless. Satu koneksi yang terhenti hanya akan terhenti dengan sendirinya, bukan yang lain. Kelemahan utama adalah manajemen kesalahan. Tidak satu pun dari pendekatan berbasis shell ini yang dapat menangani kesalahan dengan anggun. Anda harus memeriksa sendiri keberhasilannya secara manual, dan lakukan percobaan sendiri.
Adam
1
Antrian tugas Anda mungkin 700 hari ini, tetapi bisakah ukurannya diperluas? Perhatikan ruang swap untuk tumbuh - itu menandakan Anda telah mencapai batas memori. Dan cpu% bukan ukuran yang baik (untuk linux / unix), lebih baik untuk mempertimbangkan rata-rata beban (jalankan panjang antrian).
ChuckCottrill
1
Cara terbaru saya memecah produksi di pekerjaan saya yang masih-agak-baru adalah dengan secara tidak sengaja menjalankan satu juta pekerjaan latar belakang yang berumur pendek sekaligus. Mereka melibatkan JVM (tunggu tunggu, letakkan garpu rumput), sehingga konsekuensinya 'terbatas' pada ratusan ribu file laporan kesalahan yang utasnya tidak dapat dimulai.
michaelb958 - GoFundMonica
4
Nitpick: Jangan parse lsoutput
l0b0
1
@KuboMD Dan selama tidak ada orang lain yang ingin menggunakan kode Anda.
l0b0

Jawaban:

17

Mungkinkah ke-700 instance tersebut dapat berjalan secara bersamaan?

Itu tergantung pada apa yang Anda maksudkan secara bersamaan. Jika kita pilih-pilih, maka tidak, mereka tidak bisa kecuali Anda memiliki 700 utas eksekusi pada sistem Anda yang dapat Anda manfaatkan (jadi mungkin tidak). Secara realistis, ya, mereka mungkin bisa, asalkan Anda memiliki cukup RAM dan / atau ruang swap pada sistem. UNIX dan beragam anak-anak sangat pandai mengelola tingkat konkurensi yang sangat besar, itulah sebabnya mereka sangat populer untuk penggunaan HPC skala besar.

Seberapa jauh saya bisa sampai server saya mencapai batasnya?

Ini tidak mungkin untuk menjawab secara konkret tanpa info lebih lanjut. Cukup banyak, Anda perlu memiliki cukup memori untuk bertemu:

  • Seluruh persyaratan run-time memory dari satu pekerjaan, kali 700.
  • Persyaratan memori bash untuk mengelola banyak pekerjaan itu (bash tidak mengerikan tentang hal ini, tetapi kontrol pekerjaan tidak sepenuhnya efisien dalam memori).
  • Persyaratan memori lain pada sistem.

Dengan asumsi Anda memenuhi itu (sekali lagi, dengan hanya 50GB RAM, Anda masih harus berurusan dengan masalah lain:

  • Berapa banyak waktu CPU yang akan terbuang oleh bash pada kontrol pekerjaan? Mungkin tidak banyak, tetapi dengan ratusan pekerjaan, itu bisa jadi signifikan.
  • Berapa banyak bandwidth jaringan yang dibutuhkan? Hanya dengan membuka semua koneksi itu dapat membanjiri jaringan Anda selama beberapa menit tergantung pada bandwidth dan latensi Anda.
  • Banyak hal lain yang mungkin belum saya pikirkan.

Ketika batas itu tercapai, apakah hanya menunggu untuk memulai iterasi berikutnya dari foo atau kotak akan crash?

Itu tergantung pada batas apa yang kena. Jika memori, sesuatu akan mati pada sistem (lebih khusus, terbunuh oleh kernel dalam upaya untuk membebaskan memori) atau sistem itu sendiri dapat crash (itu tidak biasa untuk mengkonfigurasi sistem untuk sengaja crash ketika kehabisan memori). Jika waktu CPU, itu hanya akan terus tanpa masalah, itu tidak mungkin untuk melakukan banyak hal lain pada sistem. Jika itu meskipun jaringan, Anda mungkin crash lainnya sistem atau jasa.


Apa yang benar - benar Anda butuhkan di sini bukan untuk menjalankan semua pekerjaan pada saat yang sama. Alih-alih, bagi menjadi beberapa kelompok, dan jalankan semua pekerjaan dalam satu batch pada saat yang bersamaan, biarkan selesai, kemudian mulai batch berikutnya. GNU Parallel ( https://www.gnu.org/software/parallel/ ) dapat digunakan untuk ini, tetapi kurang ideal pada skala itu dalam lingkungan produksi (jika Anda menggunakannya, jangan terlalu agresif, seperti yang saya katakan, Anda mungkin membanjiri jaringan dan memengaruhi sistem yang tidak akan Anda sentuh). Saya benar-benar akan merekomendasikan melihat ke alat orkestrasi jaringan yang tepat seperti Ansible ( https://www.ansible.com/), karena itu tidak hanya akan menyelesaikan masalah konkurensi Anda (Anonim tidak batching seperti yang saya sebutkan di atas secara otomatis), tetapi juga memberi Anda banyak fitur berguna lainnya untuk bekerja dengan (seperti pelaksanaan tugas idempoten, laporan status yang bagus, dan integrasi asli dengan sejumlah besar alat lainnya).

Austin Hemmelgarn
sumber
Ada beberapa cara untuk menjalankan tugas latar belakang dalam jumlah terbatas (menggunakan bash, perl, python, dkk), memantau penyelesaian tugas, dan menjalankan lebih banyak tugas saat tugas sebelumnya selesai. Pendekatan sederhana adalah mengumpulkan kumpulan tugas yang diwakili oleh file dalam subdirektori, dan memproses batch sekaligus. Ada cara lain ...
ChuckCottrill
Apakah ini juga termasuk sistem unix-like? Dan apa itu "paralel GUN"?
Biswapriyo
2
@ ChuckCottrill Ya, memang ada cara lain yang bisa dilakukan. Mengingat pengalaman saya sendiri dalam menangani hal semacam ini, hampir selalu lebih baik untuk hanya mendapatkan alat orkestrasi yang nyata daripada mencoba dan memutar solusi Anda sendiri, terutama sekali Anda melewati beberapa lusin sistem dalam hal skala.
Austin Hemmelgarn
3
@forest Ya, Anda bisa menggunakan rlimits untuk mencegah sistem crash, tetapi melakukannya dengan benar dalam kasus seperti ini tidak mudah (Anda perlu tahu apa persyaratan sumber daya untuk tugas-tugas sebelumnya) dan tidak melindungi sisa jaringan dari dampak apa pun yang disebabkan oleh pekerjaan ini (yang bisa dibilang berpotensi masalah yang lebih besar daripada menabrak sistem lokal).
Austin Hemmelgarn
12

Sulit untuk mengatakan secara spesifik berapa banyak instance dapat dijalankan sebagai pekerjaan latar belakang dengan cara yang Anda gambarkan. Tetapi server normal tentu dapat mempertahankan 700 koneksi bersamaan selama Anda melakukannya dengan benar. Pengamat web melakukan ini sepanjang waktu.

Bolehkah saya menyarankan agar Anda menggunakan GNU parallel ( https://www.gnu.org/software/parallel/ ) atau yang serupa dengan ini? Ini akan memberi Anda sejumlah keuntungan dengan pendekatan pekerjaan latar belakang:

  • Anda dapat dengan mudah mengubah jumlah sesi bersamaan.
  • Dan itu akan menunggu sampai sesi selesai sebelum memulai yang baru.
  • Lebih mudah untuk dibatalkan.

Lihat di sini untuk memulai lebih cepat: https://www.gnu.org/software/parallel/parallel_tutorial.html#A-single-input-source

laenkeio
sumber
1
Menarik! Saya akan lihat ini. Apakah Anda tahu jika mencoba operasi semacam ini (tanpa bantuan Paralel) akan berisiko menabrak hypervisor?
KuboMD
2
@KuboMD jika Anda dapat menabrak hypervisor dengan sesuatu yang begitu biasa, itu adalah bug di hypervisor :)
hobbs
di samping itu, server web sering menggunakan pemrosesan berbasis threading atau peristiwa (contoh: gunicorn.org )
ChuckCottrill
10

Menggunakan &untuk pemrosesan paralel baik-baik saja ketika melakukan beberapa, dan ketika Anda memantau kemajuan. Tetapi jika Anda menjalankan dalam lingkungan produksi perusahaan Anda memerlukan sesuatu yang memberi Anda kontrol yang lebih baik.

ls ~/sagLogs/ | parallel --delay 0.5 --memfree 1G -j0 --joblog my.log --retries 10 foo {}

Ini akan berjalan foountuk setiap file di ~/sagLogs. Ini memulai pekerjaan setiap 0,5 detik, itu akan menjalankan banyak pekerjaan secara paralel mungkin selama RAM 1 GB gratis, tetapi akan menghormati batasan pada sistem Anda (misalnya jumlah file dan proses). Biasanya ini berarti Anda akan menjalankan 250 pekerjaan secara paralel jika Anda belum menyesuaikan jumlah file terbuka yang diizinkan. Jika Anda menyesuaikan jumlah file yang terbuka, Anda seharusnya tidak memiliki masalah menjalankan 32000 secara paralel - selama Anda memiliki cukup memori.

Jika suatu pekerjaan gagal (yaitu kembali dengan kode kesalahan) itu akan dicoba lagi 10 kali.

my.log akan memberi tahu Anda jika suatu pekerjaan berhasil (setelah kemungkinan coba lagi) atau tidak.

Ole Tange
sumber
Ini terlihat sangat menjanjikan, terima kasih.
KuboMD
Menjalankan tes sederhana cat ~/sagLogs/* >> ~/woah | paralleldan moly suci yang cepat. 1.054.552 garis dalam sekejap mata.
KuboMD
3
Perintah yang Anda berikan memiliki pengalihan ganda, jadi saya tidak berpikir itu melakukan apa yang Anda inginkan. GNU Parallel memiliki overhead 10 ms per pekerjaan, jadi pekerjaan 1M harus memakan waktu 3 jam.
Ole Tange
1
Ini tidak berlaku sama sekali jika semua yang Anda ingin lakukan hanyalah menyatukan file.
Ole Tange
1
@KuboMD loop sibuk CPU sepele seperti awk 'BEGIN{for(i=rand()*10000000; i<100000000;i++){}}' akan bekerja untuk bermain-main dengan. Atau coba pada tugas seperti sleep 10melihatnya tetap nbekerja tanpa menggunakan banyak waktu CPU. misalnya time parallel sleep ::: {100..1}untuk menjalankan tidur dari 100 ke 1 detik.
Peter Cordes
1

Apa yang terjadi jika saya memulai terlalu banyak pekerjaan latar belakang?

sistem akan menjadi lambat dan tidak responsif, kasus terburuk begitu tidak responsif akan lebih baik untuk hanya menekan tombol daya dan melakukan reboot keras ... ini akan menjalankan sesuatu sebagai root di mana ia memiliki hak istimewa untuk lolos dengan melakukan itu. Jika skrip bash Anda berjalan di bawah hak pengguna biasa, maka hal pertama yang terlintas dalam pikiran adalah /etc/security/limits.confdan /etc/systemd/system.confdan semua variabel di dalamnya untuk [secara ideal] mencegah pengguna dari membebani sistem.

  • cpu = xeon E5649, itu adalah cpu 12- core ; jadi Anda memiliki 12 core untuk 12 proses yang berjalan bersamaan, masing-masing menggunakan satu dari dua belas core dengan 100%. Jika Anda memulai 24 proses, maka masing-masing akan berjalan pada utilisasi 50% pada masing-masing dua belas core, 700 proses = 1,7% tetapi itu adalah komputer selama semuanya selesai dengan benar dalam jumlah waktu ok maka itu = sukses; menjadi efisien tidak selalu relevan.

    1. Mungkinkah ke-700 instance tersebut dapat berjalan secara bersamaan? Tentu saja, 700 bukanlah jumlah yang besar; maxproc/etc/security/limits.conf default saya adalah 4.135.275 misalnya

    2. Seberapa jauh saya bisa sampai server saya mencapai batasnya? Lebih jauh dari 700 saya yakin.

    3. Batas ... apa yang akan terjadi jika skrip dimulai di bawah akun pengguna [dan umumnya root juga limits.confcukup banyak berlaku untuk semua orang] adalah skrip akan keluar setelah mencoba melakukan foo &700 kali; Anda akan mengharapkan untuk melihat 700 proses foo masing-masing dengan pid yang berbeda tetapi Anda mungkin hanya melihat 456 (pilihan nomor acak) dan 244 lainnya tidak pernah dimulai karena mereka diblokir oleh batas keamanan atau sistem.

Juta $ pertanyaan: berapa banyak yang harus Anda jalankan secara bersamaan?

terlibat dengan spot untuk menyelesaikan sesuatu secepat mungkin ... meminimalkan overhead dan meningkatkan efisiensi. Menjadi 12 core (atau 24 jika Anda memiliki 2 cpu) kemudian mulai dengan 12 (atau 24) sekaligus dan kemudian tambahkan nomor batch bersamaan dengan 12 atau 24 sampai Anda tidak melihat peningkatan run time. jaringan dan Anda mengatakan masing-masing akan melakukan koneksi telnet, tebakan berpendidikan adalah Anda akan mengalami batas jaringan dan overhead sebelum Anda melakukannya untuk batas cpu dan ram. Tapi saya tidak tahu apa yang Anda lakukan secara spesifik, apa yang kemungkinan akan terjadi adalah Anda dapat memulai semua 700 sekaligus, tetapi hal-hal secara otomatis akan memblokir sampai proses sebelumnya dan koneksi jaringan selesai dan ditutup berdasarkan berbagai batas sistem, atau sesuatu seperti 500 pertama akan dimulai kemudian 200 sisanya tidak akan karena batas sistem atau kernel mencegahnya. Tapi betapapun banyak yang berlari sekaligus, akan ada beberapa yang manis

petunjuk: google max koneksi telnet dan lihat bagaimana ini berlaku untuk sistem Anda. Juga jangan lupa tentang firewall. Juga lakukan perhitungan cepat memori yang dibutuhkan per proses x 700; pastikan <RAM yang tersedia (sekitar 50GB dalam kasus Anda) jika tidak, sistem akan mulai menggunakan SWAP dan pada dasarnya menjadi tidak responsif. Jadi tendangan 12, 24, N memproses sekaligus dan memonitor RAM bebas, kemudian meningkatkan N sudah memiliki beberapa pengetahuan tentang apa yang terjadi.

Secara default, RHEL membatasi jumlah koneksi telnet dari satu host hingga 10 sesi secara bersamaan. Ini adalah fitur keamanan ... set ke 10, /etc/xinetd.conf, ubah nilai "per_source".

ron
sumber