Перенос проектов между ЦОДами. Часть 2

Apr 9, 2019 01:09 · 897 words · 5 minutes read ЦОД Миграции Проект

С чего начать и что делать?

Определиться с требованиями:

  • выделить роли контейнеров
  • единая точка для service-discovery (front контейнеры)
  • приложение должно получать конфигурацию через env переменные или dot.env файлы
  • доступ к ресурсам только через haproxy или фронты
База данных Percona

Необходимо получить реплику БД в нашем проде. Решив эту проблему, мы бы смогли перетащить данные в dev и встроить обновление данных в нашу баз данных.

Сервер с базой данных (Percona):

  • 600GB данных на ext4
  • 4 Kq/s.
  • находится в Нижнем Новгороде (НН)
  • может не подняться после ребута

Чтобы получить реплику, мы подцепили наш сервер обычным слейвом, в обход percona xctradb. Так было сделано потому, что для полноценной интеграции в кластер, необходимо было перезагрузить инстанс percona. 600 Gb данных переливались примерно 3 дня, так как канал между цодами НН и Урал у нас ограничен. 600Gb на zfs превратились в 400Gb. К этой реплике мы подключили percona кластер на zfs, и уже с него начали снимать zfs снэпшоты, для отправки в dev. Так у нас появилась БД в нашем дев окружении.

Sphinx

Когда данные появились в кластере, то получить из него индексы для сфинкса было делом техники. Пакет sphinx под arch linux был уже собран и протестирован. Все свелось к настройке параметров индексации данных БД в поисковые индексы. Полная индексация sphinx занимает около 6 часов.

Openstack Swift

Самая тяжелая часть приложения. 20ТБ статики, которую необходимо перенести. Swift оперирует следующими понятиями: - object - наименьшая единица информации - файл с картинкой, extended attributes - container - хранилище групп объектов. Напоминает папку с файлами - ring - группа инстансов swift

Как работала раздача статики:

  • нужно раздавать картинок, либо кропы картинок
  • поднят nginx, в котором настроена большая кэшзона на 350GB для статики
  • при cache miss запрос уходит в swift, результат складывается в cache
  • при отсутствии картинки в swift, предполагается что это запрос картинки на кроп
  • запрос уходит на сервис ресайза, итог ресайза складывается в специальный контейнер swift и отдается в stdout
  • результат кропа сохрянеятся в кэшзону

Что сделали:

  • добавили инстанс swift в ЕКБ к кольцу серверов в НН
  • поставили максимальный вес для нового инстанса swift, чтобы новые картинки сохранялись туда
  • попробовали перелить данные средствами swift - медленно

Проблема в том, что расположение файлов на файловой системе не соответсвует контейнерам. То есть нельзя по расположению объекта на файловой системе понять, к какому контейнеру он относится. Пришлось запускать rsync -rv и перекачивать все данные. Переливка заняла примерно 14 дней. Вроде все работает, файлы сохраняются, раздаются.

Memcached

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

Тут может быть несколько вариантов организации доступа к memcached.

  1. Поднимаем haproxy и через него балансируем запросы, добавляем health чеки. 1 инстанс мастер, другой backup
  2. Используем шардирование ключей по нескольким инстансам (twemproxy, mcrouter, dynomite)

Мы решили попробовать пойти по 2му варианту, но: twemproxy не умеет отдавать правильный ответ на команду version; mcrouter имеет очень много зависимостей и сложно собирается под arch; с dynomite тоже возникли некоторые проблемы.

Было решено использовать 1 жирный memcached и ходить в него через haproxy. Выделяется основной memcached, 2й ставится бэкапным. При возникновении проблем с основным инстансом, haproxy переключится на резернвый.

PHP7 + laravel

Часть проекта была на php7.1, что хорошо. Плохо, что была россыпь репозиториев, в которые были выделены сервисы проекта. Общая база, общий memcached, общий sphinx. Все пересекается. Каждый сервис имел свой клиент, который был реализован на lumen. Неиспользуемые файлы не были почищены. Функционал и роутинг каждой составляющей сервиса так же в отдельной репе. Как этим всем пользоваться:

  • пишем сервис
  • пишем клиента для этого сервиса
  • пишем laravel пакет, в котором реализуем функционал с использованием только этого сервиса. Роутинг зашиваем сюда же.
  • подключаем к проекту
  • имеем 1 пустую монорепу, к которой подключается > 10 пакетов

Что еще имеем, к вышесказанному:

  • фасады laravel, что ломает нативную работу IDE
  • отсутствие тестов, то есть единственный профит фасадов не используется
  • laravel - конфиги production внутри git
  • нет единой системы конфигурирования
  • отказоустойчивость - haproxy на другом хосте
  • логи отправляются по http
PHP56

Большая часть проекта написана на php56. Основная бизнес-логика так же там. 1.3M строк кода. Отсутствие роутинга, только вызов конкретных файлов. Подключены все библиотеки php, которые возможно. По коду захардкожено > 100 ip адресов, везде абсолютные url, при подключении файлов. В том числе и в js+css.

Что сделали

Необходимо было собрать php56, php71 под arch linux. На момент проведения этих действий, актуальный пакет php > 7.2. Провели аудит кода на предмет использования php extensions. Выяснилось, что больше половины расширений не нужно и в принципе не используется. Некоторые расширения можно удалить, переделав все немного по другому. Например memcache -> memcached. После того, как стало понятно, какой набор софта нам необходим, собрали необходимые пакеты. Для того, чтобы начать разрабатывать, мы собрали тестовые среды (у нас это набор контейнеров + бд). Попробовали завести код, который работает на php7. Микросервисы вызывают микросервисы. Начали конфигурировать сервисы через конфиг, который генерируется при старте контейнера. Он может измениться в любой момент времени. Весь сервис дискавери зарулили на фронты. Только фронты знают, где находится тот или иной сервис. Фронтов у нас 2. Доступ ко всем внешним ресурсам организовали через haproxy, который стоит на контейнере с каждым сервисом.

Со 2й частью проекта оказалось все сложнее. Там еще был и apache -> >100 файлов .htaccess внутри проекта.

  • убрали неиспользуемые расширения php
  • выпилили часть сервисов, которые не нужны
  • убрали хардкод ip адресов
  • убрали конфиги внутри приложения
  • переписали конфиги apache на nginx
  • подняли prod сервера и начали использовать из для теста
Полезные инструменты