Pull to refresh
0
1cloud.ru
IaaS, VPS, VDS, Частное и публичное облако, SSL

Как масштабировать Ruby-приложения

Reading time 3 min
Views 13K
Основная цель нашей работы состоит в том, чтобы сделать IaaS простым и понятным даже для тех, кто не сталкивался с ИТ-сферой. Поэтому мы проводим постоянную оптимизацию всех систем и рассказываем о том, что нам удалось сделать, в нашем блоге на Хабре.

Пара примеров:


Сегодня мы решили взглянуть на западный опыт и кратко проанализировать тему масштабирования приложений. Нас привлекло руководство Нейта Беркопека (Nate Berkopec), эксперта по Ruby.


/ фото Juhan Sonin CC

Нейт начинает с того, что говорит о сложности темы в целом. Здесь есть определенная разница между теми методами, которые подходят для масштабирования с 10 до 1000 запросов в минуту, и теми, которые используют компании вроде Twitter для перехода к обработке 600 запросов в секунду.

Особая тяга к масштабированию обычно компенсируется тем, что на определенном этапе у вас возникают проблемы с вводом/выводом в базе данных. Управление количеством процессов, загрузкой ЦП и оперативной памяти усложняют масштабирование для тех, кто разрабатывает приложения на Rails.

Здесь Нейт говорит об использовании Memcached и Redis вместе с RabbitMQ и Kafka. В основном он применял подобные решения на платформе Heroku, которая в целом годится для решения подобной задачи с масштабированием до 1000 запросов в минуту.

Он подчеркивает, что простое добавление Dyno-контейнеров на Heroku не даст желаемого эффекта — приложение не будет быстрее. Эти контейнеры могут лишь увеличить надежность. Если говорить об AWS, то переход с одного типа инстанса на другой (с T2 на M4) уже может оказать влияние на производительность приложения.

Некоторые инсайты из примеров Нейта:

  • Масштабирование может повлиять на время ожидания, если у вас есть очередь
  • Для решения задачи нужно разобраться в принципах работы сервера приложений
  • Документации Heroku не объясняет все нюансы маршрутизации HTTP запросов
  • Веб-приложению на Ruby необходима защита от медленного клиента и отклика
  • Нельзя масштабировать только на основании времени отклика — здесь может играть роль время ожидания в очереди. То же относится и к хостам worker’ов.
  • Веб-приложение может работать не с одной, а с десятками очередей, которые образуются в балансировщике нагрузки, маршрутизаторах Heroku, многопроцессном сервере и в «главном процессе»
  • Закон Литтла позволяет определить число необходимых экземпляров приложения как произведение среднего числа запросов в секунду на среднее время отклика (в секундах). Если начать масштабирование при 25%-й производительности, то это будет что-то в духе фальстарта. Производительность здесь — это отношение числа экземпляров приложения к среднему время отклика.

Маршрутизация запросов


Кратко о том, как устроен этот процесс:

1. В первую очередь запрос встречает балансировщик нагрузки — он распределяет запросы между маршрутизаторами Heroku.

2. Маршрутизатор передает запрос на обработку в случайный контейнер Dyno, который имеет отношение к вашему приложению.

3. Пока маршрутизатор определяется с тем, какой выбрать контейнер, запрос находится в его очереди ожидания. Этот процесс похож на работу nginx и отправку health-check запросов.

Далее с запросом работает выбранный вами сервер:

1. Для Webrick — открывает соединение с маршрутизатором для загрузки запроса, далее запускает ответ маршрутизатору и переходит к следующему запросу. Этот процесс полностью загружает хост и дает ему работать с запросами от других маршрутизаторов.

2. Thin работает немного иначе. Он событийно управляем. Он использует EventMachine, который похож на работу Node.js. Thin принимает запрос по частям, но только после полной загрузки запроса он передает его в приложение. Он хорошо подходит для обработки медленных запросов, но не является многозадачным.

3. Unicorn — это однопоточный, но уже многозадачный веб-сервер. Он построен на worker'ах и прослушивании одного сокета Unix. Здесь ситуация аналогичная — запрос должен быть полностью загружен, поэтому Unicorn не очень подходит для медленных клиентов, как и Webrick. Пока идет загрузка другие соединения не могут быть установлены. Эту проблему решает буферизация запросов, которой и занимается Passenger.

4. Phusion Passenger 5 — он позволяет установить что-то вроде nginx прямо перед worker’ами. В него встроен обратный прокси-сервер, который защитит рабочие процессы от медленных клиентов и загрузок. По мере загрузки запроса его передают HelperAgent'у, который распределяет запросы между worker’ами. Он вполне подходит для масштабирования. Альтернатива — Puma в кластерном режиме или Unicorn в связке с nginx.

P.S. Немного о работе нашего IaaS-провайдера:

Tags:
Hubs:
+10
Comments 14
Comments Comments 14

Articles

Information

Website
1cloud.ru
Registered
Founded
Employees
31–50 employees
Location
Россия