Микросервисы и базы
Когда говорят “микросервисы”, мне хочется смеятся. Когда говорят, что у каждого микросервиса своя база данных, я хочу плакать.
База данных сильна лишь когда хранит все данные. Целое больше суммы частей. Когда у вас пятнадцать сервисов и пятнадцать баз, их нельзя назвать базами – это ошметки.
Сторонники множественных баз не понимают, что с ними невозможно наладить отчетность. А отчетность – это то, что движет бизнес вперед. Фонарь, освещающий путь в темноту.
Неважно, насколько красивый у вас лендинг или сколько библиотек в js-бандле. Важно, сколько фирма продает, и как быстро, и что именно, и когда. На все эти вопросы отвечает отчетность. Момент, когда начальство ее потребует, является лишь вопросом времени.
Спрашивается: имея пятнадцать баз, разбитых по сервисам, как вы сделаете отчетность? Взять хотя бы такую мелочь как отчет продаж: сколько продали за последний год и кому. Это join трех-четырех таблиц. Если они раскиданы по базам, как вы его соберете?
Технически можно вызвать сервис пользователей 100 раз, выгребая по 1000 записей. Потом дернуть 1000 раз сервис продаж, потом 200 раз сервис категорий и так далее. Нагрузить сеть и положить инфраструктуру ди-досом. Соединять сущности в приложении по словарям, умирая от нехватки памяти. А можно иметь одну базу и запрос, который сделает то же самое за секунду.
Без консолидированной базы отчетность невозможна. Если у вас 15 баз, понадобится 15 репликаций, которые будут сливать в нее данные. А это – 15 процессов, которые нужно мониторить. Вдруг одна репликация отвалилась? Как вы об этом узнаете?
В Постгресе и других базах есть схемы – аналог пространств имен в языках
программирования. Две сущности с одним именем, но в разных схемах не
пересекаются. Таблица users в схеме accounts хранит пользователей системы
(покупателей), а в схеме backoffice – членов персонала.
Естественно держать сервисы в одной базе, но разных схемах. У каждого сервиса
машинное имя и соответствующая схема, например accounts, sales, backoffice,
management, analytics и другие. В них – таблицы, вьюхи и другие сущности.
Когда мы пишем select * from users, база должна понять, какой схеме
принадлежит users. Для этого используется глобальный параметр search_path –
список схем, в которых ищутся сущности без явно указанной схемы. По умолчанию он
равен "$user",public. Схема "$user" – особая по двум причинам. Во-первых, в
ее названии есть доллар, из-за чего ее берут в двойные кавычки. Во-вторых,
$user означает имя текущего пользователя, например ivan. Это значит, что
сначала Postgres проверит, есть ли таблица ivan.users, затем public.users, а
если ничего не найдено – кинет ошибку.
Схемы дают контроль над доступом. Писать в схему может лишь сервис-владелец,
например пользователь accounts пишет в accounts.user, но не в
sales.products. Данные из других схем выборочно дают на чтение. Скажем, сервису
accounts нужны категории товаров. В этом случае дается GRANT SELECT на таблицу
sales.categories для пользователя accounts. Эту таблицу можно прочитать или
приджойнить в запросе.
Удобно, когда каждый сервис подключается под своим пользователем. Если это
сервис accounts, база будет искать таблицу users в accounts и в
public. Таблицы, которые принадлежат текущему сервису, можно писать без схемы,
а для таблиц-соседей указывать их. Например в запросе ниже видно, что users –
это accounts.users (подключение под пользователем accounts), а профили
приходят из схемы profiles, к которой нам дали доступ на чтение.
select * from users u
join profiles.profiles p on u.id = p.user_id
Такое решение исключает ситуацию, когда вместо прямого запроса мы идем в обход: вызываем сервис и получаем результат, а затем соединяем данные в приложении. Последнее – долго, хрупко и не масштабируется.
На этом месте говорят: если база упадет, перестанут работать все сервисы. Решение – делать так, чтобы не упала! Проверяйте запросы перед вводом в эксплуатацию, смотрите планы, гоняйте на тестовых данных. Мониторьте базу, наказывайте тех, кто шлет кривые запросы. Введите общие стандарты, примеры, документацию, чтобы было куда направлять людей. Сюда же относятся резервные копии и горячее переключение, но это уже ближе к devops.
Управление данными на уровне базы намного проще, чем в коде. База данных – это данные плюс метод доступа к ним. Удивляюсь, что столь прозрачная схема до сих пор кому-то не понятна.
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter