Membatasi proses untuk tidak melebihi lebih dari 10% dari penggunaan CPU

32

Saya mengoperasikan sistem Linux yang memiliki banyak pengguna tetapi kadang-kadang terjadi penyalahgunaan; di mana pengguna dapat menjalankan proses tunggal yang menggunakan lebih dari 80% dari CPU / Memori.

Jadi apakah ada cara untuk mencegah hal ini terjadi dengan membatasi jumlah penggunaan CPU yang bisa digunakan oleh proses (hingga 10% misalnya)? Saya sadar cpulimit, tetapi sayangnya menerapkan batas untuk proses yang saya perintahkan untuk membatasi (misalnya proses tunggal). Jadi pertanyaan saya adalah, bagaimana saya bisa menerapkan batas untuk semua proses dan proses yang berjalan yang akan berjalan di masa depan tanpa perlu memberikan id / path mereka misalnya?

Giovanni Mounir
sumber
Apakah Anda mengalami masalah kinerja? atau hanya angka-angka yang mengganggu Anda?
ctrl-alt-delor
@richard Masalah kinerja, jadi itu sebabnya saya mencoba untuk mematikan / membatasi / mengakhiri proses yang tampaknya menggunakan banyak CPU, tapi saya sudah melakukannya dengan menulis skrip bash. Ini juga mesin virtual jika itu membantu
Giovanni Mounir
2
Hati-hati membunuh proses yang mungkin 100% untuk waktu yang sangat singkat, juga proses sistem. Pertimbangkan cpulimitbersama skrip pencarian Anda. Memiliki kebijakan dan merekomendasikan penggunaan cpulimit, kemudian mencari lebih dari 10% dan kemudian membatasi hingga 5% (sehingga pengguna disarankan untuk menggunakan cpulimit). Pastikan juga Anda dapat mendeteksi beberapa proses yang menambahkan hingga lebih dari 10% untuk satu pengguna.
ctrl-alt-delor
@richard Terima kasih Richard untuk semua komentar yang cukup berguna ini! Mereka sangat membantu saya! Saran Anda untuk menggunakan cpulimitjauh lebih baik daripada hanya membunuh proses karena dapat dimulai kembali oleh pengguna nanti (seperti yang ditunjukkan dalam salah satu komentar Anda). Terima kasih!
Giovanni Mounir
1
stackoverflow.com/questions/386945/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Jawaban:

20

Meskipun bisa menjadi penyalahgunaan memori, itu bukan untuk CPU: ketika CPU diam, proses yang berjalan (dengan "berjalan", maksud saya bahwa proses itu tidak menunggu I / O atau sesuatu yang lain) akan mengambil Waktu CPU 100% secara default. Dan tidak ada alasan untuk memberlakukan batas.

Sekarang, Anda dapat mengatur prioritas berkat nice. Jika Anda ingin mereka berlaku untuk semua proses untuk pengguna tertentu, Anda hanya perlu memastikan bahwa shell loginnya dijalankan dengan nice: proses anak akan mewarisi nicenilai. Ini tergantung pada bagaimana pengguna login. Lihat memprioritaskan ssh login (bagus) misalnya.

Atau, Anda dapat mengatur mesin virtual. Memang menetapkan batas per-proses tidak masuk akal karena pengguna dapat memulai banyak proses, menyalahgunakan sistem. Dengan mesin virtual, semua batasan akan bersifat global ke mesin virtual.

Solusi lain adalah menetapkan /etc/security/limits.confbatasan; lihat halaman manual membatasi.conf (5). Misalnya, Anda dapat mengatur waktu CPU maksimum per login dan / atau jumlah proses maksimum per login. Anda juga dapat mengatur maxloginske 1 untuk setiap pengguna.

vinc17
sumber
1
@GiovanniMounir yang saya maksud: satu mesin virtual per pengguna.
vinc17
1
Saya mengerti, tetapi sayangnya ini akan menghabiskan banyak sumber daya dan tidak benar-benar berguna untuk tujuan saya, karena pengguna mungkin memerlukan penggunaan beberapa paket pengembangan umum, dan saya tidak akan menginstal ini pada setiap mesin baru; Saya pikir lebih baik membiarkannya seperti itu dan melakukan pemantauan secara otomatis dengan skrip bash.
Giovanni Mounir
1
@GiovanniMounir Anda dapat berbagi partisi antara beberapa mesin virtual.
vinc17
@GiovanniMounir Anda dapat menggunakan LXC atau Docker untuk mengurangi overhead virtualisasi menjadi hampir nol. Juga "menyukai" bukanlah alasan yang kuat. Sebagai contoh saya akan menggunakan solusi Anda jika Anda mengelola host PHP bersama karena melakukan LXC atau Mesin Virtual akan membutuhkan penulisan ulang perangkat lunak berlisensi $ 15 / $ 5 yang berlebihan.
Pooyan Khosravi
Pemahaman saya adalah bahwa bagus hanya mengatur CPU relatif dibandingkan dengan proses lain. Jika tidak ada proses lain yang menggunakan CPU, maka proses Anda akan menggunakan CPU 100%, tidak membatasi hingga 10%.
Johnny mengapa
25

bagus / renice

nice adalah alat yang bagus untuk 'one off' tweak ke suatu sistem.

 nice COMMAND

cpulimit

cpulimit jika Anda perlu menjalankan pekerjaan intensif CPU dan memiliki waktu CPU yang bebas sangat penting untuk responsif suatu sistem.

cpulimit -l 50 COMMAND

cgroups

cgroups menerapkan batasan pada serangkaian proses, daripada hanya satu

cgcreate -g cpu:/cpulimited
cgset -r cpu.shares=512 cpulimited
cgexec -g cpu:cpulimited COMMAND_1
cgexec -g cpu:cpulimited COMMAND_2
cgexec -g cpu:cpulimited COMMAND_3

Sumber daya

http://blog.scoutapp.com/articles/2014/11/04/restricting-process-cpu-usage-using-nice-cpulimit-and-cgroups

RafaSashi
sumber
5
Bagi mereka yang mencari untuk menetapkan batas keras pada penggunaan CPU, bahkan ketika tidak ada proses lain yang berjalan, lihat cpu.cfs_quota_usparameter (lihat manual )
Diego
cgroup lebih mudah digunakan berkat arahan systemd ... buat unit baik sistem atau pengguna untuk tujuan itu adalah pilihan terbaik
Yves Martin
untuk proses yang berjalan, ex .:sudo cgclassify -g cpu:cpulimited 2315444
Aquarius Power
1
Pemahaman saya adalah bahwa bagus hanya mengatur CPU relatif dibandingkan dengan proses lain. Jika tidak ada proses lain yang menggunakan CPU, maka proses Anda akan menggunakan CPU 100%, tidak membatasi hingga 10%.
Johnny mengapa
10

Apakah Anda melihat cgroup? Ada beberapa informasi di Arch Wiki tentang mereka. Baca bagian tentang cpu.shares, sepertinya melakukan apa yang Anda butuhkan, dan mereka dapat beroperasi pada tingkat pengguna, sehingga Anda dapat membatasi semua proses pengguna sekaligus.

Paul Schyska
sumber
Namun, CGroups adalah jalan yang harus ditempuh. Saya juga menjalankan (banyak) server komputer bersama dan kami menggunakan cgroup untuk membatasi jumlah core maksimum yang dapat digunakan oleh seluruh sesi login . Dengan cara ini, jika orang tersebut terus memulai proses baru, masing-masing mendapat irisan yang lebih kecil. Sama untuk penggunaan memori. Anda dapat meminta pengguna secara otomatis dimasukkan ke dalam cgroup dengan pam_cgroups dan layanan cgrulesengd. Anda dapat menggunakan 'templat' di file cgconfig untuk menempatkan setiap pengguna ke dalam cgroup mereka sendiri. cgrulesengd bertindak seperti skrip Anda, kecuali alih-alih membunuh proses, itu hanya memastikan setiap proses berada di cgroup yang tepat.
jsbillings
Bahkan jika Anda tidak menggunakan cgroup untuk membatasi penggunaan sumber daya, Anda dapat menggunakannya untuk mengevaluasi berapa banyak sumber daya yang digunakan individu, dengan melihat file 'stat' untuk setiap sumber daya, kemudian gunakan informasi itu untuk skrip 5 menit Anda.
jsbillings
3

Untuk memori, apa yang Anda cari adalah ulimit -v. Catatan yang ulimitdiwarisi oleh proses anak, jadi jika Anda menerapkannya pada shell login pengguna pada saat login, itu berlaku untuk semua prosesnya.

Jika semua pengguna Anda menggunakan bashshell login, memasukkan baris berikut ini /etc/profileakan menyebabkan semua proses pengguna memiliki batas keras 1 gigabyte (lebih tepatnya, satu juta kilobyte):

ulimit -vH 1000000

Opsi Hini memastikan bahwa ini adalah batas yang sulit, yaitu, pengguna tidak dapat mengaturnya kembali setelahnya. Tentu saja pengguna masih dapat mengisi memori dengan memulai cukup banyak proses sekaligus.

Untuk cangkang lain, Anda harus mencari tahu file inisialisasi apa yang mereka baca (dan perintah ulimitapa yang digunakan alih-alih ).

Untuk CPU, apa yang Anda inginkan sepertinya tidak masuk akal bagi saya. Apa gunanya membiarkan 90% CPU tidak digunakan saat hanya satu proses yang berjalan? Saya pikir apa yang sebenarnya Anda inginkan nice(dan mungkin ionice). Perhatikan bahwa, seperti ulimit, nicenilai diwarisi oleh proses anak, jadi menerapkannya pada shell login saat waktu login sudah cukup. Saya kira itu juga berlaku untuk ionicetetapi saya tidak yakin.

celtschk
sumber
Terima kasih atas saran ingatannya! Apakah ada kemungkinan Anda bisa menunjukkan kepada saya contoh untuk menerapkan ini ke shell login pengguna pada saat login? Saya tidak begitu yakin bagaimana melakukan ini. Saya juga minta maaf karena tidak cukup jelas; apa yang saya coba lakukan adalah tidak mengizinkan proses apa pun untuk menggunakan lebih dari 10% dari CPU. Jadi menurut Anda apakah nicecukup baik untuk melakukan ini? Jika demikian, apakah Anda pikir Anda dapat menunjukkan kepada saya contoh untuk mencapai ini?
Giovanni Mounir
Saya masih tidak mendapatkan titik menjaga CPU 90% idle ketika hanya satu proses yang berjalan.
celtschk
1
Jika saat ini ada kurang dari 10 proses yang berjalan secara bersamaan (dan dengan menjalankan maksud saya benar - benar berjalan, tidak hanya menunggu input pengguna atau disk I / O), maka secara virtual dijamin bahwa salah satu dari mereka akan memiliki lebih dari 10% CPU. Kalau tidak, CPU akan hampir idle. Dan jika Anda hanya membunuh proses apa pun yang berjalan di atas 10%, saya yakin Anda akan memiliki banyak pengguna yang ingin membunuh Anda. Atau setidaknya, akan mencoba membuat Anda digantikan oleh seseorang yang memiliki petunjuk tentang apa arti angka-angka itu, karena Anda tampaknya tidak.
celtschk
Berbeda dengan komentar @celtschk, jika ada 11 atau lebih proses yang berjalan (cpu terikat), maka mereka akan kurang dari 9,09%. Jadi jika saya adalah pengguna sistem yang melarang penggunaan CPU lebih dari 10%, saya dapat menjalankan 11 proses atau lebih, dan bersembunyi di bawah radar.
ctrl-alt-delor
@ Richard Anda benar, mungkin akan lebih baik jika skrip akan meringkas jumlah total memori / CPU yang digunakan oleh pengguna, dan kemudian menghentikan semua proses pengguna ini ketika persentasenya mencapai jumlah tertentu (jadi akan juga mencatatnya) keluar)
Giovanni Mounir
3

Karena Anda menyatakan bahwa cpulimit tidak akan praktis dalam kasus Anda, maka saya sarankan Anda melihat nice , renice , dan tasket , yang mungkin mendekati apa yang ingin Anda capai, meskipun tasket memungkinkan untuk mengatur afinitas CPU suatu proses, sehingga mungkin tidak segera membantu dalam kasus Anda.

RJ
sumber
1
nicedan renice? Itu bagus! Saya telah melihat halaman manual mereka, tetapi saya masih berpikir mereka tidak dapat membantu karena Anda masih harus menetapkan ID proses. Namun jika Anda bisa memberi saya contoh yang melibatkan paket-paket ini untuk menerapkan batas pada semua proses yang sedang berjalan / proses masa depan yang akan luar biasa!
Giovanni Mounir
1

Karena tag Anda miliki centos, Anda dapat menggunakan systemd.

Misalnya jika Anda ingin membatasi pengguna dengan ID dari 1234:

sudo systemctl edit --force user-1234.slice

Kemudian ketik dan simpan ini:

[Slice] CPUQuota=10%

Lain kali ketika pengguna masuk, itu akan mempengaruhi.

Man: systemctl, systemd.slice, systemd.resource-control...

tumpukan-kebijakan-adalah-troll
sumber
0

Jika Anda ingin membatasi proses yang sudah dimulai, Anda harus melakukannya satu per satu dengan PID, tetapi Anda dapat memiliki skrip batch untuk melakukannya seperti di bawah ini:

#!/bin/bash
LIMIT_PIDS=$(pgrep tesseract)   # PIDs in queue replace tesseract with your name
echo $LIMIT_PIDS
for i in $LIMIT_PIDS
do
    cpulimit -p $i -l 10 -z &   # to 10 percent processes
done

Dalam kasus saya pypdfocrmeluncurkan serakah tesseract.

Juga dalam beberapa kasus adalah CPU Anda cukup baik Anda bisa menggunakan reniceseperti ini:

watch -n5 'pidof tesseract | xargs -L1 sudo renice +19'
Eduard Florinescu
sumber