Конфигурация баз данных
Что это?
Для того, чтобы Мета могла обращаться к любым базам данных без необходимости указыва в каждом месте полный набор параметров соединения (хост, порт и прочее) конфигурации БД хранятся в отдельном файле meta-databases.yaml. Он имеет следующую структуру:
acl: # Настройки доступа к профилям
can_prefer_production_profile:
users: # Список пользователей, которые могут запрашивать доступ к production профилю, даже при наличии test профиля
- 4501
databases: # Список конфигураций БД
- id: coordinator # Внутренний идентификатор, по которому будут идти обращения к этой БД
description: База данных Координатора # Человекопонятное описание
# Тип БД. Возможные значения:
# - Postgres или POSTGRESQL
# - PostgresSchemaShard
# - META
# - MSSQL
# - MySQL или MYSQL
# - ClickHouse или CLICKHOUSE
# - BigQuery
# - GoogleSheet
type: Postgres
name: starter_coordinator # Имя БД, с которой устанавливается соединение
host: 192.168.1.1 # Хост
port: 5432 # Порт
# Произвольный набор параметров, которые нужно передать в JDBC строке соединения
connectionParams:
compress_algorithm: gzip
username: user # Логин пользователя
password: pass # Пароль
profiles: # Дополнительные профили БД
test: # id профиля
host: 192.168.1.2
port: 5433
username: user2
password: pass2Как видно, кроме понятных типов БД (Postgres, MySQL) используется и специальные типы:
- META: позволяет через JDBC протокол получать доступ к конфигурации Меты, хранящейся в обычных объектах в памяти
- GoogleSheet: позволяет подключаться через JDBC протокол к Google-таблицам
Обращения к БД идут по их идентификатору, который, как правило, передается в поле db-alias или dbAlias, в зависимости от места применения.
Например, обращение на странице:
<script type="meta/sql" db-alias="adplatform.test" id="res">
SELECT name FROM users LIMIT 10
</script>Или, при использовании MetaSDK
db_adplatform = META.db("adplatform")
users = db_adplatform.all("SELECT name FROM users LIMIT 10")Однако, видно, что id БД при обращени отличается - в первом примере использован adplatform.test, а во-втором - просто adplatform. Отличие кроется в запросе нужного профиля
Профили БД
Профили БД - это дополнительные наборы настроек БД, переопределяющие базовые настройки, что позволяет поддерживать несколько модификаций одного соединения. Это позволяет реализовать, в частности, концепцию тестовых БД, работа с которыми будет осуществляться вместо работы с БД продовой.
Предопределены два профиля (хотя потенциально их может быть больше):
- production. Это тот набор настроек, который указан непосредственно в списке
databasesконфигурацииmeta-databases.yaml - test (и потенциально остальные). Набор настроек, указываемый в параметре
profilesкаждой БД. Можно указать (и, тем самым, переопределить) любые из следующих параметров:- host
- port
- username
- password
- connectionParams
При обращении к БД профиль указывается в идентификаторе после точки. Например, adplatform.test обратится к профилю test базы с id adplatform. Если профиль не указан, будет сделана попытка обратиться к профилю production. Например, обращение adplatform и adplatform.production идентичны - в обоих случаях будет сделана попытка обратиться к БД с профилем production.
Почему мы пишем "сделана попытка", а не просто "произойдёт обращение"? Потому что если к профилю test можно обратиться всегда и без ограничений, успешность запроса к production зависит от ряда условий:
- От сценария работы с Метой
- От наличия id пользователя к белом списке тех, кому разрешен доступ к
productionпрофилю даже при наличии профиляtest. За это отвечает параметрacl.can_prefer_production_profile.usersвmeta-databases.yaml - От режима работы самого развернутого экземпляра Меты (параметр
meta.yaml.forceProductionDbProfile) - От того, запускается ли локальный экземпляр Меты (в IDE или через DDC) в режиме требования
productionпрофиля (параметрmeta.yaml.forceProductionDbProfileили ENV переменнаяMETA_FORCE_PRODUCTION_DB_PROFILE)
Для определения того, возможен ли доступ к production профилю или будет использован test профиль можно использовать следующую матрицу ACL.
| meta.yaml.forceProductionDbProfile = true Все боевые стейджи |
meta.yaml.forceProductionDbProfile = false Тестовые стейджи | |||
|---|---|---|---|---|
| Сценарий работы с Метой | userId есть в meta-databases.acl | userId нет в meta-databases.acl | userId есть в meta-databases.acl | userId нет в meta-databases.acl |
| 1. Обращение в web-интерфейсе | Отдает production | Отдает production | Отдает test | Отдает test |
| 2. Запрос meta-databases через dev-api (при локальном запуске или через DDC) Параметр forceProductionDbProfile = false |
Отдает test | Отдает test | Отдает test | Отдает test |
| 3. Запрос meta-databases через dev-api (при локальном запуске или через DDC) Параметр forceProductionDbProfile = true |
Отдает production | Отдает test | Отдает production | Отдает test |
| 4. Запрос MetaQL (описанный в yaml) В yaml entity указан production профиль |
Отдает production | Отдает test | Отдает test | Отдает test |
| 5. Запрос MetaQL (описанный в скрипте страницы) | Отдает production | Отдает test | Отдает production | Отдает test |
| 6. Запрос через DB API (например, stream-query) | Отдает production | Отдает test | Отдает test | Отдает test |
Например, работая на проде в интерфейсе любого приложения Меты, вы реализуете сценарий 1. Запуская Мету через DDC - сценарий 2 или 3. Обращаясь через MetaSDK - сценарии 4, 5 или 6.
Важно отметить, что система обеспечения доступа к профилям реализована так, чтобы максимально избежать получения пользователем ошибок. Подмена production профиля на test и обратно происходит прозрачно, ошибки возникнут только при попытки обращения к любым другим профилям. Например:
- Затребован профиль
production- Если профиль
testсуществует, будет произведена проверка по матрице ACL- Если доступ к
productionразрешен, он будет использован - Если доступ к
productionзапрещён, будет прозрачно использован профильtest
- Если доступ к
- Если профиля
testне существует, будет использованproduction
- Если профиль
- Затребован профиль
test- Если профиль
testсуществует, он и будет использован - Если профиля
testне существует, будет использованproduction
- Если профиль
- Затрабован профиль
expirement- Если профиль
expirementсуществует, он и будет использован - Если профиля
expirementне существует, будет вызвана ошибка
- Если профиль