Ograniczanie procesów do nie więcej niż 10% wykorzystania procesora

32

Używam systemu Linux, który ma wielu użytkowników, ale czasami zdarza się nadużycie; gdzie użytkownik może uruchomić pojedynczy proces, który zużywa ponad 80% procesora / pamięci.

Czy istnieje sposób, aby temu zapobiec, ograniczając zużycie procesora przez proces (na przykład do 10%)? Zdaję sobie z tego sprawę cpulimit, ale to niestety ogranicza limit do procesów, które nakazuję mu ograniczyć (np. Pojedyncze procesy). Więc moje pytanie brzmi: w jaki sposób mogę zastosować limit do wszystkich uruchomionych procesów i procesów, które będą uruchamiane w przyszłości bez konieczności podawania na przykład ich identyfikatora / ścieżki?

Giovanni Mounir
źródło
Czy masz problemy z wydajnością? czy to tylko liczby Cię niepokoją?
ctrl-alt-delor
@richard Problemy z wydajnością, dlatego próbowałem zabić / ograniczyć / położyć kres procesom, które wydają się zużywać dużo procesora, ale już to zrobiłem, pisząc skrypt bash. Jest to również maszyna wirtualna, jeśli to pomaga
Giovanni Mounir
2
Uważaj na procesy zabijania, które mogą trwać w 100% przez bardzo krótki czas, także procesy systemowe. Zastanów się cpulimitw połączeniu ze swoim skryptem wyszukiwania. Miej zasady i zalecaj stosowanie cpulimit, a następnie wyszukaj ponad 10%, a następnie ogranicz do 5% (więc użytkownicy są zachęcani do korzystania cpulimit). Upewnij się także, że możesz wykryć wiele procesów, które stanowią ponad 10% dla jednego użytkownika.
ctrl-alt-delor
@richard Dzięki Richard za wszystkie te bardzo przydatne komentarze! Pomogli mi bardzo! Twoja sugestia użycia cpulimitjest o wiele lepsza niż zwykłe zabicie procesu, ponieważ może zostać później ponownie uruchomiony przez użytkownika (jak wskazano w jednym z twoich komentarzy). Dziękuję Ci!
Giovanni Mounir
1
stackoverflow.com/questions/386945/…
Ciro Santilli 18 改造 中心 法轮功 六四 事件

Odpowiedzi:

20

Chociaż może to być nadużycie pamięci, nie dotyczy procesora: gdy procesor jest w stanie bezczynności, uruchomiony proces (przez „uruchomienie” oznacza, że ​​proces nie czeka na operacje we / wy lub coś innego) Domyślnie 100% czasu procesora. I nie ma powodu egzekwować limitu.

Teraz możesz ustawić priorytety dzięki nice. Jeśli chcesz, aby miały zastosowanie do wszystkich procesów dla danego użytkownika, musisz tylko upewnić się, że jego powłoka logowania jest uruchomiona z nice: procesy potomne odziedziczą tę nicewartość. Zależy to od sposobu logowania użytkowników. Zobacz na przykład Priorytet logowania ssh (miły) .

Alternatywnie możesz skonfigurować maszyny wirtualne. Rzeczywiście ustawienie limitu na proces nie ma większego sensu, ponieważ użytkownik może uruchomić wiele procesów, nadużywając systemu. W przypadku maszyny wirtualnej wszystkie ograniczenia będą globalne dla maszyny wirtualnej.

Innym rozwiązaniem jest ustalenie /etc/security/limits.conflimitów; zobacz stronę podręcznika limit.conf (5). Na przykład można ustawić maksymalny czas procesora na logowanie i / lub maksymalną liczbę procesów na logowanie. Możesz także ustawić maxloginsna 1 dla każdego użytkownika.

vinc17
źródło
1
@ GiovanniMounir Miałem na myśli: jedna maszyna wirtualna na użytkownika.
vinc17
1
Rozumiem, ale niestety będzie to pochłaniać zasoby i nie będzie tak naprawdę przydatne do moich celów, ponieważ użytkownicy mogą wymagać użycia niektórych popularnych pakietów programistycznych i nie będę instalować tego na każdym nowym komputerze; Myślę, że lepiej zostawić to w ten sposób i wykonać monitorowanie automatycznie za pomocą skryptu bash.
Giovanni Mounir
1
@GiovanniMounir Możesz udostępnić partycję między kilkoma maszynami wirtualnymi.
vinc17
@ GiovanniMounir Możesz użyć LXC lub Docker, aby zmniejszyć narzut wirtualizacji prawie do zera. Również „polubienie” nie jest silnym powodem. Na przykład wybrałbym twoje rozwiązanie, jeśli zarządzasz współdzielonym hostem PHP, ponieważ wykonywanie LXC lub maszyn wirtualnych będzie wymagało przepisania oprogramowania licencjonowanego o wartości 15 USD / 5 USD, co jest przesadą.
Pooyan Khosravi
rozumiem, że nice ustawia tylko względny procesor w porównaniu do innych procesów. Jeśli żaden inny proces nie korzysta z procesora, wówczas proces będzie zużywał 100% procesora, nie ograniczając go do 10%.
John, dlaczego
25

ładne / renice

nice jest doskonałym narzędziem do jednorazowych poprawek w systemie.

 nice COMMAND

cpulimit

cpulimit jeśli chcesz uruchomić zadanie intensywnie wykorzystujące procesor i mieć wolny czas procesora, jest niezbędny do reakcji systemu.

cpulimit -l 50 COMMAND

grupy

cgroups zastosować ograniczenia do zestawu procesów, a nie tylko do jednego

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

Zasoby

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

RafaSashi
źródło
5
Dla tych, którzy chcą ustalić twardy limit wykorzystania procesora, nawet gdy żaden inny proces nie jest uruchomiony, spójrz na cpu.cfs_quota_usparametr (patrz instrukcja )
Diego
grupy c są łatwiejsze w użyciu dzięki systemowym dyrektywom ... utworzenie jednostki albo system, albo użytkownik w tym celu jest najlepszą opcją
Yves Martin
dla trwającego procesu, np .:sudo cgclassify -g cpu:cpulimited 2315444
Aquarius Power
1
rozumiem, że nice ustawia tylko względny procesor w porównaniu do innych procesów. Jeśli żaden inny proces nie korzysta z procesora, wówczas proces będzie zużywał 100% procesora, nie ograniczając go do 10%.
John, dlaczego
10

Patrzyłeś na cgroups? Na stronie Arch Wiki znajduje się kilka informacji na ich temat. Przeczytaj sekcję o cpu.shares, wygląda na to, że robi to, czego potrzebujesz, i mogą działać na poziomie użytkownika, dzięki czemu możesz ograniczyć wszystkie procesy użytkownika na raz.

Paul Schyska
źródło
CGroups to jednak droga. Korzystam również z wielu serwerów współużytkowanych komputerów i używamy cgroups, aby ograniczyć maksymalną liczbę rdzeni, z których może korzystać cała sesja logowania . W ten sposób, jeśli dana osoba rozpoczyna nowe procesy, każdy dostaje mniejszy kawałek. To samo dotyczy użycia pamięci. Możesz mieć użytkowników automatycznie umieszczanych w grupie za pomocą pam_cgroups i usługi cgrulesengd. Możesz użyć „szablonu” w pliku cgconfig, aby umieścić każdego użytkownika we własnej grupie. cgrulesengd działa jak twój skrypt, z wyjątkiem tego, że zamiast zabijać procesy, po prostu upewnia się, że każdy proces znajduje się we właściwej grupie.
jsbillings
Nawet jeśli nie używasz grup dyskusyjnych w celu ograniczenia wykorzystania zasobów, możesz użyć go do oceny, ile zasobów zużywa dana osoba, przeglądając plik „stat” dla każdego zasobu, a następnie użyj tych informacji w swoim 5-minutowym skrypcie.
jsbillings
3

Dla pamięci to, czego szukasz ulimit -v. Zauważ, że ulimitjest dziedziczony przez procesy potomne, więc jeśli zastosujesz go do powłoki logowania użytkownika w momencie logowania, dotyczy to wszystkich jego procesów.

Jeśli wszyscy użytkownicy używają bashjako powłoki logowania, wstawienie następującego wiersza /etc/profilepowinno spowodować, że wszystkie procesy użytkownika będą miały twardy limit 1 gigabajta (a dokładniej milion kilobajtów):

ulimit -vH 1000000

Opcja Hzapewnia, że ​​jest to twardy limit, to znaczy, że użytkownik nie będzie mógł później ustawić go ponownie. Oczywiście użytkownik nadal może zapełnić pamięć, uruchamiając jednocześnie wystarczającą liczbę procesów.

W przypadku innych powłok musisz dowiedzieć się, jakie pliki inicjujące czytają zamiast tego (i jakich innych poleceń zamiast ulimitużywać).

Wydaje mi się, że to, czego sobie życzysz, nie ma sensu. Jaki byłby użytek z pozostawienia 90% procesora nieużywanego, gdy uruchomiony jest tylko jeden proces? Myślę, że tak naprawdę chcesz nice(i prawdopodobnie ionice). Zauważ, że podobnie ulimit, nicewartości są dziedziczone przez procesy potomne, więc wystarczy zastosować je do powłoki logowania w czasie logowania. Myślę, że dotyczy to również, ioniceale nie jestem pewien.

celtschk
źródło
Dzięki za sugestię pamięci! Czy jest jakaś szansa, że ​​możesz mi pokazać przykład zastosowania tego do powłoki logowania użytkownika podczas logowania? Nie jestem pewien, jak to zrobić. Przepraszam również, że nie byłem wystarczająco jasny; Staram się, aby żaden proces nie zużywał więcej niż 10% procesora. Czy myślisz, że to nicebędzie wystarczająco miłe, aby to zrobić? Jeśli tak, czy uważasz, że możesz pokazać mi przykład, aby to osiągnąć?
Giovanni Mounir
Nadal nie mam sensu utrzymywać procesora w 90% bezczynności, gdy działa tylko jeden proces.
celtschk
1
Jeśli obecnie działa mniej niż 10 procesów jednocześnie (a przez uruchomienie mam na myśli naprawdę działające, a nie tylko oczekiwanie na dane wejściowe użytkownika lub dyskowe operacje wejścia / wyjścia), to jest praktycznie gwarantowane, że jeden z nich będzie miał więcej niż 10% procesora. W przeciwnym razie procesor byłby praktycznie na biegu jałowym. A jeśli zabijesz jakikolwiek proces, który przekroczy 10%, jestem pewien, że będziesz mieć wielu użytkowników, którzy będą chcieli cię zabić . A przynajmniej postara się zastąpić cię kimś, kto ma pojęcie o tym, co oznaczają te liczby, ponieważ wydaje się, że nie.
celtschk
W przeciwieństwie do komentarza @celtschk, jeśli uruchomionych jest 11 lub więcej procesów (związanych z procesorem), będzie ich mniej niż 9,09%. Więc jeśli jestem użytkownikiem systemu, który zakazuje użycia procesora powyżej 10%, mogę uruchomić 11 lub więcej procesów i ukryć się pod radarem.
ctrl-alt-delor
@richard Masz rację, być może byłoby lepiej, gdyby skrypt sumował całkowitą ilość pamięci / procesora zużytego przez użytkownika, a następnie zakończyłby wszystkie procesy tego użytkownika, gdy odsetek osiągnie określoną ilość (więc również by go zalogował out)
Giovanni Mounir
3

Ponieważ jesteś stwierdzające, że cpulimit nie byłoby praktyczne w Twoim przypadku, to proponuję spojrzeć w Nicei , Renice i taskset , które mogą zbliżyć się do tego, co chcesz osiągnąć, chociaż taskset pozwala na ustawienie procesora powinowactwo dla procesów męska, więc może nie być natychmiast pomocny w twoim przypadku.

RJ
źródło
1
nicei renice? To miłe! Przejrzałem ich strony podręcznika, ale nadal nie sądzę, aby mogli w tym pomóc, ponieważ nadal musisz ustawić identyfikator procesu. Jeśli mógłbyś jednak podać przykład, w którym te pakiety stosują limit na wszystkie uruchomione procesy / przyszłe procesy, które byłyby niesamowite!
Giovanni Mounir
1

Ponieważ Twoje tagi mają centos, możesz użyć systemd.

Na przykład, jeśli chcesz ograniczyć użytkownika o identyfikatorze 1234:

sudo systemctl edit --force user-1234.slice

Następnie wpisz i zapisz to:

[Slice] CPUQuota=10%

Wpłynie to na zalogowanie się użytkownika.

Strony man: systemctl, systemd.slice, systemd.resource-control...

stos-zasady-są-trolle
źródło
0

Jeśli chcesz ograniczyć procesy, które już zostały uruchomione, będziesz musiał to zrobić jeden po drugim według PID, ale możesz mieć skrypt wsadowy, aby to zrobić tak jak poniżej:

#!/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

W moim przypadku pypdfocruruchamia chciwy tesseract.

Również w niektórych przypadkach, gdy twój procesor jest całkiem dobry, możesz po prostu użyć renicetakiego:

watch -n5 'pidof tesseract | xargs -L1 sudo renice +19'
Eduard Florinescu
źródło