DEV Community

Mikhail
Mikhail

Posted on

Highload Junior. 1. HighLoad++ для начинающих

Проблематика

Высокая нагрузка - это нагрузка, с которой по какой-то причине не справляется железо (не хватает CPU или памяти).

На данный момент с развитием железа проблемы его нехватки отпали, если приложение тормозит, то в 99% случаев это косяк в архитектуре.

Расммотрим рядовую операцию на бэкенде

  1. Прием данных по сети
  2. Парсинг полученных данных
  3. Взаимодействие с БД
  4. Формирование ответа
  5. Отправка ответа клиенту

Самый простой способ реализовать эту операцию - использовать один поток на один запрос. Но тогда быстро упремся в кол-во обрабатываемых запросов в секунду.
Далее можно увеличить кол-во используемых котоков или процессов, распределить нагрузку между несколькими серверами.
Однако все это не даст значительного прироста в RPS - он останется в пределах нескольких сотен.

При этом если проанализировать, сколько времени выполняется каждый из пунктов в операции на бэкенде, то увидим, что:

  • Прием данных по сети - 15к в сек

  • Парсинг полученных данных - 15к в сек

  • Взаимодействие с БД - 60к в сек

  • Формирование ответа - 100к в сек

  • Отправка ответа клиенту - 15к в сек

Если этого все сложить по формуле

1/sum(1/freq(i))

то получим 6к запросов в секунду, а не условно 500.

В таких случаях нужно заняться профайлингом. Тогда увидим, что код выполняется процессором от силы 10% всего времени, а остальное времени идет ожидание от БД и сети.

Событийно-ориентированная архитектура

Решить предыдущую проблему поможет изменение парадигмы программирования.

Событийно-ориентированная архитектура подразумевает, что выполнение программы определяется событиями, на которые осуществилась "подписка". То есть мы говорим, что когда поступит событие успешного сохранения в БД, сделай то-то.
Это то-то определяем в колбеке, который передаем отдельным аргументом. Из-за этого придется менять основную часть кодовой базы, которая крутится вокруг взаимодействия по сети.

Также приходится решать проблемы, связанные со сменой парадигмы.

  • сохранение контекста между колбеками

  • обработка исключений

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

Green Threads

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

Тогда если соединить вместе друг с другом свой планировщик и машину событий, то получим таком порядок выполнения операции:

  1. Регистрация событий в машине состояний
  2. Передача управления планировщику
  3. При наступлении события планировщик будит зеленый поток
  4. Программа работает с данными от события, которое наступило в пред. пункте

Т.е. зеленый поток усыпляется до тех пор, пока не наступает событие.

Такой подход подразумевает использования библиотеки для использования зеленых потоков и написания кода-оберток над БД и сетевых вызовов.

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay