/
/
Миграция высоконагруженного магазина

Миграция высоконагруженного интернет-магазина на отказоустойчивую инфраструктуру

О клиенте

Клиент развивает крупный интернет-магазин на базе 1С-Битрикс. Проект состоит из отдельного фронтенда на Node. js, нескольких серверов бэкенда, базы данных, систем кеширования и вспомогательных сервисов.

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

Исходная ситуация

На момент начала работ приложение было распределено между несколькими серверами, но ряд критических компонентов оставался единичным. Весь входящий трафик проходил через один балансировщик, а общая кодовая база и пользовательские файлы хранились на одном NFS-сервере.

База данных работала на двух узлах MariaDB с Galera, однако автоматический failover не был настроен. Взаимодействие между узлами базы проходило по внешней сети. PHP-код исполнялся непосредственно на серверах, процессы развертывания фронтенда и бэкенда отличались друг от друга, а значительная часть конфигурации зависела от конкретных хостов.

При этом проект нельзя было просто перенести на новые серверы. В коде были модификации ядра 1С-Битрикс, большое количество собственных SQL-запросов и сильная зависимость от Redis и Memcached. Административная часть работала медленно, а обновление платформы было затруднено.

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

Какие проблемы мы обнаружили

Единичные точки отказа
Несмотря на наличие нескольких frontend- и backend-серверов, доступность приложения зависела от единичных инфраструктурных компонентов.

Один HAProxy принимал весь внешний трафик. При его отказе остальные серверы не могли обеспечить доступность сайта. Аналогичная ситуация сложилась с NFS: один сервер использовался как общее хранилище кодовой базы и файлов.

NFS создавал не только риск полной недоступности. Механизмы файловых блокировок PHP и сетевой файловой системы приводили к дополнительным задержкам. Производительность приложения зависела от состояния сети и одного хранилища.
Кластер базы данных не обеспечивал ожидаемой надежности
База данных была развернута на двух узлах MariaDB с Galera. Такая конфигурация не обеспечивала полноценного кворума и автоматического переключения при отказе одного из узлов.

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

В результате кластер усложнял эксплуатацию, но не давал требуемой отказоустойчивости.
Инфраструктура была связана с конкретными серверами
Конфигурация приложения, файловое хранение и процессы обновления зависели от существующих хостов. Для локального запуска не было полностью рабочего Docker Compose, а параметры среды не везде передавались через переменные окружения.

Бэкенд обновлялся через операции с Git на нескольких серверах. Процесс требовал синхронного выполнения действий и оставлял риск различий между экземплярами приложения. Сборка фронтенда также зависела от отдельного GitLab Runner и сложившегося окружения.

Это мешало воспроизводить среду, тестировать изменения до публикации и переносить приложение между площадками.
Кеширование стало обязательной частью работоспособности
В проекте одновременно использовались Redis и Memcached для разных типов данных. Часть приложения предполагала постоянную доступность кеша.

Кеш перестал быть только средством ускорения. Сбой отдельного экземпляра Redis или Memcached мог влиять на пользовательские сессии и работу приложения. В ходе сопровождения фиксировались перезапуски Redis и проблемы с PHP-сессиями.

Архитектура кеширования была разнородной, а ответственность отдельных компонентов пересекалась.
Не было единого контура наблюдаемости
Часть мониторинга существовала, но в начале работ не было полного доступа к объективным данным о состоянии всех компонентов. Требовалось отдельно подключать серверы, базы данных, Redis, RabbitMQ и сайты к системам мониторинга.

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

Команде разработки требовалось перенести код в систему контроля версий, вынести настройки в переменные окружения, проверить механизм миграций 1С-Битрикс и начать перенос пользовательских данных в объектное хранилище.

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

Что было сделано

1
Принятие проекта на сопровождение и настройка наблюдаемости
Сначала инфраструктуру приняли на поддержку в существующем состоянии. Проверили доступы к серверам и подключили основные хосты к мониторингу.

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

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

Были выделены основные направления:
  • отказ от единственного балансировщика;
  • вывод NFS из критического контура;
  • перенос пользовательских данных в S3;
  • изменение схемы базы данных;
  • контейнеризация фронтенда и бэкенда;
  • унификация кеширующих сервисов;
  • создание воспроизводимого CI/CD;
  • подготовка приложения к запуску в Kubernetes.

Работы разделили на этапы, поскольку перенос инфраструктуры зависел от готовности кода, базы данных и файлового хранилища.
3
Оптимизация существующей среды
До завершения миграции проект продолжал работать на прежней площадке. Чтобы снизить риски переходного периода, были выполнены настройки MariaDB и PHP-FPM.

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

Также прорабатывался отказ от лишних промежуточных балансировщиков. Это уменьшало количество элементов, через которые проходил запрос, и упрощало диагностику.
4
Перестройка базы данных
Вместо прежней двухузловой схемы база данных была перенесена в собственный кластер из трех узлов MariaDB.

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

Позднее инфраструктура базы продолжала развиваться: выполнялись работы по миграции в отдельный кластер, проверке конфигурации, резервному копированию и устранению ошибок восстановления.
5
Вывод файлов из NFS
Пользовательские файлы и статика были перенесены в S3-совместимое объектное хранилище. Для тестовых и рабочих сред использовались отдельные бакеты.

В Kubernetes S3 был подключен к backend-контейнерам через CSI-драйвер. Это позволило приложению работать с файловыми данными без привязки к локальным дискам конкретной ноды.

Переход устранил зависимость от единственного NFS-сервера и позволил независимо масштабировать вычислительные компоненты приложения.
6
Контейнеризация и перенос приложения в Kubernetes
Для фронтенда и бэкенда были подготовлены контейнерные образы и сценарии запуска. Конфигурацию постепенно переносили в переменные окружения и Helm-чарты.

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

После функционального тестирования отдельные frontend- и backend-компоненты были развернуты в Kubernetes. В кластер также переносились кеширующие сервисы, включая отдельный Redis для бэкенда.
7
Перестройка CI/CD
Были подготовлены пайплайны сборки и развертывания контейнерных образов. Для управления публикацией в Kubernetes использовался GitLab CI/CD совместно с Argo CD.

Старый GitLab Runner вывели из эксплуатации, а сборку образов перенесли на новый runner с достаточными ресурсами. Это уменьшило зависимость от прежнего сервера и связало сборку приложения с целевой контейнерной инфраструктурой.

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

В Kubernetes и на вспомогательных серверах разворачивались:
  • ingress-контроллер;
  • управление сертификатами;
  • Prometheus и Grafana;
  • централизованный сбор логов;
  • Argo CD;
  • Redis для отдельных частей приложения;
  • системы обработки ошибок;
  • защищенный доступ к инфраструктуре.

Доступ к внутренним сервисам ограничили VPN-контуром, а публичный трафик направили через сервис защиты от DDoS.
9
Тестирование и поэтапное переключение
Переход выполнялся по частям. Отдельно тестировались база данных, S3, backend, frontend, Redis, сборка образов и маршрутизация.

Во время тестирования выявлялись ошибки приложения, которые не были видны в старой среде: зависимости от имен хостов, некорректные пути к статике, особенности работы с S3 и предположения о доступности Redis.

Такой подход позволял исправлять несовместимости до переключения пользовательского трафика и не переносить старые ограничения в новую архитектуру.

Результат

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

приложение было подготовлено к работе в Kubernetes
фронтенд и часть backend-компонентов перенесены в контейнерную среду
фронтенд и часть backend-компонентов перенесены в контейнерную среду
база данных переведена с двухузловой схемы на трехузловой кластер
пользовательские файлы и статика перенесены с NFS в S3
устранена зависимость файлового хранения от одного сервера
создан воспроизводимый контейнерный сценарий запуска
сборка и развертывание связаны с GitLab CI/CD и Argo CD
старый GitLab Runner выведен из эксплуатации
отдельные кеширующие сервисы перенесены в новую инфраструктуру
расширено покрытие мониторингом и контролем резервного копирования
внутренние инфраструктурные сервисы отделены от публичного доступа
диагностика инцидентов стала опираться на централизованные метрики и логи

Вывод

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

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

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

Смотрите другие
кейсы по Bitrix

    Error get alias

    Хотите передать
    свою инфраструктуру в надежные руки?

    Будем рады проконсультировать вас и обсудить проект.