Резать ли базу: дезинтеграторы и интеграторы
Алине книга нравится меньше предыдущей, но полезной оказалась: диалоги героев показывают, как из общих слов рождается структурное профессиональное мнение. Герои к этому моменту распилили монолит на доменные сервисы вокруг одной большой базы, и глава 6 спрашивает, что с ней делать. Дезинтеграторы — факторы за разделение: контроль изменений, потому что база — неявный API, и удаление колонки или смена типа ломает три сервиса, а забытый четвёртый узнают по падению; Вова добавляет, что при четырёхстах микросервисах такие изменения не провести никогда. Дальше управление соединениями: у каждого инстанса свой пул, коннекты простаивают, и авторы предлагают квоты — сначала поровну, потом по измеренной потребности; масштабируемость, отказоустойчивость с базой как единой точкой отказа, архитектурный квант — Илья для себя определяет его как blast radius деплоя — и выбор типа хранилища под данные.
Интеграторы — то, что удерживает данные вместе: связи через внешние ключи, представления и триггеры, которые не разорвать без потери транзакционности, и сами транзакции базы, ради которых слишком мелко порезанные сервисы приходится сливать обратно. Александр вспоминает Влада: если нужна одна транзакция, значит это один агрегат и распределённой системы не будет. Дальше пять шагов, и здесь авторы уже называют их шагами, а не паттернами, — участники видят в этом мгновенную обратную связь на свои прошлые претензии. Алина проходит: проанализировать домены данных; разложить таблицы по схемам доменов, сохраняя совместимость запросов синонимами; развести соединения так, чтобы кросс-джойнов не осталось, а логика чужих доменов ушла на уровень сервисов, — состояние авторы называют «нирваной» и data sovereignty, платя производительностью и консистентностью; вынести схемы на отдельные серверы через backup/restore или репликацию, которая, по опыту Александра, всё равно начинается с restore и догоняющего потока; и переключиться, удалив старое.
Зоопарк баз данных
Авторы отсылают к Refactoring Databases Садаладжа, и большой кусок главы — обзор типов хранилищ по семи характеристикам: лёгкость обучения и моделирования, масштабируемость, доступность, консистентность, поддержка в языках, размер сообщества и, как замечает Илья, возможность нанять людей, а также перекос на чтение или запись. Александр пробегает по типам: реляционные — золотой стандарт с SQL и ACID; key-value — большая хеш-таблица, которая умеет только доставать по ключу, поэтому данные моделируют под запросы; документные, популяризованные MongoDB, которая когда-то была быстрой, потому что не писала на диск; column-family на примере Cassandra с настраиваемой консистентностью на чтение и запись и нетривиальной моделью; графовые, где Александр сам управлял данными и делал доклад, с красивым языком запросов Cypher и ценой enterprise-версии как крыло самолёта; NewSQL вроде Spanner и CockroachDB, раздвигающие CAP за счёт инфраструктуры; cloud-native и time series вроде InfluxDB и TimescaleDB.
Итоговая табличка со звёздочками похожа на сравнение архитектурных стилей из Fundamentals — Александр показывает свой конспект той книги, где сервис-ориентированная архитектура получила оценки «лучше слоёной»: цифры дискуссионные, взяты не с потолка, но откуда-то рядом, и от знакомства с каждым типом таблица не избавит. Вова отмечает, что колоночных баз вроде ClickHouse в обзоре нет, а Илья вспоминает эпизод «Южного парка» о том, как правительство принимает решения по курице без головы. Впечатление участников: сравнение выглядит списанным с обзоров NoSQL десятилетней давности, будто время в этой главе остановилось. Главное же в главе не звёздочки: разделив базу, каждый сервис выбирает хранилище под свои данные, и с этого начинается практический распил у героев книги.
Гранулярность сервисов
Глава 7 разводит модульность — на какие смысловые части делить — и гранулярность — насколько мелко. Метрики: statements и число публичных интерфейсов, обе средние по больнице. Табличка снова из двух колонок, очень похожая на предыдущую. Дезинтеграторы: объём ответственности сервиса — на примере уведомлений, которые можно слать тремя способами; изменчивость кода — часть меняется каждую неделю, остальное раз в полгода, и, выделив её, не нужно перепроверять и передеплоивать весь юнит, хотя Илья замечает, что тем же аргументом можно держать вместе модули, меняющиеся синхронно; масштабирование — монолит скейлится целиком и ресурсы улетают в никуда, что при нынешней цене железа важно вдвойне; отказоустойчивость, которую получишь, только если сервисы не ходят друг в друга на каждый чих; безопасность — чувствительную часть уносят в отдельный контур; и расширяемость, где Александр предостерегает от преждевременной оптимизации: монолит, окружённый лунами-сервисами, всё равно падает вместе с Юпитером.
Интеграторы: транзакции базы, workflow с оркестрацией или хореографией через кучу сервисов, общий код и связи данных. С общим кодом авторы аккуратны: инфраструктурные библиотеки — логирование, мониторинг, авторизация — оправданы, а доменная логика в библиотеке, которую подключают десятки сервисов, при каждом изменении требует пересборки всех и превращает систему в распределённый монолит. Из эвристик — имя: если сервису не придумать название, он нарезан неправильно; Илью насмешил пример, где обычная почта меняется каждую неделю, а SMS и email — раз в полгода. Разбор из сюжета — выделить ли пароли из профиля: безопасники требуют отдельный сервис, бизнес не готов к eventual consistency в профиле, и в итоге безопасность обеспечивают дизайном через фреймворк, а транзакции оставляют в одном сервисе; спонсор проекта выбирает безопасность после недавнего прокола с утечкой. Алине понравилось, что архитектор ведёт беседу как фасилитатор, а не приносит готовое решение. Александр добавляет новость недели: Apple показала протокол входа без паролей на приватных ключах устройства — радикальный способ вырезать пароли из базы вообще. Следующая встреча — вторая часть, как собирать распиленное обратно.
Что стоит унести с собой
- 01База данных — неявный API: за её разделение говорят контроль изменений, пулы соединений, масштаб, отказоустойчивость и квант деплоя, против — внешние ключи и транзакции, ради которых сервисы сливают обратно.
- 02Распил базы идёт пятью шагами — домены данных, схемы, разведённые соединения без кросс-джойнов, отдельные серверы, переключение, — и состояние «нирваны» оплачивается производительностью и консистентностью.
- 03Таблица типов баз со звёздочками — ориентир, а не аргумент: колоночных баз в ней нет, оценки спорны, и от знакомства с каждым типом она не избавляет.
- 04Гранулярность сервиса задают изменчивость кода, масштаб, отказоустойчивость и безопасность, а удерживают транзакции, workflow и доменная логика в общих библиотеках; если сервису не придумать имя — он нарезан неправильно.