разделение монолита
Разделение монолита: первый сервис наружу за 20 дней
Одиннадцать лет коммитов в одном деплое, четыреста таблиц в одной схеме, релизный поезд раз в квартал. Мы находим, где данные на самом деле расходятся, сначала делим схему и вырезаем сервис, который собирается, деплоится и будит дежурного сам по себе. Rails, Django, Spring, .NET, PHP или Go: метод один и тот же, а второй сервис идёт быстрее, потому что трудная часть уже позади.
20 дней на первый сервис, второй быстрее
Два сервиса и библиотека. Число сервисов должно совпадать с числом команд, готовых носить по ним пейджер.
Один деплой
Один репозиторий, одна схема, один релизный поезд, импорты, которые ходят по кругу.
- one deployable11 years of commits
- shared schema400+ tables
- release trainquarterly
- circular importscycles
Разделено
Два сервиса со своими схемами, библиотека под общее, отдельные выкатки.
- billingGo · own schema
- catalogueGo · own schema
- shared kernellibrary
- deploysper service
20 дней на первый сервис, второй быстрее
Как идёт работа
- 01дни 1–4
Найти швы в данных
Логи запросов показывают, какие таблицы читаются вместе в одном запросе. Границы там, что бы ни утверждала структура пакетов.
- 02дни 3–8
Сначала разделить схему
Разносим таблицы и убираем джойны через границу, пока всё ещё один деплой. Основной риск живёт здесь, и на этой стадии всё ещё обратимо.
- 03дни 8–15
Вынести один сервис
Тот, у которого меньше всего входящих зависимостей, а это редко тот, который раздражает людей сильнее прочих. Он едет за тем же интерфейсом, пока его эксплуатация не перестанет быть интересной.
- 04дни 14–20
Дать ему свой пайплайн
Свой репозиторий, своя выкатка, своё дежурство. Сервис, релизы которого всё равно приходится согласовывать с монолитом, не выиграл вам ничего, и видно это на пятнадцатый день, а не в конце.
Что делает платформа, что делает человек
| Что делает платформа, что делает человек | Кто делает | Примечания |
|---|---|---|
| Строит карту совместного доступа к таблицам и связности модулей | Платформа | По логам запросов и графу вызовов, за период, который включает закрытие месяца. |
| Предлагает швы | Вместе | Платформа ранжирует кандидатов. Человек сверяет их с границами ваших команд. |
| Ломает джойны через границу | Платформа | Механическая работа, читается пул-реквестами, едет мелкими кусками. |
| Выбирает, какой сервис пойдёт первым | Инженер | Владение командой решает это чаще, чем сам код. |
| Границы транзакций | Инженер | Там, где одна транзакция базы раньше пересекала шов, кто-то должен решить, что происходит при отказе. |
| CI, выкатка и дежурство | Вместе | Сервис без своего пайплайна и своей смены - это модуль с лишними сетевыми хопами. |
Кто режет шов
Десятки миграций, больше десяти лет на системах, которые строили давно ушедшие люди, и достаточно разделений, чтобы знать, какие из них окупаются. Монолиты на Rails, Django, Spring, .NET, PHP и Go, схемы на четыреста таблиц и десятилетие джойнов через границу. Шов никогда не проходит там, где его рисует архитектурная схема, и найти настоящий - это и есть большая часть того, что вы покупаете.
Проверкой служит первый вынос, и он ограничен: один сервис, своя схема, своя выкатка, в проде. Рабочий ответ ценой одной фазы.
Вопросы, которые задают инженеры
- Сколько сервисов должно получиться?
- Меньше, чем на схеме в архитектурной презентации. Вынесите один, подержите его в проде квартал, потом решайте про следующий. Команды, которые планируют двенадцать сразу, обычно получают четыре и много общей базы.
- Нам обязательно переписывать на Go?
- Нет. Вынос и переписывание - разные решения, и множество разделений остаются на исходном языке. Там, где мы всё-таки переписываем сервис, дело в том, что этот модуль всё равно шёл на переписывание, где бы он ни лежал.
- Что происходит с общим кодом?
- Он становится версионируемой библиотекой с небольшой поверхностью. Когда общее ядро начинает расти каждый спринт, это сигнал, что шов встал не там, и подвинуть его на пятнадцатый день заметно дешевле, чем на втором году.
- Можно ли делать это, продолжая выпускать фичи?
- Да, и от этого будет медленнее. Защищать нужно шаг разделения схемы: если вплетать туда работу над фичами, проект встаёт на год с наполовину разделённой базой.
- А общая база данных, которой все пугают?
- Ради этого схема и идёт первой. Два сервиса на одной схеме - распределённый монолит с режимами отказа хуже исходных, и это самый частый способ сделать такую работу плохо.
Начните с одного выноса
Достаточно размера монолита, частоты релизов и того, что толкает к изменениям. Вернёмся с тем, где швы, похоже, проходят, и во что обойдётся первый сервис.
Отвечает инженер, и первый вопрос обычно про частоту релизов.