К нам обратился заказчик, который хотел улучшить архитектуру высоконагруженного ресурса на основе Moodle. Сайт имел привычку падать при высокой нагрузке. Ничего необычного, подумали мы. Берем

Нетривиальность задачи оказалось в том, что кейсов инсталляции сервисов Moodle на ресурсы с нагрузкой >10 тыс. человек нет ни у Яши, ни у других сервисов, к которым мы привыкли. Из коробки ничего не работало, документации тоже не нашлось. Предыдущий исполнитель с задачей не справился и оставил сервис в печальном состоянии.

Срок выполнения задачи  – 2 месяца, что добавило остроты проекту перед Новым годом…


Исходные данные

Легкое ощущение запутанности

Ресурс (сайт) для проведения онлайн-тестирования с использованием системы Moodle со следующими характеристиками:

  • нагрузка на ресурс периодическая: в пиковые нагрузки - до 12 тыс. онлайн пользователей, в период простоя ~200 человек.

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

  • архитектура: 20 постоянно работающих серверов с разными базами данных в разных дата-центрах, где каждый сервер находился в регионе присутствия компании. Это огромная, неповоротливая архитектура, где для любого обновления нужно делать привязку к каждому отдельному серверу.

  • подготовка сводной аналитики: данные раз в несколько дней выгружали из каждой базы данных и скриптами сводили вместе все отчеты.

  • базы данных представляли собой модульную объектно-ориентированную динамическую среду обучения – Moodle. 

Налицо неэффективная система обработки данных.

Заказчик столкнулся с проблемой перегрузки серверов и решил ее, просто увеличив количество серверов в 5 раз (хехе). Решение ожидаемо привело к расходам и сложностям со сведением данных с разных серверов в одну базу.

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

Тут, собственно, задача и попала к нам.

Задачи разработки

Основной запрос – оптимизация архитектуры ресурса. Мы предложили спроектировать архитектуру с динамически изменяемым количеством серверов в зависимости от нагрузки.

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

Итак: знаем что делать, но не знаем как. (пока)

Обратный отсчет

Мастера планирования в деле

Для решения задачи наштормили несколько вариантов. Времени делать сложносочиненные решения не было…

Вариант 1: использовать Yandex Cloud (YDB) для создания отдельного программного модуля – коннектора, поддерживающего нативный интерфейс MySQL.

Для Moodle-системы это выглядело как подключение к базе данных MySQL, а коннектор транслировал запрос в YDB.

Сложности подхода: часть функций не поддерживалась, т.е. невозможно было реализовать полную совместимость с MySQL очевидными и быстрыми методами, из коробки. Нагрузочное тестирование показало слабые результаты. Показатели были существенно ниже обычных для MySQL.

От идеи быстро отказались и погнали дальше.

До сдачи 52 дня.

Вариант 2: использование оркестратора базы данных Vitess. Vitess был создан в 2010 году для решения проблемы масштабируемости MySQL, с которыми тогда столкнулась команда YouTube. Пиковая нагрузка превышала пропускную способность базы данных, а использование прокси-сервера между приложением и базой данных для маршрутизации и управления взаимодействием с базой данных позволило решить эту проблему.

Вдохновившись этой историей, мы попробовали взять в работу Vitess.

Ограничивающим фактором стало отсутствие адекватной документации. В результате тестирования получили схожие с первым вариантом результаты. Решение просто не стало работать в режиме кластера!

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

До сдачи 41 день.

Настало время последнего варианта. Скажем прямо – на первый взгляд он выглядел так себе… Но, параллельно с работая над предыдущими вариантами, мы проводили ресерч и тесты и постепенно пришли к мысли, что при качественной проработке это может стать хорошим решением.

Лучшее - враг хорошего

Когда ты уже свой в бардаке

Вариант 3: остаться на используемой базе MySQL в режиме кластера из одной ноды (экземпляра). Тут следует заметить, что предыдущий исполнитель, к которому обращался заказчик, решить такую задачу не смог. Он ушел с используемой заказчиком базы и создал множество инстансов баз данных и сервисов Moodle. Его подход, конечно, не нашел продолжения в новой архитектуре. Но идея с базой данной прижилась!

Нам удалось применить однонодовую конфигурацию кластера базы данных MySQL. Мы проверили ее оптимизацию и доработали конфигурации для работы с максимальной нагрузкой на ресурс.

Такой результат был получен за счет "тонкой" конфигурации кластера MySQL в соответствии с поставленной задачей, что позволило достигнуть требуемой пиковой нагрузки на одном экземпляре базы данных

Вова Завьялов, архитектор проекта

Использовали Yandex Managed Service for MySQL® на базе инфраструктуры Yandex.Cloud в качестве платформы для управления кластером базы данных. Конфигурация сервера была следующая:

  • CPU 96 ядер;

  • RAM 192 ГБ;

  • SSD 512 ГБ.

Создание централизованного хранилища

Когда на карту поставлены все котики

До сдачи 30 дней...

Исходная архитектура заказчика была примерно эры динозавров, поэтому мы провели миграцию всех структур и данных на современную контейнерную архитектуру. Но и тут появились проблемы, с которыми мы просели еще на неделю как минимум..

Проблема 1

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

Оптимизация и адаптация подразумевала необходимость централизовать хранилище, сведя все кластеры серверов в единую систему.

Проблема 2

Проблемой заказчика была трудоемкость работы с базами. Каждый сервер имел свой отдельный moodle, базу данных и файловые системы.

Чтобы свести все данные с каждого сервера использовались заклинания скрипты. Как понимаете, это приводило к хаосу. Идентификаторы связанных серверов пересекались и происходила перезапись данных.

Из хаоса в систему

Чтобы исключить подобные ситуации мы создали сетевое централизованное хранилище.

Хранилище имеет максимальную скорость чтения и записи до 8 Гбит/сек.Доступ к дисковому хранилищу организован через протоколы NFS (network file storage). Настроили RAID-массив и выделили хранилище в отдельный сервер, работающий на CentOS. После проведения тестирования мы перевели платформу на новый уровень порядка и организации и получили достаточно высокопроизводительное хранилище, которое гибко интегрировалось со всеми серверами.

Ищем равновесие

Системе был необходим дирижер динамической архитектуры. В его роли выступил балансировщик нагрузки (!!!), который при росте количества пользователей автоматически создает новые сервера, а при снижении – удаляет сервер через несколько минут после того, как нагрузка спала.

Мы использовали в проекте L7-балансировщик, что позволило в нагрузочном тесте сгладить итоговые результаты за счет поддержки функции Session Affinity, когда балансировщик запоминает пользователя и закрепляет его за определенным сервером бэкенда, что в свою очередь снижает нагрузку на файловый кэш.

По срокам мы вроде еще успевали, но нельзя недооценивать последние этапы.

Итоги

Еще около 12 дней ушло на развертывание сервисов, нагрузочное тестирование и ввод в эксплуатацию. Еще одна непредвиденная проблема и мы бы жестко пролетели со сроками. К счастью, ее не случилось.

По итогу мы собрали пазл из разрозненных серверов в централизованный ресурс. 

Для этого:

  • провели централизацию базы данных;

  • выполнили оптимизацию конфигурации кластера базы данных MySQL для  работы с пиковой нагрузкой до 12 тысяч пользователей;

  • вывели кэш сессий в Redis;

  • использовали L7-балансировщик для распределения нагрузки между серверами;

  • для хранения пользовательских временных файлов создали отдельный NFS-сервер, который может работать на скорости до 8 Гбит/сек.

Заказчик получил централизованную систему, единый Moodle, который может работать при максимальной нагрузке (см пикчу)

Структура управляющей программы

Решена проблема сведения результатов онлайн тестирования из разных баз: теперь данные отображаются в единой базе и администратору доступны сразу все отчеты.

По цифрам

Резко упала стоимость ресурсов в момент простоя платформы. Это главное.

Учитывая сезонность работы сайта, когда большую часть года ресурс работает с минимальной нагрузкой, и только несколько месяцев в году происходит резкий рост пользователей, методы балансировки нагрузки позволяют мощно сократить финансы.

Когда нагрузка отсутствует, ненужные сервера не запущены и заказчик за них не платит.

Сэкономленные деньги - это заработанные деньги

Расчет стоимости ресурсов идет в зависимости от нагрузки на сайт за 1 секунду. 

Итого сервис располагает серверами:

  • баз данных;

  • файлового хранилища;

  • сервисные сервера;

  • сервера бэкенда;

  • сервера-балансировщики нагрузки, которые создаются под обработку запросов.

Серверов-балансировщиков в пиковые нагрузки  может быть до 24 шт. В момент простоя работают только сервер базы данных, сервер хранилища, сервер кэша и один сервер для обработки пользовательских запросов.

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

Нагрузочное тестирование показало предельное RPS 200 (Requests Per Second  – количество запросов за одну секунду).  Цифра превзошла наши ожидания: для нашего проекта это эквивалентно работе 16 тысяч пользователей.

Валера Ковальский, разработчик

Когда разработал в срок в канун НГ

В итоге, Заказчик получил сайт 30 декабря. А мы ушли восстанавливаться :-)