META
Конфигурация
Конфигурация баз данных

Конфигурация баз данных

Что это?

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