Как можно ограничить количество ядер ЦП, которые может использовать каждый пользователь?

18

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

Реза
источник
5
Не ответ, только идея. Возможно, вы захотите настроить несколько виртуальных машин. У каждого может быть только ограниченное количество процессоров. Каждый пользователь будет находиться только на одной из виртуальных машин, а пользователи этой виртуальной машины будут ограничены в использовании ЦП. Возможно, что некоторые из программ для виртуализации имеют инструменты для поддержки этого.
ghellquist
1
@ghellquist, вы должны сделать это ответ
slebetman
@ghellquist: Вы, вероятно, хотите что-то настолько легкое, насколько это возможно, например контейнеры Linux, если вы просто хотите, чтобы разные пользователи видели только некоторые из процессоров. (например, когда они запускают OpenMP или другую программу, которая запускает столько потоков, сколько видит ядер, она запускает соответствующее число для количества ядер, которое вы позволяете каждому пользователю фактически использовать). Полная виртуализация, как и KVM, требует снижения производительности даже при аппаратной поддержке, такой как VT-X или AMD-V, от дополнительных уровней таблиц страниц, даже когда выходы из виртуальных машин исключены, в коде, который пропускает 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, никто не будет загружать ресурсы (и никто не поставит сервер на колени).

Обратите внимание, что высокое значение nice означает низкий приоритет. Это мера того , насколько хорошо мы должны быть и лучше , мы, тем больше мы разделяем.

Также обратите внимание, что это не поможет управлять распределением памяти, а только влияет на планирование ЦП. Поэтому, если несколько пользователей запускают несколько процессов, интенсивно использующих память, у вас все равно будет проблема. Если это проблема, вы должны посмотреть на правильные системы очередей, такие как крутящий момент .

terdon
источник
Спасибо за Ваш ответ. Есть некоторые «менеджеры рабочей нагрузки», такие как SLURM, но они предназначены для компьютеров с несколькими узлами. Я думаю, что имеет смысл, что люди не разрабатывали аналогичные приложения для компьютеров с одним узлом, так как не так много спроса.
Реза
@ Reza nice, судя по тому , что вы описываете, это почти то, что вам нужно.
тердон
3
@Reza: Это потому, что ОС уже делает это. Он автоматически распределяет время по доступным процессорам между потоками / процессами по мере необходимости.
BlueRaja - Дэнни Пфлюгофт
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? [duplicate] на сайте 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 для автоматического перемещения процессов в соответствующую cgroup на основе пользователя / группы вместо того, чтобы полагаться на пользователей, выполняющих свои процессы с cgexec. Но, похоже, настроить это в Ubuntu несколько нетривиально.
Ганс-Якоб
@ Hans-Jakob Это выглядит несколько запутанно, плюс требует добавления флагов ядра в GRUB. Вероятно, для компьютеров уровня предприятия, где у вас много пользователей, и вы не хотите, чтобы они ломали систему, это, вероятно, стоит, но для настольных компьютеров - слишком много работы. Спасибо, что связали это.
Сергей Колодяжный
2
sched_setaffinity(2)говорит , что маска сродства сохраняется через execve(2), и что ребенок наследует это на fork(2). Таким образом, если вы задаете командную оболочку для пользователя (или его графическую оболочку для сеанса X), все, что они запускают из этой оболочки, по умолчанию будет использовать ту же маску сходства.
Питер Кордес
1
Одним из возможных недостатков являются программы, которые проверяют, сколько процессоров имеет машина, когда решают, сколько потоков запустить; у них будет слишком много потоков для того количества ядер, на которое они на самом деле запланированы. Вы узнали, могут ли cgroups что-то с этим сделать?
Питер Кордес
@PeterCordes Идея создания нереста звучит интересно. Мне нужно разобраться в этом. Благодарность ! Что касается второго комментария, нет, на данный момент я недостаточно исследовал cgroups.
Сергей Колодяжный