Конфигурация баз данных
Что это?
Для того, чтобы Мета могла обращаться к любым базам данных без необходимости указыва в каждом месте полный набор параметров соединения (хост, порт и прочее) конфигурации БД хранятся в отдельном файле 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
не существует, будет вызвана ошибка
- Если профиль