Материал проходит вычитку — возможны неточности.
Урок 76 из 118

Практика syscall-нагрузки

Коллега Дима «по статье из интернета» поднял GOMAXPROCS выше числа ядер, и экспорт стал только хуже. Миша не спорил: вернул настройку и поставил семафор на одновременные экспорты. Цифры после замера закрыли спор.

Главная мысль

под нагрузкой блокирующих syscall'ов параллелизм ограничивают семафором; поток, заблокированный в syscall, не занимает P и не считается в лимите GOMAXPROCS — новые потоки runtime заводит сам, а GOMAXPROCS подбирают под фактическую квоту CPU.

Семафор ограничивает параллелизм

Если каждая из тысяч горутин уходит в блокирующий syscall, потоков не хватает (урок). Решение — ограничить, сколько горутин одновременно могут быть «в syscall»: перед вызовом горутина занимает одно из N разрешений, а после — освобождает. Простейший семафор — буферизованный канал:

sem := make(chan struct{}, N) // N разрешений
sem <- struct{}{}             // занять: при занятых N — блокировка
<-sem                         // освободить

Подробнее такой семафор разобран в уроке; здесь важна сама идея: блокирующий I/O — дефицитный ресурс, его лимитируют явно. Именно этот скелет Миша и поставил на экспорт архивов.

GOMAXPROCS — под квоту CPU

Второй рычаг — GOMAXPROCS, но работает он не так, как иногда советуют. Поток, заблокированный в syscall, не занимает P и не учитывается в лимите GOMAXPROCS: P перехватывает другой M, а новые потоки runtime заводит сам, по потребности — их может быть больше числа P (предел в runtime велик, урок). Поэтому поднимать GOMAXPROCS выше числа ядер «ради застрявших потоков» не нужно: это не добавляет запасных потоков, а лишь добавляет конкуренцию за ядра и лишние переключения. GOMAXPROCS подбирают под фактическую квоту CPU — в контейнере под её лимит — и проверяют измерениями; универсального рецепта нет. Ровно так Миша и разобрал настройку Димы: тот лечил несуществующую проблему.

Что важно понять

Сетевой I/O не нужно лимитировать ради спасения потоков — poller; семафоры для сети ставят ради пулов соединений и защиты бэкенда. Дисковый — нужно: это редкий и дорогой ресурс. Знание механики из превращается в инженерные решения: где ставить семафор, как настроить GOMAXPROCS, сколько воркеров в пуле.

В следующем уроке

Вы узнаете:

  • как GOMAXPROCS взаимодействует с контейнерными лимитами CPU
  • чем семафор отличается от воркер-пула для дискового I/O
Задание · вопросы

Проверьте себя

Вопрос 1 из 3

Подъём GOMAXPROCS выше числа ядер при блокирующих syscall'ах — что даёт?

Вопрос 2 из 3

Из чего выводят число лимита на одновременные блокирующие вызовы?

Вопрос 3 из 3

Какой главный рычаг при массовом блокирующем дисковом I/O?

Итоги

Под нагрузкой блокирующих syscall: семафор-лимит на число одновременных вызовов; поток в syscall не занимает P, новые M создаются автоматически; GOMAXPROCS подбирают под квоту CPU, а не под число застрявших потоков. Проверяется измерениями.

Наш сайт собирает куки. Чтобы тебе было удобнее им пользоваться. Нажимая на кнопку, ты даёшь разрешение собирать куки