У меня есть конвейер, который выполняет некоторые ресурсоемкие задачи на Linux-машине. Сценарий, запускающий их, проверяет текущее среднее значение нагрузки и, если оно выше определенного порога, ожидает, пока нагрузка не упадет ниже его. Это на виртуальной машине Ubuntu (работающей на хосте Ubuntu, если это актуально), которой может быть назначено переменное количество ядер. И наши машины разработки, и производственные машины - это виртуальные машины, работающие на одном физическом сервере, и мы вручную выделяем ядра каждому по мере необходимости.
Я заметил, что даже когда у виртуальной машины всего 20 ядер, нагрузка в ~ 60 не ставит машину на колени. Мое понимание То, как работает средняя загрузка Linux, заключалось в том, что все, что превышает количество процессоров, указывает на проблему, но, очевидно, все не так однозначно, как все это.
Я подумываю установить порог примерно как $(grep -c processor /proc/cpuinfo) x N
где N>=1
. Есть ли какой-нибудь умный способ определения стоимости N
следует принимать так, чтобы как максимизировать производительность, так и минимизировать задержку?
Другими словами, как я могу узнать, какую максимальную среднюю нагрузку может поддерживать машина, прежде чем производительность начнет падать? Я наивно ожидал, что это будет количество процессоров (так что N=1
), но, похоже, этого не происходит. Поскольку количество ядер может варьироваться, проверка возможных комбинаций является сложной и трудоемкой, а, поскольку эта машина используется разными людьми, непрактична.
Итак, как я могу определить приемлемый максимальный порог средней нагрузки в зависимости от количества доступных ядер?
Загрузка - это очень часто неправильно понимаемое значение в Linux.
В Linux это измерение всех задач в рабочем или непрерывном спящем состоянии.
Обратите внимание, это задачи, а не процессы. В это значение включены потоки.
Нагрузка рассчитывается ядром каждые пять секунд и является средневзвешенной. То есть минутная нагрузка составляет в среднем 5/60, пятиминутная 5/300 и пятнадцать 5/900.
Вообще говоря, нагрузка как чистое число не имеет большого значения без точки отсчета, и я считаю, что это значение часто искажается.
Другими словами, как я могу узнать, какую максимальную среднюю нагрузку может поддерживать машина, прежде чем производительность начнет падать?
Это самая распространенная ложь, которую люди делают о нагрузке в Linux. Что его можно использовать для измерения производительности процессора относительно некоторого фиксированного соотношения. Это не какая нагрузка дает вам.
Чтобы уточнить - людям легко понять использование ЦП. Это полезность со временем. Вы берете выполненную работу, а затем делите ее на возможные работы.
Возможная работа в этом отношении - это фиксированное известное значение, обычно представляемое в процентах из 100 - это ваше фиксированное соотношение.
Однако нагрузка не имеет ограничений. Не существует фиксированного максимума, поэтому вам трудно понять, что измерять.
Чтобы уточнить, из какой нагрузки идет отбор делает иметь нефиксированный максимум, который представляет собой общее количество задач, которые в настоящее время присутствуют в системе на момент взятия выборки (это не имеет реального отношения к тому, какая работа процессора выполняется).
Расчетная нагрузка не имеет фиксированного максимума, так как она включена в средневзвешенное значение, и при измерении взвешивания не ведется запись количества задач.
Поскольку мне нравится еда, вы можете провести аналогию с тем, что использование - это скорость, с которой вы можете съесть свою тарелку, а загрузка - это в среднем то, сколько тарелок вам осталось съесть.
Итак, разница между утилитой ЦП и нагрузкой невелика, но важна. Утилита ЦП - это мера работа выполняется а нагрузка - это мера работа, которую нужно сделать.
Второе заблуждение состоит в том, что нагрузка - это гранулированное измерение. Вы можете прочитать номер и получить представление о состоянии системы.
Нагрузка не является гранулярной, но представляет собой общее долгосрочное состояние системы. Он не только отбирается каждые пять секунд (поэтому пропускает выполнение задач, которые происходят в течение 5-секундного окна), но и измеряется как среднее значение за 1, 5 и 15 минут соответственно.
Вы не можете использовать это как мгновенный показатель емкости, но в целом ощущаете нагрузку на систему в течение длительного периода.
Нагрузка может быть 100, а затем 10 только через 30 секунд. Это ценность, на которую нужно постоянно смотреть, чтобы работать.
Это может дать вам представление о тенденциях в работе системы. Ему дают больше, чем он может справиться, или меньше?
Из-за состояния непрерывного сна это делает значение нагрузки нечетким, как чистую оценку работы по расписанию, но дает вам некоторое представление о том, сколько запросов есть на диске (это все еще работа, которую нужно выполнять технически).
Load также предлагает подсказки об аномалиях в системе. Если вы видите нагрузку 50+, значит, что-то не так.
Кроме того, нагрузка может беспричинно волновать людей.
Я считаю load очень туманным значением, в нем нет никаких абсолютов. Его измерение, которое вы получаете в одной системе, часто бессмысленно по сравнению с другой.
Вероятно, это одна из первых вещей, которые я увижу в топе просто для того, чтобы проверить наличие явной аномалии. В основном я использую его почти как термометр - только как общее состояние системы.
Я считаю, что его период выборки слишком длинный для большинства рабочих нагрузок, которые я бросаю в свои системы (которые обычно выполняются в секундах, а не в минутах). Я полагаю, это имеет смысл для систем, которые выполняют длительные и интенсивные задачи, но я на самом деле мало этим занимаюсь.
Еще я использую его для долгосрочного управления мощностью. Приятно строить графики за длительные периоды времени (месяцы), поскольку вы можете использовать их, чтобы понять, сколько работы вы выполняете по сравнению с тем, что было несколько месяцев назад.
Наконец, чтобы ответить на ваш вопрос о том, что делать в вашем сценарии. Честно говоря, лучшее предложение, которое я мог бы предложить, - это вместо того, чтобы рассматривать использование нагрузки в качестве фактора, когда запускать, - используйте nice для выполнения вашего процесса, отдавая другим процессам приоритет над ним. Это хорошо по нескольким причинам.
При аккуратности 0 (по умолчанию) каждый процесс получает вес 1024. Чем меньше вес, тем меньше времени отводится процессу на CPU. Вот таблица этого поведения.
Nice Weight
0 1024
1 820
2 655
3 526
4 423
5 335
6 272
7 215
8 172
9 137
10 110
11 87
12 70
13 56
14 45
15 36
16 29
17 23
18 18
19 15
Итак, для сравнения, в сценарии, в котором у вас есть 2 процесса, ожидающих запуска - если вы рененируете процесс +10, он получает примерно 1/10 процессорного времени, который имеет процесс с приоритетом 0. Если вы измените его на +19, он получит 1/100 процессорного времени, который имеет процесс с приоритетом 0.
Следует отметить, что вы, вероятно, увидите свою нагрузку на 1 по крайней мере во время вашего трубопровода.
Думаю, это было бы более элегантное решение вашей проблемы.
Из Википедия:
Однако в Linux также есть процессы, находящиеся в непрерывном спящем режиме (обычно ожидающие активности диска), что может привести к заметно разным результатам, если многие процессы остаются заблокированными при вводе-выводе из-за загруженной или остановленной системы ввода-вывода.
Другими словами, средняя загрузка, сообщаемая Linux, включает все процессы, ожидающие ввода-вывода (например, диск или сеть). Это означает, что если ваше приложение несколько интенсивно вводит / вывод, у вас будет высокая средняя нагрузка (то есть: многие процессы ожидают ввода / вывода) с низкой загрузкой ЦП (они спят, ожидая ввода / вывода).
Это, в свою очередь, приведет к тому, что система будет реагировать даже при средней перегрузке.