Справедливое разделение ресурсов в Linux

12
HR
На сайте с 18.07.2013
Offline
1
1615

Приветствую.

Пытаюсь найти способы для справедливого разделения ресурсов (CPU, RAM, I/O) в Unix.

У меня имеется веб-сервер (nginx - php-fpm на Debian) и некоторое количество сайтов. Несколько скриптов (где число их = кол-ву ядер) могут истратить все ресурсы процессора и не дать остальным скриптам нормально работать. Нужно позволить скрипту использовать все ресурсы только, когда он работает единственный в системе. В остальных же случаев скрипты/процессы должны делится между собой ресурсами (т.е. начинать тратить меньше).

Вторая задача - это честное разделение ресурсов по домену или юзеру. Допустим по домену. У нас есть два активных работающих PHP скрипта на разных доменах, который являются тестовыми и занимают 100% допустимых ресурсов. Тогда первый скрипт должен тратить 50%, и второй 50%. А определять это можно по папке /var/www/$domain. Соответственно если домена три, то в случае трёх скриптов - каждый должен занимать не более 33%.

Кто-нибудь сталкивался с такой задачей? Получилось ли реализовать? Какими методами? Я предполагаю, что первый вопрос относится к модифицированному ядру Linux, может быть с BFS/BFQ. Но разделение памяти останется не честным.

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

Оптимизайка
На сайте с 11.03.2012
Offline
396
#1

На виртуальные машины сервер попилить не хотите? В этом случае не потребуется писать скрипты, т.к. лимиты ресурсов на виртуальные машины поддерживаются "из коробки".

⭐ BotGuard (https://botguard.net) ⭐ — защита вашего сайта от вредоносных ботов, воровства контента, клонирования, спама и хакерских атак!
P
На сайте с 16.03.2009
Offline
144
#2

nice, ionice, cgroups

или виртуалки, например на openvz

HR
На сайте с 18.07.2013
Offline
1
#3
poiuty:
nice, ionice, cgroups

Я понимаю, но я новичёк, подскажите, как хотя бы в теории это реализовывается, я в основном про второй вариант (когда надо честное разделение по домену)? Написать скрипт на bash? Модифицировать ядро?

p.s. У вас полезный блог. Может напишите статейку про мою проблему?)

P
На сайте с 16.03.2009
Offline
144
#4

Два варианта

- "жесткие лимиты, пусть использует N ресурсов и не больше"

- "мягкие лимиты(например изменение nice), пусть лучше быстрее обработает"

Для первого - это поднять виртуалки и раскидать туда клиентов. Каждому гарантировано CPU, RAM.

Или использовать cgroups -> для юзеров на CPU и RAM. PHP-PFM можно запускать под разными пользователями. Для RAM - лучше выставить лимиты на кол-во процессов php. И лимит делать только по CPU.

Для LAMP - лимит делать на I/O, не особо актуально. Грузит больше mysql, но есть userstat у percona.

И второй случай, можно менять nice пользователям

Для ISPmanager -> php как fcgi

http://poiuty.ru/ispmanager-menyaem-nice-pri-dlya-processov.html (набросок)

if($cpu_pool_intval < 25)
{
echo $item->name." - ".$cpu_pool_intval."\n";
}

if($cpu_pool_intval > 25 && $cpu_pool_intval < 50)
{
echo $item->name." - ".$cpu_pool_intval." RENICE!\n";
$cpu_nice = shell_exec("renice +3 -u '$item->name'");

}

if($cpu_pool_intval > 50 && $cpu_pool_intval < 75)
{
echo $item->name." - ".$cpu_pool_intval." RENICE!\n";
$cpu_nice = shell_exec("renice +4 -u '$item->name'");

}

А так же блокировать тех, кто нагрузил весь сервер (например форк или ddos)

http://poiuty.ru/process-killer-dlya-ispmanager-pro.html (набросок)

HR
На сайте с 18.07.2013
Offline
1
#5
poiuty:
Два варианта
- "жесткие лимиты, пусть использует N ресурсов и не больше"
- "мягкие лимиты, пусть лучше быстрее обработает"


Для первого - это поднять виртуалки и раскидать туда клиентов. Каждому гарантировано CPU, RAM.
Или использовать cgroups -> для юзеров на CPU и RAM. PHP-PFM можно запускать под разными пользователями. Для RAM - лучше выставить лимиты на кол-во процессов php. И лимит делать только по CPU.

Для LAMP - лимит делать на I/O, не особо актуально. Грузит больше mysql, но есть userstat у percona.

И второй случай, можно менять nice пользователям
Для ISPmanager -> php как fcgi
http://poiuty.ru/ispmanager-menyaem-nice-pri-dlya-processov.html (набросок)
А так же блокировать тех, кто нагрузил весь сервер (например форк или ddos)
http://poiuty.ru/process-killer-dlya-ispmanager-pro.html (набросок)

Мне если честно любой из предложенных вами вариантов подойдёт. Но в идеале "жесткие лимиты", правда хотелось бы без виртуалок...

ISPManager не использую и не планирую. Можно как-нибудь без него это сделать? И если делать скрипт, то как часто его запускать? Ну т.е. понятно что запуск один раз навечно, но как часто он должен выполнять действия - если раз в милисекунду - не будет ли слишком грузить CPU? Прежде всего волнуют динамические фреймворки (php, perl, node.js, ruby)

P
На сайте с 16.03.2009
Offline
144
#6

Можете накодить скрипты и пускать их по крону. Можете нагуглить себе мануал по cgroups (ядро модифицировать не надо вроде)

HR
На сайте с 18.07.2013
Offline
1
#7
poiuty:
Можете накодить скрипты и пускать их по крону.

Но как часто?

P
На сайте с 16.03.2009
Offline
144
#8
HostRinger:
Но как часто?

я раз в 3 минуты пускаю, но при этом еще собираю стату

http://poiuty.ru/grafiki-cpu-load-na-virtualnom-xostinge.html

HR
На сайте с 18.07.2013
Offline
1
#9
poiuty:
я раз в 3 минуты пускаю, но при этом еще собираю стату
http://poiuty.ru/grafiki-cpu-load-na-virtualnom-xostinge.html

Не совсем понятно.

Скрипты PHP например обычно работают не больше, чем 10 секунд. Если запускать раз в 3 минуты, то сама проблема (занятые ресурсы) никуда не денется.

P
На сайте с 16.03.2009
Offline
144
#10
HostRinger:
Не совсем понятно.

Скрипты PHP например обычно работают не больше, чем 10 секунд. Если запускать раз в 3 минуты, то сама проблема (занятые ресурсы) никуда не денется.

Процессы не работают 10 секунд под нагрузкой. Так же через ps aux стата падает не резко в 0

Вот пример -> сбор статы, юзер почти не создает нагрузку.

Получаем сколько ест CPU в % от ядер (например процессы пользователя юзают 50% от 1 ядра, или процессы пользователя юзают 150% от 2 ядер)

ps aux | grep '$item->name' | awk '{ sum += $3 } END { print sum }'

Если cpu > n -> меняем приоритет процессам пользователя.

Если cpu > max -> отключаем пользователя.

Хотите жесткие лимиты используйте cgroups

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий