Назад | Перейти на главную страницу

Как выбрать максимальный порог нагрузки в зависимости от количества доступных ядер?

У меня есть конвейер, который выполняет некоторые ресурсоемкие задачи на 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.

Вообще говоря, нагрузка как чистое число не имеет большого значения без точки отсчета, и я считаю, что это значение часто искажается.

Заблуждение 1: нагрузка как отношение

Другими словами, как я могу узнать, какую максимальную среднюю нагрузку может поддерживать машина, прежде чем производительность начнет падать?

Это самая распространенная ложь, которую люди делают о нагрузке в Linux. Что его можно использовать для измерения производительности процессора относительно некоторого фиксированного соотношения. Это не какая нагрузка дает вам.

Чтобы уточнить - людям легко понять использование ЦП. Это полезность со временем. Вы берете выполненную работу, а затем делите ее на возможные работы.

Возможная работа в этом отношении - это фиксированное известное значение, обычно представляемое в процентах из 100 - это ваше фиксированное соотношение.

Однако нагрузка не имеет ограничений. Не существует фиксированного максимума, поэтому вам трудно понять, что измерять.

Чтобы уточнить, из какой нагрузки идет отбор делает иметь нефиксированный максимум, который представляет собой общее количество задач, которые в настоящее время присутствуют в системе на момент взятия выборки (это не имеет реального отношения к тому, какая работа процессора выполняется).

Расчетная нагрузка не имеет фиксированного максимума, так как она включена в средневзвешенное значение, и при измерении взвешивания не ведется запись количества задач.

Поскольку мне нравится еда, вы можете провести аналогию с тем, что использование - это скорость, с которой вы можете съесть свою тарелку, а загрузка - это в среднем то, сколько тарелок вам осталось съесть.

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

Заблуждение 2: нагрузка - это мгновенное измерение

Второе заблуждение состоит в том, что нагрузка - это гранулированное измерение. Вы можете прочитать номер и получить представление о состоянии системы.

Нагрузка не является гранулярной, но представляет собой общее долгосрочное состояние системы. Он не только отбирается каждые пять секунд (поэтому пропускает выполнение задач, которые происходят в течение 5-секундного окна), но и измеряется как среднее значение за 1, 5 и 15 минут соответственно.

Вы не можете использовать это как мгновенный показатель емкости, но в целом ощущаете нагрузку на систему в течение длительного периода.

Нагрузка может быть 100, а затем 10 только через 30 секунд. Это ценность, на которую нужно постоянно смотреть, чтобы работать.

Что может вам сказать Load?

Это может дать вам представление о тенденциях в работе системы. Ему дают больше, чем он может справиться, или меньше?

  • Если нагрузка меньше, чем количество процессоров, которые у вас есть, это (обычно) означает, что у вас больше мощности процессора, чем работает.
  • Если нагрузка больше или равна количеству процессоров и имеет тенденцию к увеличению, это означает, что у системы больше работы, чем она может обработать.
  • Если нагрузка больше или равна количеству процессоров и имеет тенденцию к снижению, это указывает на то, что система выполняет работу быстрее, чем вы даете ей задание.

Из-за состояния непрерывного сна это делает значение нагрузки нечетким, как чистую оценку работы по расписанию, но дает вам некоторое представление о том, сколько запросов есть на диске (это все еще работа, которую нужно выполнять технически).

Load также предлагает подсказки об аномалиях в системе. Если вы видите нагрузку 50+, значит, что-то не так.

Кроме того, нагрузка может беспричинно волновать людей.

  1. Общеизвестно, что активность диска может увеличивать нагрузку.
  2. Нагрузка может быть искусственно завышена, если множество процессов привязано к одному ожидаемому процессору.
  3. Задачи с очень низким приоритетом (изящностью) часто долго ждут, увеличивая нагрузку на 1 для этого конкретного процесса.

В итоге

Я считаю load очень туманным значением, в нем нет никаких абсолютов. Его измерение, которое вы получаете в одной системе, часто бессмысленно по сравнению с другой.

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

Я считаю, что его период выборки слишком длинный для большинства рабочих нагрузок, которые я бросаю в свои системы (которые обычно выполняются в секундах, а не в минутах). Я полагаю, это имеет смысл для систем, которые выполняют длительные и интенсивные задачи, но я на самом деле мало этим занимаюсь.

Еще я использую его для долгосрочного управления мощностью. Приятно строить графики за длительные периоды времени (месяцы), поскольку вы можете использовать их, чтобы понять, сколько работы вы выполняете по сравнению с тем, что было несколько месяцев назад.


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

  1. Вы даете этому процессу лишь небольшое количество процессорного времени, когда другие процессы заняты.
  2. Если на ЦП ничего нет или ЦП простаивает, ваша задача тратит на это 100% времени.
  3. Все процессы в группе процессов наследуют одинаковую привлекательность.

При аккуратности 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, включает все процессы, ожидающие ввода-вывода (например, диск или сеть). Это означает, что если ваше приложение несколько интенсивно вводит / вывод, у вас будет высокая средняя нагрузка (то есть: многие процессы ожидают ввода / вывода) с низкой загрузкой ЦП (они спят, ожидая ввода / вывода).

Это, в свою очередь, приведет к тому, что система будет реагировать даже при средней перегрузке.