@asmelnik

Context switch per second (Linux) 1.3млн это много или мало?

Есть сервер, снимаю с него статистику нагрузки.
По CPU, RAM, IOPS-ам -- есть запас "прочности"
CPU - 80-85% загрузки т.е. еще 10-15% гипотетически догрузить можно. (на синтетической нагрузке все ядра на полчаса уложить в 100% можно)
RAM - 120-150Гб свободной из 384Г установленной
IOPS - дисковая подсистема вообще мало нагружена
график "Context switch per second" в zabbix-е упирается "полкой" в 1.3млн.
Если ту же самую нагрузку распределить по 2-м серверам, то нет проблем с обработкой и суммарно "Context switch per second" с 2-х серверов получаю примерно 1.45-1.5млн.
Т.е. не смотря на запас примерно 15% производительности по CPU скорее всего упираюсь именно в "Context switch per second"
Поиск по проблеме ничего вразумительного не дал.
Какими параметрами ядра это может регламентироваться -- найти не удалось.
Где может быть потенциально узкое место, не позволяющее нагрузить в 100% CPU?

реальность 1.
nginx с сжатием gzip по максимуму для отдающихся текстовых файлов грузит CPU в "полку" на 100% и обслуживает некоторое количество подключений и выдает отказы в обслуживании

реальность 2.
nginx c gzip с минимальным сжатием (уровень 3) для тех же файлов гузит CPU только на 80-85% и обслуживает большее количество подключений, чем с максимальным сжатием, но есть отказы в обслуживании

реальность 3
nginx c gzip с минимальным сжатием (уровень 3) для тех же файлов с распределением нагрузки по 2-м серверам без отказов в обслуживании обслуживает реальную нагрузку на 5-10% большую, чем в "реальности 2" (больше просто пользователи реально не создают) .

Вопрос: что мешает в "реальность 2" обслужить эти 5-10%? явно не CPU/RAM/IOPS
единственное обнаруженное, что отличает по набору снятых метрик в "реальность 2" и "реальность 3" -- Context switch per second 1.3млн
  • Вопрос задан
  • 1177 просмотров
Решения вопроса 1
@asmelnik Автор вопроса
Спасибо всем неравнодушным и ответившим по существу проблемы.
Всякое решение плодит новые проблемы.(один из законов Мэрфологии)

Похоже время ответить на вопрос и закрыть тему

Context switch per second (Linux) 1.3млн это много или мало?
Если коротко — это для конфигурации
E5-2699v4 — 2шт
RAM 378Gb
Довольно много, но не предел.
Достигнутый максимум 1.5 млн.
Достигнут был при следующих условиях:
Совет от edo1h,
1. mitigations=off, это снизит стоимость переключения контекста;
2. «Зажал» бы частоту процессора и отключил всякие c3, энергосберегающие опции плохо совместимы с короткими запросами.
processor.max_cstate=1 intel_idle.max_cstate=1 к параметрам ядра, плюс поставить pstate-frequency и запустить pstate-frequency -p max (если помогло, то в systemd включаем pstate-frequency@max)

Дал направление копания, итоговый набор параметров ядра совпал с советом выше.
mitigations=off intel_idle.max_cstate=1 processor.max_cstate=1

Замечания jcmvbkbc, res2001, Everything_is_bad натолкнули на мысль разделить задачи сервера на более-менее автономные блоки и исследовать как по отдельности, так и взаимосвязи между ними.

Результат оказался для меня неожиданным (об этом в п.3)

1. Сеть
Тюнинг сетевой подсистемы дал снижение количества прерываний/сек (не слишком значительное, но это положительным образом сказалось на результатах).
Убрал bonding интерфейсов (выигрыш на уровне погрешностей измерения, но иногда(хоть и крайне редко) при работающем bonding наблюдались всплески interrupts, которые полностью отсутствовали при выключенном bonding в течении 4-х дней)
Максимальный размер буферов на адаптере.
Воспользовался tuned + корректировка параметров sysctl.
Профиль network-latency субъективно подошел лучше всего.

2. Работа nginx-а
Тут дало положительный эффект запуск 2-х независимых серверов на 2-х dummy интерфейсах. Не могу пока предположить с чем связано.

3. Неожиданный эффект — т.к. логирование таки необходимо, довольно много сливалось в rsyslog по unix.socket (сеть не вариант, нагрузка выше заметно)
Вот отказ от заливки логов nginx-а в rsyslog снял 75-76% (С 1.3млн до 0.3млн на пиках нагрузки) количества «Context switch per second».
Буквально «на коленке» на python написал заменитель, вся задача — сообщение из unix.socket записать в файл в нужном формате.

Итог, сервер выполняет те же функций:
«Context switch per second» -- снизился на 50% от исходного.
Нагрузка на CPU — снижение примерно на 25-30%.
При тех нагрузках, при которых ранее появлялись отказы, отказов нет.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
saboteur_kiev
@saboteur_kiev Куратор тега Linux
software engineer
Нужно понимать как работает многозадачность и распределение процессорного времени по ядрам.
В Линукс довольно сложно посчитать реальную занятость процессора.
В сам свитчинг ничего упираться не может, точнее нет каких-то специальных лимитов. Это обычная процессорная занятость, относящаяся наверное к system cpu usage, но это неточно. Чем быстрее процессор, тем быстрее он может выполнять свитчинг и тем больше свитчингов в секунду может быть выполнено, это просто выполнение инструкций процессора вне рамках процессов, а внутри ядра системы, точнее process scheduler.

Но проблема в том, как именно распределяется процессорное время. process scheduler в ядре линукса выделяет слайсы примерно по 10-15 милисекунд на процесс, потом переключает на другой. Для процессов, которые что-то активно вычисляют (например архивация), после анализа деятельности может быть выделен более длинный слайс или несколько подряд, то есть уменьшается свитчинг. При этом оценка времени, которая нужна на сам свитчинг - она довольно сложная, ведь для подсчета количество потраченного cpu нужно потратить cpu, и эти 10-15% может на самом деле не существовать.

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

Ну или просто не хватает CPU, а система ошибочно показывает свободные ресурсы, которых на самом деле нет.

Линукс на самом деле не так уж детально может посчитать точное количество ресурсов. Там выполняется все очень просто - на входе в контекст засекается timestamp, на выходе из контекста засекается таймстамп, и потраченное время дописывается в метаданные процесса (для каждого ядра, если процесс многопоточный). Исторические значения не записываются, в метаданных процесса есть только вот это - сколько всего cpu usage с момента старта процесса.
Если запустить какой-нить top, он будет каждые 1-2 секунды бегать по списку процессов, сравнивать этот параметр и показывать результат загруженности за последние 1-2 секунды, но вот уточнить процесс занял свои 25% cpu плавно в течение секунды, или он занимал 100% cpu первую четверть секунды или третью - вы уже не сможете.

Ну и само ядро считает свои внутренние потоки так же само.
И только активность самого process scheduler (то есть cpu затраченное на анализ и переключения процессов) не может быть красиво подсчитана.

p.s. я не разработчик линукс, поэтому это мое IMHO основанное на наблюдениях и обзорных статьях о работе современного планировщика, если будут гуру которые меня поправят или подтвердят сказанное - будет круто.
Ответ написан
Комментировать
ky0
@ky0
Миллиардер, филантроп, патологический лгун
Цель "нагрузить 100% процессора" - странная. Замеры нужно проводить не синтетических попугаев, а прикладных метрик - и уже потом пытаться искать узкие места и что-то менять.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы