Базы данных

Стратегия постепенного перехода с одной базы данных на другую

Постепенное развертывание миграции с MongoDB на PostgreSQL.

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

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

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

Этот пост призван объяснить стратегию и процесс облегчения миграции в нашей производственной системе.

Общий обзор

Предположим, мы хотим перейти с MongoDB на PostgreSQL.

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

Мы изменим нашу текущую настройку и добавим PostgreSQL в качестве вторичной базы данных.

Как только наше приложение будет нормально работать с PostgreSQL, мы удалим базу данных MongoDB.

Стратегия и подход

Стратегия такова:

Инкрементальный перенос базы данных

Это означает, что мы начинаем использовать PostgresSQL для небольшого процента пользователей и наблюдаем за производительностью и использованием ресурсов нашей системы.

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

Как вы могли заметить, процент пользователей, использующих PostgreSQL, также использует MongoDB.

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

Итак, процесс миграции делится на три части:

1. Стабилизировать операции записи

Это позволяет нам иметь одни и те же данные в обеих базах данных.

  1. Постепенно увеличивайте процент пользователей, использующих новую базу данных.
  2. Это нормально иметь неудачи на стороне PostgreSQL. Но не допускайте сбоя всего входящего HTTP-запроса и/или процесса из-за этой ошибки.
  3. Сосредоточьтесь на стабилизации операций записи.
  4. Данные будут доступны в обеих базах данных, как только операции записи стабилизируются.
  5. Теперь сбой всего входящего HTTP-запроса и/или процесса при возникновении сбоев в любой из баз данных. Это позволяет нам действовать соответствующим образом при сбоях.

2. Стабилизируйте чтение

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

Мы будем следовать тому же подходу, который упоминался выше в разделе Stabilize writing operation first, но теперь он применим к чтению.

3. Очистить

Поскольку чтение и запись теперь стабильны, мы удалим старую базу данных и сделаем PostgreSQL нашей основной БД.

Доказательство концепции

Исходный код написан на Scala: https://github.com/anasanjaria/incremental-db-service-migration

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

Аргумент rollout в прокси определяет, разрешено ли пользователю использовать новую базу данных или нет.

Please note that it's just a very simple and basic implementation. You can adjust it as per your need.

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

MongodbProductDAO & PsqlProductDAO manage products CRUD operations for mongodb & postgesql respectively.
storeProduct stores a product name in respective databases.

Модульные тесты

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

ProductDAOProxy
should fail whole product saving such that user can use both databases
  - when it fails to store product in a mongodb
should not fail whole product saving such that user can use both databases
  - when it fails to store product in a postgres
should only store products in monogdb when user is not allowed to use postgres

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

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

IncrementalRollout
should allow a user to use a feature
- when a feature is enabled completely for all users
- when a feature is enabled 50%
should not allow a user to use a feature
- when a feature is disabled completely for all users
- when a feature is enabled 50%

Поиск неисправностей

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

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

По определенной причине нам нужно включить ведение журнала для медленных запросов. И это можно сделать, настроив конфигурацию Postgres. Вот хороший туториал на эту тему — 3 СПОСОБА ОБНАРУЖЕНИЯ МЕДЛЕННЫХ ЗАПРОСОВ В POSTGRESQL.

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

Спасибо за прочтение.

Если у вас есть какие-либо вопросы, пожалуйста, не стесняйтесь спрашивать меня.

Если вам нравится этот пост, вам также может понравиться следующий пост.





Ознакомьтесь с моими бесплатными шаблонами понятий.