Як можна обмежити кількість ядер CPU, якими може користуватися кожен користувач?


18

У нас є комп’ютер, у якого процесор має 32 ядра, і він буде використовуватися для запуску програм декількома різними користувачами. Чи є спосіб обмежити кількість ядер, які кожен користувач може використовувати в будь-який час, щоб один користувач не монополізував всю потужність процесора?


5
Не відповідь, лише ідея. Можливо, ви захочете вивчити налаштування декількох віртуальних машин. Кожен може мати лише обмежену кількість процесорів. Кожен користувач буде лише на одній з віртуальних машин, а користувачі на цьому VM будуть обмежені у використанні процесора. Можливо, деякі програмні засоби для віртуалізації мають інструменти для цього.
ghellquist

1
@ghellquist ви повинні зробити так, щоб відповісти
slebetman

@ghellquist: Ви, мабуть, хочете чогось легкого, наприклад контейнерів Linux, якщо ви хочете, щоб різні користувачі бачили лише деякі процесори. (наприклад, коли вони запускають OpenMP або іншу програму, яка запускає стільки потоків, скільки бачить ядер, вона запустить відповідне число для кількості ядер, які ви дозволяєте кожному користувачеві реально використовувати). Повна віртуалізація, як і KVM, має продуктивність навіть при апаратній підтримці, як VT-X або AMD-V, від додаткових рівнів таблиць сторінок, навіть коли виключаються виходи VM, в коді, який отримує будь-які пропуски TLB від торкання великої кількості пам'яті.
Пітер Кордес

Вибачте, але чи є в цьому навіть потреба? Як багатокористувацька система, Linux за замовчуванням вже реалізує попереджувальну багатозадачність, тому ситуація, коли один (не зловмисний) користувач просто підтягує всю систему для себе, не повинен придуматись.
Кубік

Відповіді:


16

Хоча це можливо , це складна і майже напевно погана ідея. Якщо наразі машиною користується лише один користувач, обмеження їх до N ядер - це марна трата ресурсів. Набагато кращим підходом було б керувати усім nice:

NAME
       nice - run a program with modified scheduling priority

SYNOPSIS
       nice [OPTION] [COMMAND [ARG]...]

DESCRIPTION
       Run  COMMAND  with an adjusted niceness, which affects process scheduling.  With
       no COMMAND, print the current niceness.  Niceness values range  from  -20  (most
       favorable to the process) to 19 (least favorable to the process).

Це чудовий інструмент, який встановлює пріоритет процесу. Тож якщо лише один користувач щось працює, він отримає стільки часу, скільки потрібно процесору, але якщо хтось інший запустить власну (також за нумерацією) роботу, їм буде приємно і поділитися між собою. Таким чином, якщо ваші користувачі запускають усі команди nice 10 command, ніхто не буде перебирати ресурси (і сервер ніхто не поставить на коліна).

Зауважте, що високе приємне значення означає низький пріоритет. Це міра того, як ми повинні бути приємними і чим милішими, тим більше ми ділимося.

Також зауважте, що це не допоможе керувати розподілом пам'яті, це вплине лише на планування процесора. Тож якщо кілька користувачів запускають кілька процесів, що займають багато пам’яті, у вас все ще буде проблема. Якщо це проблема, вам слід вивчити належні системи черги, такі як крутний момент .


Дякую за вашу відповідь. Є деякі "менеджери навантаження", такі як SLURM, але вони призначені для комп'ютерів з декількома вузлами. Я думаю, має сенс, що люди не розробили подібні додатки для комп'ютерів з одним вузлом, оскільки попит не настільки великий.
Реза

@ Спробуйте nice, з того, що ви описуєте, це саме те, що вам потрібно.
тердон

3
@Reza: Це тому, що ОС це вже робить. Він автоматично розподіляє доступні процесори на потоки / процеси за потребою.
BlueRaja - Danny Pflughoeft

13

TL; DR : З коротких досліджень видно, що можна обмежити команди конкретною кількістю ядер, однак у всіх випадках ви повинні використовувати команду, яка фактично застосовує обмеження.

групи

Linux має те, cgroupsщо часто використовується саме з метою обмеження ресурсів, доступних для процесів. З дуже короткого дослідження ви можете знайти приклад в Arch Wiki з конфігурацією Matlab (наукового програмного забезпечення), встановленою в /etc/cgconfig.conf:

group matlab {
    perm {
        admin {
            uid = username;
        }
        task {
            uid = username;
        }
    }

    cpuset {
        cpuset.mems="0";
        cpuset.cpus="0-5";
    }
    memory {
        memory.limit_in_bytes = 5000000000;
    }
}

Для того, щоб така конфігурація набула чинності, потрібно запустити процес за допомогою cgexecкоманди, наприклад, з тієї ж сторінки вікі:

$ cgexec -g memory,cpuset:matlab /opt/MATLAB/2012b/bin/matlab -desktop

набір завдань

Пов'язаний з ним питання про проси Ubuntu і як обмежити процес до одного ядра процесора в Linux? [дублікат] на сайті Unix & Linux показують приклад використання tasksetдля обмеження процесорів для цього процесу. У першому питанні це досягається шляхом аналізу всіх процесів для конкретного користувача

$ ps aux | awk '/^housezet/{print $2}' | xargs -l taskset -p 0x00000001

В іншому питанні процес запускається через tasksetсебе:

$ taskset -c 0 mycommand --option  # start a command with the given affinity

Висновок

Хоча, безумовно, можливо обмежити процеси, але здається, що досягти цього для конкретних користувачів не так просто. Приклад у пов'язаній публікації Ask Ubuntu вимагає послідовного сканування процесів, що належать кожному користувачеві, та використання tasksetкожного нового. Набагато більш розумним підходом було б вибірково запускати ресурсомісткі програми, або через cgexecабо taskset; також немає сенсу обмежувати всі процеси конкретною кількістю CPUS, особливо для тих, хто фактично використовує паралелізм і паралельність для швидшого виконання своїх завдань - обмеження їх конкретною кількістю процесорів може призвести до уповільнення обробки. Крім того, як відповідь тердона згадувала, що це марнотрата ресурсів

Запуск вибраних програм через tasksetабо cgexecвимагає спілкування з вашими користувачами, щоб вони могли знати, які програми вони можуть запускати, або створювати сценарії обгортки, які запускають вибрані програми через taskselабо cgexec.

Крім того, врахуйте встановлення кількості процесів, які користувач або група може породити замість встановлення обмеження на кількість процесорів. Цього можна досягти за допомогою /etc/security/limits.confфайлу .

Дивись також


1
добре, є cgrulesengd і cgrules.conf для автоматичного переміщення процесів у відповідну групу на основі користувача / групи замість того, щоб покладатися на користувачів, які виконують свої процеси з cgexec. Але, здається, налаштування цього в ubuntu дещо нетривіально.
Ганс-Якоб

@ Hans-Jakob Це виглядає дещо перекрученим, плюс вимагає додати прапори ядра в GRUB. Можливо, для корпоративного рівня машини, де ви маєте багато користувачів і не хочете, щоб вони руйнували систему, це, мабуть, варто, але для робочого столу - занадто багато роботи. Дякую, що зв’язали це.
Сергій Колодяжний

2
sched_setaffinity(2)каже, що маска спорідненості зберігається поперек execve(2), і що дитина успадковує її fork(2). Тож якщо ви задаєте оболонку для користувача (або їх графічну оболонку для X сеансу), все, що вони починаються з цієї оболонки, за замовчуванням використовуватиме ту саму маску спорідненості.
Пітер Кордес

1
Один з можливих недоліків - це програми, які перевіряють, скільки процесорів має машина, вирішуючи, скільки ниток для запуску; у них буде занадто багато ниток для кількості ядер, на які вони дійсно будуть заплановані. Чи дізналися ви, чи можуть угруповання щось із цього робити?
Пітер Кордес

@PeterCordes Нерест оболонки ідея звучить цікаво. Мені потрібно буде розібратися в цьому. Спасибі ! Щодо другого коментаря, ні, на даний момент я недостатньо досліджував групи.
Сергій Колодяжний
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.