Data Model Service (dms)

Описание

Сервис модели данных домена.
Работает на базе класса сущностей доменного центра `classes` интерпретируя каждый экземпляр как метаданные новой пользовательской/проектной коллекции информационных объектов.
Предоставляет CRUD API для остальных ролей и сервисов для управления экземплярами пользовательских/проектных коллекций. Поддерживает методы `create`, `update`, `replace`, `read` коллекции, `read` элемента коллекции`, `clear` коллекции, `lookup`. В зависимости от метаданных коллекции поддерживает работу со словарем в памяти, с распределенной объектной БД, c сервером PostgreSQL, с KAFKA и колоночной БД Clickhouse. Поддерживает однопоточный, параллельный и асинхронный режимы работы с коллекциями. Способна гарантировать целостность модификации/чтения/уведомления, гарантирует сохранение последовательности модификаций в хранилище и в уведомлениях. Позволяет использовать временный или постоянный кэш для элементов коллекций.

Работает совместно с wssubscr для уведомления подписчиков об изменениях (класс/тип событий `modelevents.data_changed`). Поддерживает подписку с фильтрами и маскировкой. Уведомляет с корректировкой команд с учетом фильтра (например, create вместо update). Выборка данных из коллекции поддерживает сложную фильтрацию, маскировку, сортировку, агрегацию, смещение, лимитирование.

Доступ через HTTP(s) REST API `/rest/v1/model/…​`, где далее имя (или путь) класса. Управление возможно также через Websocket-API как с авторизацией под сессией пользователя, так и через токен.
Доступ к коллекциям и методам определяется раутами вебсервера. По умолчанию администратору доступны все пути и методы, а остальное определяется ролями (класс roles), назначенными пользователю (user.opts.roles) или каналу интеграции (integration_point.opts.roles).

Поддерживает привязку файлов-вложений к сущностям, имеющим свойства типа `attachment` единичного или списочного вида.
Вложения размещаются на указанных в классе хранилищах, подключения к которым настроены с помощью сущностей класса storage с типами, относящимися к файловым хранилищам.

Разделена на микросервисы по доменам.
Резервируется в режиме Active-Passive. Масштабируется разделением доменного дерева.

Table 1. Системные характеристики

Код

dms

Режим работы

Хранилище, сервис

Режим резервирования

Active-Passive

Типы сайтов

Любые

Слой

Бизнес-логика

Размещение

Внутренний

Сохранение и восстановление состояния при перезагрузке

Да, кроме классов типа RAM.

Приложение

era_dms

Собственное хранилище

RAM, Mnesia, PostgreSQL, KAFKA, Clickhouse

Ограничения

  • Доступно в рамках информационно-коммуникационной платформы 'era'.

  • Скорость работы зависит от выбранного типа хранилища коллекции. Достижима скорость работы коллекции до 10 тысяч запросов в секунду.

  • Данные между сайтами ролью не синхронизируются. Слияние через внешние хранилище возможно с поправкой на возможные проблемы целостности и необходимость отключение кэша.

Параметры

Table 2. Параметры
Имя Тип Умолчание Описание

name

str

required

Имя. Может состоять из латинских букв и цифр, должно начинаться с буквы.

roletype

str

required

Тип роли. Возможные значения: "dms".

iface

str

required

Алиас сетевого интерфейса сервера, на котором будет происходить внутреннее взаимодействие ролей между собой.

ext

json

empty

Дополнительные опции роли. Содержит json объект или список.

enabled

bool

empty

Флаг активности роли. При установке в false роль не участвует в валидации и не запускается.

dbconnstrings

array<str>

required

Строки подключения к ферме серверов PostgreSQL БД доменов, где создаются базы данных доменов с хранилищем сущностей продуктовых моделей.
Эти строки подключения используются для классов, имеющих storage_mode: 'category' или 'history', у которых не заданы специфические параметры подключения к БД PostgreSQL, а выставлен режим 'auto' (по умолчанию).

Каждый домен использует пул из 10 подключений к каждой БД (уникальная строка подключения). Новое подключение создается только при занятости. В спокойном режиме подключения к БД отсутствуют.
Каждый домен использует оригинальную указанную строку только для создания собственной БД с уникальным именем 'era_model_%DOMAIN%', а для работы использует модифицированную строку подключения, где в качестве БД подставляет имя своей БД.

Формат строки подключения: "alias://pgdb_strings/<ALIAS_NAME>", где <ALIAS_NAME> – конкретный алиас конфигурации из раздела pgdb_strings.

Перечисление в списке нескольких строк подключения обеспечивает резервный доступ к ферме серверов БД – если подключение через первую строку не удается, производится подключение через вторую и т.д.

На центральном сайте, где располагается роль MDC, при отсутствии этого параметра, для клаccов с режимом 'auto' применятся строки подключения, заданные в параметрах роли mdc.

group

int

required

Номер группы.
В рамках горизонтального масштабирования роль может быть разделена на несколько групп на сайте, в каждой из которых активен только один экземпляр, а остальные зарезервированы.
Ответственность между группами разделяется как по доменным множествам, так и по отдельным классам конкретных доменов.
Вместе все группы обслуживают полное доменное множество и полное покрытие классов.
Все роли одной группы должны иметь одинаковую ответственность.
Если пиковая нагрузка на активный экземпляр превышает нормальный предел, достаточно разделить нагрузку по нескольким экземплярам, выделив либо нагруженные классы по какому-либо признаку, либо поделив на несколько групп доменов, либо и то и другое, и распределить по разным серверам.
Целое число от 1 до 9999999.

order

int

required

Порядок экземпляра роли в рамках группы.
Определяет в каком порядке будет происходить перетекание в режиме Active-Passive.

include_domains

array<str>

empty

Список имен доменов, которые обслуживает данная группа.
Может быть указан любой домен любого уровня. Указание домена приводит к тому, что дерево его поддоменов будет обслуживаться на этой группе и не будет обслуживаться на других группах роли, исключая только те ветви, которые упомянуты в других группах.
В совокупности все группы роли на сайте обслуживают полное дерево доменов.

domain_group

int

undefined

Номер группы обслуживания доменного дерева.
Применяется в тех случаях, когда необходимо разделить обслуживание на несколько экземпляров по доменам и по секциям одновременно.
Чтобы создать несколько разных групп, обслуживающих одно и то же неполное доменное дерево, но разные секции, необходимо для этих экземпляров параметрами задать одинаковое значение в include_domains и одинаковое значение в domain_group.
Таким образом механизм распределения поддеревьев по группам при исключении поддеревьев других групп применяет в приоритете значение domain_group вместо group.
Целое число от 1 до 9999999.

max_loading_domains

int

2

Ограничитель количества одновременно загружаемых доменов.
Приносит пользу в системах с большим количеством доменов.
Применяется с целью ограничить нагрузку на процессор во время перезагрузки микросервиса.
Параметр применяется на старте, при перезапуске микросервиса, и при массовом создании новых доменов.

max_loading_classes

int

1

Ограничитель количества одновременно загружаемых классов в пределах одного домена.
Приносит пользу в системах с большим количеством доменов.
Применяется с целью ограничить нагрузку на процессор во время перезагрузки микросервиса.
Параметр применяется на старте, при перезапуске микросервиса, и при массовом создании новых классов в домене.

cache_filter_interval_sec

int

300

Интервал очистки временного кеша для классов с соответствующим режимом кеширования.
Чем чаще производится очистка, тем меньше памяти занимает кеш, тем меньше ресурсов занимает одна итерация, но тем больше времени процессора расходуется на операцию в целом.
Рекомендуемые значения от 30 до 600 секунд.

class_readers_count

int

10

Количество процессов, обслуживающих параллельно операции чтения в рамках одного класса, если параллельное чтение разрешено режимом класса.
В том числе операции выборки с фильтром.
Минимальное значение - 2, максимальное значение - 32.
Приносит пользу в системах с большим количеством доменов.
Если в системе большое количество ненагруженных доменов, то рекомендуемые значения 4 или ниже.
Если количество доменов мало (до 100), то рекомендуемые значения выше 10.
Для применения значения необходим перезапуск микросервиса.

Является значением по умолчанию для тех классов, где значение opts.worker_r_count = 0.

class_writers_count

int

4

Количество процессов, обслуживающих параллельно операции записи в рамках одного класса, если параллельное чтение разрешено режимом класса.
Операция записи сопряжена с подготовкой объекта и проверкой допустимости значений.
Минимальное значение - 2, максимальное значение - 32.
Приносит пользу в системах с большим количеством доменов.
Если в системе большое количество ненагруженных доменов, то рекомендуемые значения 4 или ниже.
Если количество доменов мало (до 100), то рекомендуемые значения выше 4. О
Для применения значения необходим перезапуск микросервиса.

Является значением по умолчанию для тех классов, где значение opts.worker_w_count = 0.

stat_enabled

bool

true

Выключатель ежеминутного логирования статистики по классам, для которых не задана индивидуально настройка уровня ежеминутного логирования статистики.
Каждую минуту происходит сбор и логирование статистики работы в виде нескольких строчек с общими показателями работы: количество запросов прошедших по разным условиям, минимальное, максимальное, среднее время обработки запроса.
Для увеличения уровня логирования конкретному классу можно задать опцию stat_mode = 'high'. Тогда статистика по минимальному, максимальному и среднему времени обработки будет выводиться в разрезе производимой операции.
Для уменьшения уровня ежеминутного логирования статистики по классам необходимо выключить этот режим и настроить конкретным классам требуемый уровень.

pg_max_connections_default

int

10

Количество потоков в пуле подключений к серверу postgresql, используемое по умолчанию.
Пул определяется строкой подключения - к каждому серверу и каждой базе данных организовывается собственный пул.
Для отдельных классов количество потоков в пуле подключений может задаваться индивидуально в опциях класса.

Отдельно существуют пул для работы серверных служб и пул для работы клиентских подключений. Каждый из них максимально расширяется до указанного количества подключений.
При неиспользовании подключения более 60 секунд, оно закрывается.

query_workers_count

int

4

Количество процессов, обслуживающих параллельно операции dmsquery на сервере.
Операция выполнения сопряжена с выполнением произвольного запроса в БД и последующей подготовкой результата, размер которого может быть произвольным.
Минимальное значение - 1, максимальное значение - 32.
Служит для ограничения пиковых нагрузок, создаваемых при параллельном построении кастомных отчетов, использующих запрос dmsquery.
Следует соизмерять с проектной логикой, количеством ядер на сервере, где исполняется экземпляр микросервиса, а также составом других микросервисов на этом сервере.
Для применения значения необходим перезапуск микросервиса.

sections

array<str>

Список секций, в которых участвует экземпляр.
Секция может быть задана в свойствах сущности класса, и тогда к его исполнению привлекаются только те экземпляры, у которых указанная секция присутствует в этом поле.
Параметр должен быть идентичен на экземплярах одной группы (active-passive).

mnesia_storage_mode

str

disc "Режим работы объектного хранилища по умолчанию.

Используеется классами типа 'runtime'

для которых индивидуально не задан режим работы хранилища.

Возможные варианты:

  • disc - полный режим

в оперативной памяти с сохранением на диск на всех экземплярах группы.

* ram - только в оперативной памяти (с поддержкой распределенности

транзакций). При одновременной перезагрузке/выключении всех экземпляров группы данные теряются.

  • disc_only - только на диске (заметно менее производительно

но экономит RAM)."

mnesia_activity_context

str

dirty

Операционный контекст объектного хранилища.
Возможные варианты:

  • dirty - каждая операция производится локально, данные асинхронно (без задержек) отправляются в хранилище пассивного экземпляра группы. Время выполнения операции записи около 30 мкс.

  • transaction - каждая операция записи создает транзакцию. Время выполнения вырастает до интервала, равного двум пингам между серверами одной группы. Если установлен этот контекст, то для отдельных классов можно включить опцию dirty_write_enabled и кратно повысить скорость обработки.

Используемый по умолчанию вариант dirty не создает проблем работе системы по сравнению с вариантом transaction, поскольку:
- Не используется режим одновременной записи с нескольких экземпляров;
- Операции с одной сущностью производятся строго в одном потоке-обработчике;
- Параллельное чтение данных не порождает логических конфликтов;
- При тейковерах и фейловерах последний загруженный экземпляр синхронизируется с того, который загрузился ранее, тем самым отдавая приоритет актуальным данным активного экземпляра;
- При распадании группы на острова и одновременной активности двух экземпляров, приоритет отдается данным лидера.

takeover

bool

global

Выключатель режима takeover.

Failover - активация менее приоритетного экземпляра сервиса при обнаружении недоступности более приоритетного экземпляра сервиса (лидера группы active-passive).
Takeover - активация более приоритетного экземпляра сервиса (лидера группы active-passive) во время его восстановления, сопровождающееся остановкой сервиса на менее приоритетном экземпляре сервиса.

  • Если режим включен - takeover осуществляется автоматически.

  • Если режим выключен - takeover не осуществляется, восстановленный лидер группы временно становится фолловером и ожидает выгрузки сервиса на менее приоритетном экземпляре.

  • Если опция не задана, то применяется ее значение из параметров текущего сайта. Если не задано в сайте, то применяется значение из раздела general. Если нигде не задано - takeover включен для более точного распределения нагрузки по заданным в конфигурации приоритетам.

Пример конфигурации

Управление конфигурацией производится в приложении, доступном для администраторов мастер-домена. Приложение скрывает полное содержание конфигурации, однако тем не менее оно доступно через API.

Конфигурация содержит раздел для описания всех экземпляров всех ролей. Параметры определяются для каждого конкретного экземпляра роли.

Пример узла
{
  "name": "dms1",
  "roletype": "dms",
  "iface": "eth0",

  "group": 11310,
  "order": 1
}