К нам обратился заказчик, который хотел улучшить архитектуру высоконагруженного ресурса на основе 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 декабря. А мы ушли восстанавливаться :-)

Комментарии (5)


  1. polearnik
    31.08.2023 15:01
    +5

    200 RPS для mysql на сервере с CPU 96 ядер? почему так сильно был нагружен сервер? на типичные запросы смотрели? модет надо было индексов добавить? или нагрузка шла во время создания сводных отчетов? тогда вроде как решается репликой на которой и запускают тяжелые запросы


  1. Akuma
    31.08.2023 15:01
    +5

    А что это было конкретно?

    Что за монстр с 96 CPU и 192 ОЗУ держит всего 200 RPS на обьеме в 500 Гб? Зачем это вообще? Засуньте все в память и будет вам скорость, если уж так надо. Может 200 тыс rps?

    Аналогично с балансировщиками. 24 отдельных сервера для липких сессий? Чем не устроил один? Nginx на VPS за тысячу в месяц сбалансирует 200 rps и не чихнет даже.


  1. vitaly_il1
    31.08.2023 15:01

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


  1. headliner1985
    31.08.2023 15:01
    +1

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


  1. savostin
    31.08.2023 15:01
    -1

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