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

Сеть против диска

В пятницу файл на NFS-шаре «повесил» сервис, хотя с сетью тот работал без нареканий. Инцидент стал первым, где сеть и диск проявили себя как разные дороги.

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

сеть работает через poller и не блокирует потоки, а дисковый I/O — это честный блокирующий syscall, который реально держит поток в ядре.

Два разных пути ожидания

Сетевое чтение, которое должно бы блокироваться, не вызывает блокирующий syscall: горутина паркуется, дескриптор регистрируется в network poller, и M освобождается немедленно. Никакого потока в ядре не застревает.

Дисковый ввод-вывод устроен иначе. Чтение файла — это блокирующий syscall: горутина и её поток уходят в ядро вместе и возвращаются вместе. Пока ядро ждёт диск, поток занят.

Оговорка: через poller не ходят именно регулярные файлы; нерегулярные (FIFO, терминалы, сокеты) могут идти через него. Для обычных файлов картина как выше.

Что это значит для кода

Отсюда практическое правило: сетевые блокировки «бесплатны» (не тратят M), а дисковые — дороже, потому что реально держат поток. Сервис с десятью тысячами сетевых соединений — норма. Сервис с десятью тысячами одновременных дисковых чтений — уже история про исчерпание потоков (урок).

conn.Read(buf)   // сеть: парковка, поток свободен
file.Read(buf)   // диск: поток уходит в ядро

Практическое следствие

Именно поэтому дисковый I/O под нагрузкой ограничивают — семафорами и воркер-пулами (уроки,), а сетевой — не принято. И поэтому же context с таймаутами критичен для сетевых вызовов: горутина может «ждать сеть» вечно, если никто не отменит (урок).

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

Вы узнаете:

  • почему диск не встроили в poller
  • как entersyscall работает для диска
Задание · вопросы

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

Вопрос 1 из 3

Сервис с 100 000 одновременных вебсокетов — нужно ли лимитировать горутины?

Вопрос 2 из 3

Почему таймауты критичны именно для сетевых вызовов, а не для дисковых?

Вопрос 3 из 3

file.Read паркует горутину и освобождает поток?

Итоги

Сеть — poller, диск — блокирующий syscall. Один поток на тысячу сетевых ожиданий, но один поток на каждое дисковое. Отсюда — разная инженерная стратегия.

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