Блог Amazon Web Services

Миграция кластеров NoSQL DB между регионами AWS

Андрей Зайчиков, Архитектор AWS

Роман Скваж, CTO FunCorp

Александр Домнин, SysOps Engineer FunCorp

Всем привет!

Сегодня у нас в гостях замечательные специалисты и просто хорошие люди из компании FunCorp — Роман Скваж (CTO) и Александр Домнин (SysOps). Мы расскажем вам об одном интересном проекте по миграции больших кластеров нереляционных баз данных между регионами AWS (из Европы в США).

Что мигрировать?

По словам Романа Скважа: «Флагманский продукт компании — iFunny (https://ifunny.co/) одно из наиболее популярных развлекательных приложений среди американской молодежи. За 5 лет сервис обзавелся внушительной аудиторией: мобильные приложения обслуживают более 3,5 миллионов активных пользователей в день и работают во всех часовых поясах.  Backend приложения полностью реализован на Amazon Web Services и его масштаб впечатляет:

  • Кластер Apache Cassandra — 25 узлов, 18 TB данных;
  • Кластер Apache Cassandra — 18 узлов, 16 TB данных;
  • Кластер MongoDB — 5TB данных, распределенных по 8 shard’ам, каждый shard — ReplicaSet из Master и двух Slave;
  • Кластер MongoDB — 150GB данных, распределенных по 4 shard’ам, каждый shard — ReplicaSet из Master и двух Slave;
  • Кластер Elasticsearch — поисковый индекс объемом 1 TB;
  • 3 ReplicaSet Redis — Master + 2 Slave с 15 GB, 10 GB и 1 GB данных и крайне высокой скоростью записи.

Силами наших DevOps и Backend команд, нам предстояло перенести все это из одного региона AWS в другой без downtime и крупных изменений в приложении. При этом желательно было не задействовать сторонние приложения и платные сервисы».

Зачем мигрировать?

Наверняка у вас возник резонный вопрос. А зачем вообще все это переносить? Ведь работает?

Ответ на этот вопрос, как это ни странно, довольно прост. Начальный выбор региона для размещения приложения был сделан исходя из близости к одному рынку, а приложение получило наибольшую популярность в совсем другой географии. До определенного момента обращение к backend на другом континенте не причиняло особых неудобств. Однако, повышенный latency сильно влиял на User Experience и коллегам очень хотелось его улучшить. В связи с чем и было принято решение о переезде backend’а.

На процесс миграции был наложен ряд условий и ограничений:

  • Нулевой downtime;
  • Отсутствие изменений в приложениях и структуре БД;
  • Минимальное использование сторонних инструментов.

Забегая вперед, скажем, что перенос backend позволил снизить latency для конечных пользователей при обращении к API на 40%.

Как мигрировать?

Поначалу мы попытались решить вопрос, что называется, “в лоб”. Каждая из перечисленных выше БД (кроме Elasticsearch) обладает собственными возможностями по гео-распределенной репликации.

Однако, после начала процесса репликации, мы столкнулись с несколькими существенными проблемами. Вполне естественно, что для каждой БД они были свои.

MongoDB
Первая проблема касалась MongoDB, а именно, mongos процессов. Сама репликация прошла относительно спокойно и была выполнена только с использованием штатных средств MongoDB. Но после переключения пользователей на новый backend MongoDB производительность mongos в США существенно упала. Буквально в разы. Дело в том, что на текущий момент, гео-распределенный кластер MongoDB поддерживает только один набор конфигурационных серверов, которые на тот момент располагались в другом регионе (Европе).

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

Хорошая новость заключалась в том, что mongos кэширует конфигурацию. При этом возникает следующая проблема – нельзя увеличивать количество chunk’ов или реорганизовывать данные между ними (иначе кеш mongos будет инвалидироваться и сами mongos будут постоянно обращаться к конфигурационным серверам на другом континенте), соответственно, миграция серверов конфигурации должна была произойти довольно быстро. Сам алгоритм миграции выглядел следующим образом.

  1.  В первую очередь, мы заранее создали новые инстансы в целевом регионе с конфигурацией, идентичной текущей и включили их в существующие ReplicaSet исходных кластеров. Затем дождались окончания репликации данных.
  2. Непосредственно перед переездом отключили балансировку mongos. Таким образом, mongos кластера в целевом регионе использовали кэшированную версию конфигурации.
  3. Во время переезда поочередно вывели все инстансы с данными в старом регионе. В ReplicaSet`ах остались только инстансы в целевом регионе, среди которых стандартными средствами MongoDB выбрались новые Primary-сервера.
  4. На последнем этапе была выполнена миграция конфигурационного ReplicaSet в новый регион.

Cassandra

Для переноса кластеров Cassandra мы создали дополнительные DC со стандартным EC2Snitch в целевом регионе и подключили их к существующим кластерам через software VPN туннель – подняли ноды и начали репликацию. VPN туннель был необходим для того, чтобы при миграции данных между регионами не пришлось проводить трудоемкую процедуру смены Snitch с EC2Snitch на EC2MultiRegionalSnitch, которая в нашем случае подразумевала не только смену самого Snitch, но и ручное масштабирование кластера, поддержку списков адресов в Security Groups, взаимодействие между узлами по публичным IP (авторизация на уровне кластера была отключена). При использовании VPN между регионами Cassandra позволяет реплицировать данные с EC2Snitch.

Сразу после запуска процесса репликации производительность исходного кластера Cassandra упала в разы. Дело в том, что Cassandra начала реплицировать данные всех SSTable в новый DC одновременно на все узлы с учетом нашего фактора репликации и уровня консистентности, что дало примерно следующую картину (только многократно помноженную на количество узлов и фактор репликации).

Для того, чтобы решить эту проблему мы остановили репликацию кластеров и начали проводить rebuild узлов целевого кластера по частям – по два-три node’а за один раз. Оба кластера с таким подходом были реплицированы в течение двух недель без остановки работы и практически без снижения производительности.

По окончании процедуры репликации был проведен repair всех узлов целевого кластера, после чего приложения были отключены от исходного DC, он был исключен из кластера и остановлен.

Redis

Миграцию Redis мы начали по схожей схеме – создали новые кластера, подключили к уже существующему кластеру в исходном регионе и стали ждать … Объем мигрируемых данных был незначительный, однако данные менялись с очень большой скоростью. Это приводило к тому, что данные не успевали реплицироваться в рамках определенного для кластера максимального Replication Window, после чего все данные в целевом кластере инвалидировались.

Мы рассматривали несколько разных решений, включая использование DirectConnect, WAN Optimization, Replication Acceleration и других. Подробнее о каждом из них расскажем ниже.

После нескольких недель размышлений и поисков мы нашли простое решение проблем с репликацией Redis.

  1. Устанавливаем SSH туннель с компрессией и «пробрасываем» порт репликации на localhost: ssh -C -L 6280:localhost:6379 $MASTER_REDIS
  2. Говорим slave синхронизироваться с localhost вместо синхронизации с master: redis-cli slaveof localhost:6280

Готово. Теперь репликация Redis проходит успешно поскольку за счет компрессии replication lag не растет и не достигает критического порогового значения Replication Window.

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

Хорошая новость заключалась в том, что для ElasticSearch есть отличный plug-in, который позволяет делать backup’ы, в том числе инкрементные. Найти его можно здесь.

Процесс переноса ElasticSearch выглядел довольно просто:

  1. Создаем кластер ElasticSearch;
  2. Создаем Bucket в S3 и включаем версионность и cross-regional replication;
  3. С помощью ElasticSearch plug-in создаем snapshot основного массива данных и записываем его в S3. Snapshot автоматически передается в новый регион;
  4. Восстанавливаем данные из snapshot в целевом регионе;
  5. Выполняем шаги 3-4 для инкремента (в нашем случае операция по переносу инкремента заняла порядка 12 минут).

А были ли еще варианты?
На проекте мы рассматривали несколько альтернативных вариантов, которые могут помочь в миграции больших объемов данных. Мы кратко опишем эти варианты, а также лучшие практики по использованию каждого из них.

AWS Direct Connect
Данный сервис предоставляет надежный выделенный канал связи и идеален для случаев, когда необходимо обеспечить взаимодействия собственных мощностей в своем ЦОД или co-location с облаком AWS. Подробнее тут.

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

AWS Import / Export
Сервис AWS Import/Export Disk позволяет одномоментно загрузить большие объемы данных в AWS и нередко является более быстрым решением, нежели организация передачи данных по каналам связи. Он использует физические носители для передачи данных в заданный регион и загрузки данных в объектное хранилище S3. Более подробная информация доступна здесь.

WAN Optimization
WAN Optimization – это набор технологий и продуктов, которые позволяют оптимизировать использование WAN канала за счет нескольких основных техник:

  • Де-дупликация пакетов;
  • Сжатие траффика;
  • Кеширование;
  • Улучшенная обработка ошибок передачи данных;
  • другие.

WAN оптимизация реализуется на двух основых уровнях модели OSI – транспортном (L4 – TCP) и уровне приложений (L7 – обычно HTTP).

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

WAN Optimization deployment включает в себя специализированное программное / аппаратное обеспечение, устанавливаемое на обоих концах соединения. После чего траффик по определенным портам пропускается через него.

На текущий момент, на AWS Marketplace доступно несколько основных решений по WAN Optimization, включая Riverbed, SilverPeak, Citrix, Barracuda и Sangfor и других.

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

Хотелось отметить, что все рассматриваемые альтернативные варианты решения отлично подходят для многих вариантов использования, в числе которых:

  • Постоянная работа приложений и баз данных в гибридной среде;
  • Перенос больших (сотни Тб) объемов данных в облако и из облака AWS;
  • Оптимизация использования вычислительной сети без оптимизации работы приложений;
  • Множество других вариантов использования.

Вместо заключения
Миграция баз данных – всегда сложный процесс, требующий внимания к деталям. При миграции всегда могут возникнуть неоднозначные ситуации, нестандартное поведение движков баз данных, существенное влияние сети на процесс. Самый лучший и безопасный путь провести миграцию без потерь и сюрпризов – проверить на реальных данных и с реальными конфигурациями, и уже после переносить «боевые» базы в новое место. Даже если ваше приложение не “cloud-native”, использование облачных сервисов позволяет получить возможность экспериментировать – воспроизвести реальный use-case в географически распределенной среде на реальном масштабе кластеров и данных. Пользуйтесь ею!

На этом на сегодня, пожалуй, все.

Спасибо нашим сегодняшним гостям — компании FunCorp!

Следите за следующими постами — будет интересно.