Настройка репликации в StandIn при использовании DataSpace#
Возможности StandIn при использовании DataSpace#
При использовании DataSpace для работы с данными консистентная репликация изменений в БД StandIn обеспечивается автоматически при выполнении следующих условий:
агрегатоцентричная модель данных;
наличие на стенде корректно настроенного и функционирующего компонента Прикладной журнал (APLJ) (ПЖ), в том числе плагинов в ПЖ (для репликации в StandIn используются плагины Kafka EXPORT_FUNC_SI и EXPORT_FUNC_SI_LCK);
корректные настройки приложения dataspace-core подключения к ПЖ и к БД StandIn;
разворачивание модуля применения векторов изменений в OS с корректными настройками.
Этапы настройки репликации в StandIn для новых пользователей DataSpace#
Этап 1 — проверка модели данных#
Необходимо убедиться, что модель данных удовлетворяет критерию агрегатоцентричности или разработать такую модель данных (сведения о реализации предметной модели можно найти в документе «Руководство по ведению модели данных»).
Этап 2 — проверка наличия ПЖ#
Убедиться, что на стенде имеется развернутый компонент Прикладной журнал (APLJ), или заказать разворачивание этого сервиса. Описание установки компонента Прикладной журнал (APLJ) приводится в его эксплуатационной документации.
Режим ожидания подтверждения commit#
Концепция:
В этом режиме ПЖ буферизирует вектора изменений до получения флага успешного commit соответствующей транзакции с БД источника.
Если вместо флага подтверждения пришел флаг отката, то транзакция не будет передана в модуль применения векторов.
Если истекло время ожидания, и не пришло ни подтверждение, ни отмена транзакции — ПЖ отправит запрос на получение нового подтверждение в модуль применения векторов.
Данный режим является целевым для использования и исключает получение неподтвержденных данных потребителями векторов DataSpace, такими, как:
репликация в StandIn;
потоковая загрузка в хранилище данных текущих транзакций, обеспечиваемая компонентом Архивирование (ARCH) продукта Platform V Archiving.
Для функционирования данного режима вводятся новые topics, по которым нужно получить права на чтение/запись:
journal_request_topic_confirmed_{zoneId}_{datatype};
journal_confirmation_{zoneId}_{datatype}.
Особенность настройки плагина EXPORT_FUNC_SI#
При настройке плагина EXPORT_FUNC_SI необходимо включить режим «Ожидание при подтверждении».

После настройки ПЖ должен быть перегружен для создания новых вышеупомянутых topics.
Проверить наличие новых topics можно в режиме «Мониторинг» в UI ПЖ.

Поддержка режима ожидания подтверждения commit во всех модулях DataSpace#
Необходимо прописать для модуля dataspace-applier (gigabas) следующие параметры со значениями:
dataspace.replication.confirmation-mode=confirmed;dataspace.standin.applier.lock-control-logic-modeможет иметь два значения:VERSION_WITH_DELETE— рекомендуется в общем случае, выполняет очистку «на лету» служебной таблицыT_REPL_AGGLOCKEVENT;VERSION— рекомендуется использовать при высокой нагрузке.
Подробнее про служебную таблицу T_REPL_AGGLOCKEVENT и варианты ее очистки описано в документе «Структура базы данных».
Если требуется вернуться в режим по умолчанию, необходимо вернуть этим параметрам следующие значения:
dataspace.replication.confirmation-mode=unconfirmed;dataspace.standin.applier.lock-control-logic-mode=LOCK_EVENT_TABLE.
Этап 3 — создание новой зоны ПЖ#
Необходимо выбрать идентификатор StandIn-зоны (зоны ПЖ) и заказать создание новой зоны ПЖ с данным идентификатором на стенде. За подробностями можно обратиться к эксплуатационной документации компонента Прикладной журнал (APLJ).
После получения новой зоны ее необходимо определить в параметре standin.cloud.client.zoneId=<ИМЯ_ЗОНЫ>.
Этап 4 — настройка плагинов ПЖ#
Вариант1: Использование быстрого переключения в функциональный StandIn#
См. раздел «Поддержка быстрого переключения в функциональный StandIn».
Необходимо заказать настройку плагинов ПЖ для DataSpace или убедиться, что такая настройка произведена. Настройка осуществляется согласно таблице:
Имя плагина |
Тип данных |
Комментарий |
|---|---|---|
EXPORT_FUNC_SI |
DATASPACE |
Вектора изменений DataSpace, формат — JSON |
EXPORT_FUNC_SI_LCK |
LCK |
StandIn блокировки агрегатов, формат — JSON |
EXPORT_FUNC_SI_LCK |
ULCK |
StandIn разблокировки агрегатов, формат — JSON |
EXPORT_FUNC_SI_REJ |
REJ |
StandIn флаг отката, формат — JSON |

Дополнительно необходимо заказать настройку использования блокировок для указанной зоны: параметр force.func.standin.enabled должен быть установлен в «true».
Обычно ПЖ по умолчанию устанавливает в «false», в «true» он устанавливается по запросу.

Вариант2 (рекомендуется): Отказ от обработки технических векторов на стороне репликации#
Если режим быстрого переключения в функциональный StandIn не используется (см. раздел «Поддержка быстрого переключения в функциональный StandIn») и настроен режим работы с подтверждением транзакций (CONFIRMED), возможно на стороне репликации отказаться полностью от приема технических векторов с типами LCK, ULCK и REJ.
В этом случае экономятся ресурсы как компонента «Прикладной журнал» (APLJ) (не создаются плагины и топики для этих типов данных), так и ресурсы репликации DATASPACE (исключена логика обработки приема технических векторов, а также исключено создание прослушивания приемных топиков).
Описание настроек:
Настройка на стороне компонента «Прикладной журнал» (APLJ):
В режиме
Плагины Кафкапроконтролировать отсутствие, и если есть, удалить плагины:EXPORT_FUNC_SI_LCK (тип данных = LCK);
EXPORT_FUNC_SI_LCK (тип данных = ULCK);
EXPORT_FUNC_SI_REJ (тип данных = REJ).
В режиме
Мониторингпроконтролировать отсутствие, и если есть, сделать запрос в сопровождение компонента «Прикладной журнал» (APLJ) на удаление топиков, соответствующих удаленным плагинам в предыдущем пункте.Сделать запрос в сопровождение компонента «Прикладной журнал» (APLJ) на установку значения параметра not.write.in.db.and.transfer.in.topic.lck.ulck(Не записывать LCK и ULCK вектора в базу и не перекладывать в journal_request_topic) в значение true.
Сделать запрос в сопровождение компонента «Прикладной журнал» (APLJ) на установку значения параметра force.func.standin.enabled(Форсированный переход в функциональный standin (Oracle)) в значение false.
Настройка модуля dataspace-applier (gigabas):
параметру
dataspace.replication.confirmation-modeприсвоить значениеCONFIRMED_LITE;параметру
dataspace.standin.applier.lock-control-logic-modeприсвоить значениеLITE.
Этап 5 — настройка параметров ПЖ#
Настройка параметров должна быть выполнена для всех модулей DataSpace.
После настройки ПЖ необходимо запросить параметры подключения к ПЖ на данном стенде и сконфигурировать параметры в ConfigMap сервиса:
kind: ConfigMap
apiVersion: v1
metadata:
name: app-config
data:
override.properties: |-
standin.cloud.client.stub=false
standin.cloud.client.zoneId=<укажите свою зону>
standin.cloud.client.kafka.bootstrapServers=<адрес:порт>
standin.cloud.client.subscriptionKafkaConcurrency=10
standin.cloud.client.heartBeatPeriod=10000
standin.cloud.client.kafka-retry=5
standin.cloud.client.retry-timeout=10000
Настройка SSL-подключения к ПЖ#
Примечание
Параметры, не относящиеся к username, password или passphrase, задаются в ConfigMap сервиса:
kind: ConfigMap apiVersion: v1 metadata: name: app-config data: override.properties: |- standin.cloud.client.stub=false standin.cloud.client.zoneId=${ZONE_ID} standin.cloud.client.kafka.bootstrapServers=${KAFKA_BOOTSTRAP_SERVERS} standin.cloud.client.kafka.producerConfig."[security.protocol]"=SSL standin.cloud.client.kafka.producerConfig."[ssl.keystore.location]"=/opt/keystore/kafka/server.keystore_aj.jks standin.cloud.client.kafka.producerConfig."[ssl.truststore.location]"=/opt/keystore/kafka/trust_aj.jks standin.cloud.client.kafka.producerConfig."[ssl.keystore.type]"=JKS standin.cloud.client.kafka.producerConfig."[ssl.truststore.type]"=JKS standin.cloud.client.kafka.producerConfig."[ssl.protocol]"=TLS standin.cloud.client.kafka.producerConfig."[ssl.enabled.protocols]"=TLSv1.2 standin.cloud.client.kafka.producerConfig."[ssl.endpoint.identification.algorithm]"= standin.cloud.client.kafka.consumerConfig."[security.protocol]"=SSL standin.cloud.client.kafka.consumerConfig."[ssl.keystore.location]"=/opt/keystore/kafka/server.keystore_aj.jks standin.cloud.client.kafka.consumerConfig."[ssl.truststore.location]"=/opt/keystore/kafka/trust_aj.jks standin.cloud.client.kafka.consumerConfig."[ssl.keystore.type]"=JKS standin.cloud.client.kafka.consumerConfig."[ssl.truststore.type]"=JKS standin.cloud.client.kafka.consumerConfig."[ssl.protocol]"=TLS standin.cloud.client.kafka.consumerConfig."[ssl.enabled.protocols]"=TLSv1.2 standin.cloud.client.kafka.consumerConfig."[ssl.endpoint.identification.algorithm]"=
Создается секрет с указанием паролей к хранилищам с сертификатами и приватному ключу:
apiVersion: v1
kind: Secret
metadata:
name: secret-appjournalsettings
stringData:
appJournal.properties: |-
standin.cloud.client.kafka.producerConfig."[ssl.key.password]"=${SSL_KEY_PASSWORD}
standin.cloud.client.kafka.producerConfig."[ssl.keystore.password]"=${SSL_KEYSTORE_PASSWORD}
standin.cloud.client.kafka.producerConfig."[ssl.truststore.password]"=${SSL_TRUSTSTORE_PASSWORD}
standin.cloud.client.kafka.consumerConfig."[ssl.key.password]"=${SSL_KEY_PASSWORD}
standin.cloud.client.kafka.consumerConfig."[ssl.keystore.password]"=${SSL_KEYSTORE_PASSWORD}
standin.cloud.client.kafka.consumerConfig."[ssl.truststore.password]"=${SSL_TRUSTSTORE_PASSWORD}
Добавляется секрет с хранилищами с сертификатами в формате base64:
apiVersion: v1
kind: Secret
metadata:
name: kafka-ssl-secret
type: Opaque
data:
server.keystore_aj.jks: >-
MIIukwIBAzCCLkwGCSqGSIb3DQEHAaCCLj0Egi45MIIuNTCCBWEGCSqGSIb………
trust_aj.jks: >-
MIIukwIBAzCCLkwGCSqGSIb3DQEHAaCCLj0Egi45MIIuNTCCBWEGCSqGSIb………
Все свойства с префиксом standin.cloud.client.kafka отвечают за соединение с Kafka ПЖ.
По значениям остальных параметров можно обратиться к эксплуатационной документации компонента Прикладной журнал (APLJ).
Этап 6 — обеспечение доступа к Kafka ПЖ из кластера#
Необходимо обеспечить доступ из пространства Kubernetes (или OpenShift) к Kafka ПЖ.
При интеграции на dev-средах, можно создать ServiceEntry по образцу:
kind: ServiceEntry
spec:
addresses:
- 1.2.3.4
endpoints:
- address: 1.2.3.4
exportTo:
- .
hosts:
- dataspace.client.kafka.poseidon
location: MESH_EXTERNAL
ports:
- name: tcp
number: 9092
protocol: TCP
resolution: DNS
Этап 7 — конфигурирование параметров приложений DataSpace#
Для обеспечения репликации в SI помимо остальных приложений DataSpace требуется разворачивать также приложение для применения векторов изменений DataSpace Applier (или Gigabas). Необходимо указывать параметры SpringBoot-приложений явно:
Обязательно должно быть сконфигурировано соединение с Kafka ПЖ по аналогии с secret-appJournalSettings из этапа 5 (добавьте актуальные значения всех параметров из
appJournal.propertiesв конфигурационные файлы приложений DataSpace Core и DataSpace Gigabas, например, вapplication.properties).Должны быть сконфигурированы оба datasource:
для main БД — это свойства
spring.datasource.*(spring.datasource.url,spring.datasource.username,spring.datasource.passwordи при необходимости другие);для standin БД — это те же свойства, только с префиксом standin вместо spring:
standin.datasource.url,standin.datasource.username,standin.datasource.passwordи другие при необходимости.
Настройка параметров применения векторов изменений (DataSpace Applier)#
Существует возможность переопределения параметров применения векторов изменений.
Описание параметров:
Параметр |
Значение |
Комментарий |
|---|---|---|
|
10 |
Настройка клиентской библиотеки ПЖ. Рекомендуемое значение — 10. Количество потоков, читающих topic с журналами на одно приложение. Это означает, что один модуль Applier (Gigabas) будет использовать 10 потоков для обработки партиций в topics Kafka. Рекомендуемое значение количества партиций — тоже 10 по следующим причинам: 1. Если количество партиций будет меньше 10, тогда Applier (Gigabas) будет иметь неиспользуемые зарезервированные ресурсы. 2. Если количество партиций будет больше 10, в этом случае 10 потоков Applier (Gigabas) будут переключаться для обработки излишних партиций. Если один pod Applier (Gigabas) не справляется с нагрузкой, рекомендуется для каждого нового pod Applier (Gigabas), использующего 10 потоков, добавлять 10 новых партиций в topics. Например, при использовании трех pods Applier (Gigabas) на одном плече и трех pods Applier (Gigabas) на втором плече рекомендуется создать 60 партиций для topics |
|
5 |
Настройка клиентской библиотеки ПЖ. Количество попыток применения вектора изменений |
|
10000 |
Настройка клиентской библиотеки ПЖ. Задержка между попытками обработать вектор изменений с ошибками репликации (в мс) |
|
10000 |
Настройка клиентской библиотеки ПЖ |
Проверка интеграции DataSpace с ПЖ на стенде разработки/тестирования#
Проверка интеграции DataSpace с ПЖ на стенде разработки /тестирования осуществляется:
Внимание!
Рекомендуется использовать проверку через тестовый запрос.
Проверка интеграции DataSpace с ПЖ на стенде по логам#
Выполните создание сущности (в данном примере создается сущность Product) и убедитесь, что она появилась в БД основного контура.
В логах DataSpace найдите следующие текстовые термы: Sent LCK+DATA journal. Данная строка лога означает, что в ПЖ отправлен вектор с данными. В этой же строке уникальный идентификатор в терминах ПЖ — id сервиса. Пример данной информации: serviceId 909ee533-36d2-4be9-b214-4ca55c676c7f_6904652537442598913#Product, где:
909ee533-36d2-4be9-b214-4ca55c676c7f — идентификатор транзакции;
6904652537442598913 — идентификатор агрегата;
Product — тип агрегата.
Пример строки лога:
2020-12-10 18:38:14,884 [general-pool-thread-3] [INFO] (sbp.com.sbt.dataspace.replication.PostTransactionConfirmatorImpl) [sbp.com.sbt.dataspace.replication.PostTransactionConfirmatorImpl::sendAck:23] mdc:()| tx 909ee533-36d2-4be9-b214-4ca55c676c7f: Received ACK
В логах Applier найти следующие текстовые термы: Applied journal createMode = 0, dataType = DATASPACE (означает, что вектор с данными успешно применен). В этой же строке находится id сервиса: serviceId = 909ee533-36d2-4be9-b214-4ca55c676c7f_6904652537442598913#Product (тот же, что и в логах DataSpace).
Пример строки лога:
2020-12-10 18:38:15,123 [consumer-2-C-1] [INFO] (sbp.dataspace.standin.journal.StandInJournalConsumer) [sbp.dataspace.standin.journal.StandInJournalConsumer::handle:60] mdc:()| Applied journal createMode = 0, dataType = DATASPACE, serviceId = 909ee533-36d2-4be9-b214-4ca55c676c7f_6904652537442598913#Product
Проверка интеграции DataSpace с ПЖ на стенде через UI ПЖ#
Для того чтобы осуществить проверку через UI ПЖ, необходимо:
В режиме журнала установить фильтр по полю ID Сервиса.
В качестве значения указать значение из лога DataSpace: 909ee533-36d2-4be9-b214-4ca55c676c7f_6904652537442598913#Product.
В итоге должно быть найдено две строки:
первая — с типами данных LCK и DATASPACE;
вторая — с типом данных ULCK.
Проверка интеграции DataSpace с ПЖ на стенде через тестовый запрос#
Для того чтобы осуществить проверку через тестовый запрос, необходимо:
Убедиться, что активным является основной контур (Normal).
Выполнить создание сущности в контуре Main (например, Product), получить в ответе идентификатор (например, 6904652537442522222).
Выполнить SQL-запрос в БД основного контура и убедиться, что данная сущность присутствует. Для контроля убедиться, что дата создания сущности соответствует действительности.
Выполнить SQL-запрос в БД контура SI и убедиться, что данная сущность присутствует. Для контроля убедиться, что дата создания сущности соответствует действительности и совпадает с датой на основном контуре.
Убедиться, что все поля в таблице по данной сущности (Product с id = 6904652537442522222) полностью совпадают на обоих контурах.
Выполнить переход в режим «Функциональный StandIn».
Выполнить создание сущности в контуре StandIn (например, Product), получить в ответе идентификатор (например, 6904652537442577777).
Выполнить SQL-запрос в БД контура SI и убедиться, что данная сущность присутствует. Для контроля убедиться, что дата создания сущности соответствует действительности.
Выполнить SQL-запрос в БД основного контура и убедиться, что данная сущность отсутствует, поскольку при переходе в SI автоматически отключаются плагины репликации.
Выполнить переход в основной контур (Normal). При этом плагины автоматически включатся и репликация в основной должна быть выполнена.
Выполнить SQL-запрос в БД основного контура и убедиться, что данная сущность присутствует. Для контроля убедиться, что дата создания сущности соответствует действительности и совпадает с датой в контуре StandIn.
Убедиться, что все поля в таблице по данной сущности (Product с id = 6904652537442577777) полностью совпадают на обоих контурах.
Отключение репликации и отправки векторов в ПЖ#
Чтобы отключить соединение модулей DataSpace с ПЖ, необходимо установить значения двух параметров во всех модулях DataSpace:
standin.cloud.client.stub=true,dataspace.replication.enabled=false.
Чтобы включить соединение модулей DataSpace с ПЖ, необходимо установить значения двух параметров во всех модулях DataSpace:
standin.cloud.client.stub=false,dataspace.replication.enabled=true.
Контроль векторов компонента Прикладной журнал (APLJ) по имени и версии модели#
Данный режим нужен для корректной обработки следующих ситуаций:
Ошибочная настройка модулей DataSpace для разных моделей данных на одну и ту же зону ПЖ.
Штатный режим обновления модулей DataSpace с новой версией модели данных, при этом могут возникнуть следующие ситуации:
Версия модели данных модуля обработчика векторов (Applier/Gigabas) новее, чем версия в векторе, и обратно совместима.
Версия модели данных модуля обработчика векторов (Applier/Gigabas) новее, чем версия в векторе, и обратно несовместима.
Версия модели данных в векторе новее, чем версия модуля обработчика векторов (Applier/Gigabas).
Описание параметров#
Имеются следующие параметры:
dataspace.replicator.model.send-model-id— признак включения режима добавления имени модели в заголовок вектора (по умолчанию — «true»).dataspace.replicator.model.send-model-version— признак включения режима добавления версии модели в заголовок вектора (по умолчанию — «true»).dataspace.replicator.model.versioning-enabled— признак включения режима контроля имени и версии модели (по умолчанию — «true»).
Алгоритм контроля#
Алгоритм контроля реализован с использованием следующей логики:
Если в векторе нет имени модели, в рамках поддержки обратной совместимости контроль завершается успешно.
Если в векторе есть имя модели и оно не совпадает с именем модели модуля обработчика векторов Applier/Gigabas (далее — Applier), возникает ошибка применения вектора, контроль завершается неудачно.
Если версия модели в векторе отсутствует или не задана, в рамках поддержки обратной совместимости считается, что версия модели равна 0.0.0 для последующих пунктов контроля.
Если версия модели в векторе строго равна версии модели Applier, контроль завершается успешно.
Если версия модели в векторе строго больше (новее) версии модели Applier, контроль завершается неудачно и происходит отписка Applier от topics Kafka ПЖ для исключения дальнейшей обработки векторов данным конкретным экземпляром Applier. Возникновение данной ситуации подразумевает выполнение обновления версий модулей и появление в числе прочих обновленных Applier, которые и предназначены для дальнейшей работы по применению векторов.
Если версия модели в векторе строго меньше (старее) версии модели Applier, и при этом данная версия обратно не совместима с версией Applier, контроль завершается неудачно. Неудачный вектор сможет применить только Applier с той же самой версией.
Во всех остальных ситуациях контроль завершается успешно.
Примеры отражения контроля в логах#
Примеры:
В векторе нет имени модели. Ключевая фраза:
detected JournalDataContainer without modelId.2023-03-20 05:43:51,209 [consumer_DZ-49_EXPORT_FUNC_SI_DATASPACE-6-C-1] [WARN] (sbp.dataspace.standin.listener.modelversion.ModelVersionApplyingPipelineListener) [sbp.dataspace.standin.listener.modelversion.ModelVersionApplyingPipelineListener::preApply:49] mdc:()| e9164099-a0fa-43f0-bc39-c16d748017f8: detected JournalDataContainer without modelIdВ векторе имя модели не совпадает. Ключевая фраза:
detected JournalDataContainer without modelVersion, use DEFAULT modelVersion='0.0.0'.2023-03-20 06:50:02,212 [consumer_DZ-49_EXPORT_FUNC_SI_DATASPACE-8-C-1] [ERROR] (sbp.dataspace.standin.journal.StandinJournalConsumer) [sbp.dataspace.standin.journal.StandinJournalConsumer::handle:72] mdc:()| Исключение при попытке применения журнала sbp.dataspace.standin.listener.modelversion.ModelVersionIncompatibleException: 97340eb2-a636-4553-b9d6-093ed1a3d051: ModelId mismatch was found. applier='jjj5', received='jjj5_v2'В векторе нет версии модели. Ключевая фраза:
detected JournalDataContainer without modelVersion, use DEFAULT modelVersion='0.0.0'.2023-03-20 05:59:22,747 [consumer_DZ-49_EXPORT_FUNC_SI_DATASPACE-9-C-1] [WARN] (sbp.dataspace.standin.listener.modelversion.ModelVersionApplyingPipelineListener) [sbp.dataspace.standin.listener.modelversion.ModelVersionApplyingPipelineListener::preApply:63] mdc:()| 381c392f-c304-41f3-907c-84d9db6bda78: detected JournalDataContainer without modelVersion, use DEFAULT modelVersion='0.0.0'Успешный контроль. Ключевая фраза:
JournalDataContainer model version is compatible.2023-03-20 07:14:02,229 [consumer_DZ-49_EXPORT_FUNC_SI_DATASPACE-5-C-1] [DEBUG] (sbp.dataspace.standin.listener.modelversion.ModelVersionApplyingPipelineListener) [sbp.dataspace.standin.listener.modelversion.ModelVersionApplyingPipelineListener::preApply:79] mdc:()| 048cd268-4010-4828-a8b0-73485b1c48d1: JournalDataContainer model version is compatible. applier='DEV-SNAPSHOT', received='DEV-SNAPSHOT' 2023-03-20 13:21:50,129 [consumer_DZ-46_EXPORT_FUNC_SI_DATASPACE-5-C-1] [DEBUG] (sbp.dataspace.standin.listener.modelversion.ModelVersionApplyingPipelineListener) [sbp.dataspace.standin.listener.modelversion.ModelVersionApplyingPipelineListener::preApply:79] mdc:()| ca4722e9-4d1d-4da5-b375-6760f3d8be8b: JournalDataContainer model version is compatible. applier='3.0.1', received='3.0.1' 2023-03-20 15:01:52,652 [consumer_DZ-46_EXPORT_FUNC_SI_DATASPACE-4-C-1] [DEBUG] (sbp.dataspace.standin.listener.modelversion.ModelVersionApplyingPipelineListener) [sbp.dataspace.standin.listener.modelversion.ModelVersionApplyingPipelineListener::preApply:79] mdc:()| a154ab5e-02b3-434f-bd53-e86400723d02: JournalDataContainer model version is compatible. applier='5.0.1', received='5.0.0'Версия в векторе новее. Ключевая фраза:
Received version more than model version.2023-03-20 15:12:47,673 [consumer_DZ-46_EXPORT_FUNC_SI_DATASPACE-9-C-1] [ERROR] (sbp.dataspace.standin.journal.StandinJournalConsumer) [sbp.dataspace.standin.journal.StandinJournalConsumer::handle:72] mdc:()| Исключение при попытке применения журнала sbp.dataspace.standin.listener.modelversion.ModelVersionMoreThanCurrentException: e96be73c-5714-48b1-a776-467b53e6a535: Received version more than model version. applier = 5.0.0, received = 5.0.1И отписка от чтения остальных векторов:
2023-03-20 15:12:48,167 [consumer_DZ-46_EXPORT_FUNC_SI_DATASPACE-9-C-1] [INFO] (org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler) [org.springframework.scheduling.concurrent.ExecutorConfigurationSupport::shutdown:218] mdc:()| Shutting down ExecutorService 2023-03-20 15:12:48,270 [consumer_DZ-46_EXPORT_FUNC_SI_DATASPACE-4-C-1] [INO] (org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer) [org.springframework.core.log.LogAccessor::info:292] mdc:()| reader_DZ-46_DATASPACE_EXPORT_FUNC_SI: Consumer stopped 2023-03-20 15:12:48,271 [consumer_DZ-46_EXPORT_FUNC_SI_DATASPACE-1-C-1] [INFO] (org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer) [org.springframework.core.log.LogAccessor::info:292] mdc:()| reader_DZ-46_DATASPACE_EXPORT_FUNC_SI: Consumer stoppedВерсия в векторе старая и обратно не совместимая. Ключевая фраза:
JournalDataContainer model version is not compatible.2023-03-20 15:21:05,351 [consumer_DZ-46_EXPORT_FUNC_SI_DATASPACE-0-C-1] [ERROR] (sbp.dataspace.standin.journal.StandinJournalConsumer) [sbp.dataspace.standin.journal.StandinJournalConsumer::handle:72] mdc:()| Исключение при попытке применения журнала sbp.dataspace.standin.listener.modelversion.ModelVersionIncompatibleException: a78b86fe-922c-47e8-a530-5a0a2ec50a74: JournalDataContainer model version is not compatible. applier = 5.0.0, received = 3.0.1
Бинарная сериализация векторов#
Данный режим нужен для корректной обработки следующих ситуаций:
Бизнес-данные содержат спецсимволы, которые не обрабатываются обычной сериализацией.
Затруднить просмотр бизнес-данных.
Уменьшить размер вектора при использовании бинарной сериализации с компрессией.
Описание параметров#
Для указания алгоритма сериализации используется параметр dataspace.replicator.data-type-info.ORM_CV.serializer-id.
Значения:
change_vector_jsox— JSON-сериализация (значение по умолчанию);change_vector_kryo— бинарная Kryo сериализация;change_vector_kryz— бинарная Kryo сериализация с компрессией в gzip формат.
Примеры векторов#
Сериализация выполняется по бизнес-данным, которые указаны в качестве значения атрибута data.
JSON-сериализация:
{
"type": "DATASPACE",
"txId": "0d6acf3e-1ce2-4fb1-bdf9-884bbc866145",
"headers": {
"rootClass": "sbp.com.sbt.dataspace.jpa.RootEntity",
"prevRootVersion": 0,
"siVersion": 1,
"rootId": "7213244565303459841",
"modelId": "jjj5",
"modelVersion": "DEV-SNAPSHOT",
"rootVersion": 1,
"guid": "53273065-a618-4b90-b50f-69633857ae8c",
"protocolVersion": "1.1.0",
"txTimestamp": 1679464374617
},
"partitions": [
{
"type": "ORM_CV",
"serializer": "change_vector_json",
"format": "JSON",
"payload": {
"serializerInfo": {
"id": "3375153340802439707",
"name": "json_gson",
"format": "JSON"
},
"data": {
"type": "DELTA",
"txId": null,
"partitionId": null,
"changeSets": [
{
"createEvents": [
{
"alias": "sbp.com.sbt.dataspace.jpa.RootEntity",
"id": "7213244565303459841",
"primitives": {
"partitionId": 0,
"syalReason": null,
"lastChangeDate": "2023-03-22T05:52:54.602Z",
"recModelVersion": null,
"syalActive": false,
"ownerId": null,
"syalToken": null,
"uniqueName": null,
"isDeleted": false,
"syalTimeout": null,
"name": "createRootEntity",
"offFlag": null,
"syalChangeDate": null,
"chgCnt": null
},
"references": {},
"primitiveCollections": {},
"referenceCollections": {
"leafEntitys": [],
"apiCalls": []
},
"version": null
}
],
"updateEvents": [],
"deleteEvents": [],
"snapshotEvents": []
}
]
}
}
}
]
}
Бинарная Kryo-сериализация:
{
"type": "DATASPACE",
"txId": "1d445403-9bd5-41c8-9b87-a6649cad2e21",
"headers": {
"rootClass": "sbp.com.sbt.dataspace.jpa.RootEntity",
"prevRootVersion": 0,
"siVersion": 1,
"rootId": "7213242447844868097",
"modelId": "jjj5",
"modelVersion": "DEV-SNAPSHOT",
"rootVersion": 1,
"guid": "28edafed-c6ef-4829-a14f-4abcdfc4cc37",
"protocolVersion": "1.1.0",
"txTimestamp": 1679463882048
},
"partitions": [
{
"type": "ORM_CV",
"serializer": "change_vector_kryo",
"format": "JSON",
"payload": {
"serializerInfo": {
"id": "4086061529959564203",
"name": "binary_kryo",
"format": "BASE64"
},
"data": "CxeCDAAXgg0ApXNicC5jb20uc2J0LmRhdGFzcGFjZS5qcGEuUm9vdEVudGl0eQM3MjEzMjQyNDQ3ODQ0ODY4MDm3FgEWD3BhcnRpdGlvbknkAgBzeWFsUmVhc2_uAGxhc3RDaGFuZ2VEYXTlH5G45L7wMHJlY01vZGVsVmVyc2lv7gBzeWFsQWN0aXblBQBvd25lcknkAHN5YWxUb2tl7gB1bmlxdWVOYW3lAGlzRGVsZXRl5AUAc3lhbFRpbWVvdfQAbmFt5QNjcmVhdGVSb290RW50aXT5b2ZmRmxh5wBzeWFsQ2hhbmdlRGF05QBjaGdDbvQAFgNsZWFmRW50aXR58xcBYXBpQ2FsbPMXARYBABcBFwEXAYAAAQ\u003d\u003d"
}
}
]
}
Бинарная Kryo-сериализация с компрессией в gzip-формат:
{
"type": "DATASPACE",
"txId": "2fe40d1e-3359-4fc5-926c-cdd2e609ffc5",
"headers": {
"rootClass": "sbp.com.sbt.dataspace.jpa.RootEntity",
"prevRootVersion": 0,
"siVersion": 1,
"rootId": "7213240770615050241",
"modelId": "jjj5",
"modelVersion": "DEV-SNAPSHOT",
"rootVersion": 1,
"guid": "dce2dcf9-a40c-4706-b720-69fd020d6221",
"protocolVersion": "1.1.0",
"txTimestamp": 1679463491424
},
"partitions": [
{
"type": "ORM_CV",
"serializer": "change_vector_kryz",
"format": "JSON",
"payload": {
"serializerInfo": {
"id": "5762210136291029842",
"name": "binary_kryo_gzip",
"format": "BASE64"
},
"data": "H4sIAAAAAAAAAEWPMU7DQBBFx1ipIKKzS26w2pgE18gBKQUUEaKfbMbJwnrX7K5B6VDuwgGo6DgB4hS26CIk0qTDSSTQb0bzXvH_Ybw8gnjZhRc3KZkwBXMTz6bo0ZUoiN2VyMbG-AvtpV-EadI7Tfo8TflZb8AHPOm_RkF0XKJtsTR6VB-AW6AaEzqzAoXOZ3PUMxqib07ePj_ev7klcWWmpG7JOtlKW_9cePnYdMA8abKjeve7Mfe0gkrLh4qusWhAuiEp8lR39lwWZKo16JaFwhJ6-mu6MXl-qfBrJ_43ADGfZXoNUagI8_2mnzjAUmaoVHtFAcTBNs8Q_ALUyf1_GwEAAA\u003d\u003d"
}
}
]
}
Методика выполнения BSSI-инициализации и BSSI-сверки в ПЖ#
Методика выполнения BSSI-инициализации#
Внимание!
Данная методика относится только к синхронизации контура StandIn и не затрагивает возможное влияние на смежные системы (например, ARCH).
Необходимо выполнить следующие действия:
Убедиться, что находимся в функциональном NORMAL.
Отключить вручную плагины по репликации:
EXPORT_FUNC_SI (тип данных = DATASPACE);
EXPORT_FUNC_SI_LCK (тип данных = LCK);
EXPORT_FUNC_SI_LCK (тип данных = ULCK);
EXPORT_FUNC_SI_REJ (тип данных = REJ).
Запустить BSSI-инициализацию.
Включить вручную плагины по репликации (список плагинов см. в п.2).
Запустить BSSI-сверку и получить 100% совпадение.
Отключить вручную плагины по репликации (список плагинов см. в п.2).
Дождаться появления нагрузки.
Запустить BSSI-сверку и получить расхождения.
Включить вручную плагины по репликации (список плагинов см. в п.2).
Запустить BSSI-сверку и получить 100% совпадение.
Перейти в режим «Функциональный StandIn».
Дождаться, когда весь поток векторов в направлении на SI по всем плагинам из п.2 реплицируется.
Отключить вручную плагины по репликации (список плагинов см. в п.2).
Дождаться появления нагрузки.
Запустить BSSI-сверку и получить расхождения.
Включить вручную плагины по репликации (список плагинов см. в п.2).
Запустить BSSI-сверку и получить 100% совпадение.
Вернуться в функциональный NORMAL.
Методика для настройки конфигуратора BSSI-сверки#
Необходимо выполнить следующие действия:
Загрузить абсолютно все таблицы по схеме, ни одну из них не удалять!
Исключить из BSSI-сверки таблиц целиком:
Исключить служебные таблицы Liquibase:
DATABASECHANGELOG,
DATABASECHANGELOGLOCK,
LIQ_DATABASECHANGELOG,
LIQ_DATABASECHANGELOGLOCK.
Исключить служебную таблицу по обслуживанию StandIn-блокировок агрегатов T_REPL_AGGLOCKEVENT.
Исключить служебные таблицы, используемые в процессе инициализации в ARCH:
T_DSPC_SYS_INIT_TASK,
T_DSPC_SYS_INIT_SUBTASK,
T_DSPC_SYS_CHANGE_EVENT.
Исключить служебные таблицы DataSpace Subscription:
T_DSPC_SYS_SUBSCRIPTION_PROCESS,
T_DSPC_SYS_SUBSCRIPTION_WORKER.
Исключить служебное представление (VIEW) SYSGETCURRENTTIME.
Исключить таблицы, которые не относятся к DataSpace, но созданы сторонними процессами.
Исключить служебные таблицы для хранения результатов проверки целостности:
T_DSPC_SYS_INTEGRITYCHECK,
T_DSPC_SYS_INTEGRITYCHECKREPORT,
T_DSPC_SYS_INTEGRITYCHECKREPORTDETAILS.
Исключить служебную таблицу T_DSPC_SYS_SHEDLOCK.
Исключить из BSSI-сверки отдельные колонки в таблицах:
У таблицы T_DSPC_SYS_CONFIG исключить колонкy LASTPING,
У таблицы T_SYS_HISTORY_VERSIONS исключить колонкy STARTTIMEDRAFT,
У всех служебных таблиц T_REPL_AGGLOCK_<имя_класса_агрегата> исключить колонки:
TOKEN,
CHGCNT,
INITSTATUS,
MIGRATIONSTATUS.
Методика для настройки конфигуратора BSSI-инициализации#
Необходимо выполнить следующие действия:
Исключить из BSSI-инициализации служебной таблицы целиком T_DSPC_SYS_CONFIG.
Исключить из BSSI-инициализации служебных таблиц в хранилище данных посредством ARCH целиком:
T_DSPC_SYS_INIT_TASK,
T_DSPC_SYS_INIT_SUBTASK,
T_DSPC_SYS_CHANGE_EVENT.
Исключить из BSSI-инициализации служебные таблицы DataSpace Subscription:
T_DSPC_SYS_SUBSCRIPTION_PROCESS,
T_DSPC_SYS_SUBSCRIPTION_WORKER.
Исключить из BSSI-инициализации таблицы, которые не относятся к DataSpace, но созданы сторонними процессами.
Настройка размера векторов#
Данная настройка выполняется на клиентской части и должна быть поддержана настройками серверной части.
Пример лога, когда размер вектора превышает допустимый на клиентской части (ключевая фраза: The message is 3949669 bytes when serialized which is larger than 1048576):
2023-04-25 09:11:49,015 [general-pool-thread-44] [ERROR] (org.springframework.kafka.support.LoggingProducerListener) [org.springframework.core.log.LogAccessor::error:261] mdc:()| Exception thrown when sending a message with key='7225866311241105409#EncashmentContract' and payload='<?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:journal xmlns:ns2="http://journal.sbrf.r...' to topic journal_writer_topic_cash-collection-fabric: org.apache.kafka.common.errors.RecordTooLargeException: The message is 3949669 bytes when serialized which is larger than 1048576, which is the value of the max.request.size configuration.
Если точно известно, что сервер поддерживает размер сообщений 5 Мб, необходимо указать следующие параметры для всех модулей DataSpace:
standin.cloud.client.kafka.producerConfig."[max.request.size]"=5242880;standin.cloud.client.kafka.consumerConfig."[fetch.max.bytes]"=5242880.
Настройка представления данных в ПЖ в режиме Журнал#
Имеются следующие параметры для настройки представлений данных в журнале ПЖ:
dataspace.replication.transaction-id-format— выбор представления векторов в журнале ПЖ:V1 — представление 1;
V2 — представление 2 (по умолчанию).
dataspace.replication.transaction-id-length(только для представления V2) — принудительное обрезание значений колонок ID КЛИЕНТА и SERVICEIDTYPE до указанного количества символов (по умолчанию — «100»). Значения менее «100» не разрешены (будет принудительно установлено значение «100»). Значение данного параметра может быть увеличено только в том случае, если на стороне ПЖ будут реализованы доработки по увеличению допустимого размер указанных колонок.
Представление 1 (V1)#
Представление 1 используется по умолчанию и в общем случае отображает всю необходимую информацию о транзакциях и затронутых ими агрегатах.
Пример представления 1:

Описание таблицы:
ДАТА СОБЫТИЯ — дата и время (с указанием миллисекунд) создания вектора при его формировании модулем, создающим транзакцию (обычно — это модуль dataspace-core).
ID СЕРВИСА — уникальный идентификатор вектора. Пример значения: c740cbdc-85f2-406b-a922-3f1ae83a3344_7257461774256242691#AnalyticByDirection, где:
c740cbdc-85f2-406b-a922-3f1ae83a3344 — уникальное значение длиной 36 символов;
_ — разделитель;
7257461774256242691#AnalyticByDirection — значение из колонки ID КЛИЕНТА.
SERVICEIDTYPE — дополнительный идентификатор для усиления уникальности совместно со значением ID СЕРВИСА. Пример значения: datalck_0710051a-781c-4718-a879-46baa375f15c, где:
datalck — информационная метка о том, что этот вектор является вектором с данными (data) и имеет вектор с блокировкой StandIn (lck);
_ — разделитель;
0710051a-781c-4718-a879-46baa375f15c — частичное значение из колонки ID транзакции, которое содержит в себе уникальную строку, обозначающую создавшую данный вектор транзакцию.
ID СОБЫТИЯ — уникальный идентификатор вектора, сформированный самим ПЖ.
КОД ОПЕРАЦИИ — версия агрегата.
ID КЛИЕНТА — идентификатор и тип агрегата. Пример значения: 7257461774256242691#AnalyticByDirection, где:
7257461774256242691 — идентификатор агрегата;
# — разделитель;
AnalyticByDirection — корневой тип агрегата.
РЕЖИМ ФОРМИРОВАНИЯ — состояние StandIn в момент формирования вектора (NORMAL или STANDIN).
Дата записи — дата и время (с указанием миллисекунд) записи вектора в журнал ПЖ.
partitionDate — дата записи вектора в журнал ПЖ.
ID транзакции — уникальный идентификатор транзакции вектора, используется в режиме с подтверждениями commits. Пример значения: 0710051a-781c-4718-a879-46baa375f15c_7257461774256242691#AnalyticByDirection, где:
0710051a-781c-4718-a879-46baa375f15c — уникальное значение длиной 36 символов;
_ — разделитель;
7257461774256242691#AnalyticByDirection — значение из колонки ID КЛИЕНТА.
Система инициатор — будет установлено значение DATASPACE при формировании вектора любым модулем DataSpace.
Оператор — значение будет установлено в зависимости от модуля DataSpace, сформировавшего вектор:
DATASPACE — вектор создал модуль dataspace-core или dataspace-bundle;
SM — вектор создал модуль dataspace-cr-state-machine;
DM — вектор создал модуль dataspace-cr-duplication-service;
MG — вектор создал модуль dataspace-cr-migration-service.
Продукт — имеет значение только в случае мультитранзакций, когда в одной транзакции затрагивается несколько агрегатов. В этом случае формируется несколько векторов в соответствии с числом затронутых агрегатов. Значение поля является числом и показывает, сколько всего векторов сформировано вместе с данным. Пример значения: 3. То есть всего сформировано три вектора (или всего затронуто три агрегата), включая и текущий вектор. Чтобы найти, какие три вектора сформированы одной и той же транзакцией, нужно организовать поиск в фильтре по колонке SERVICEIDTYPE, значение взять из текущего вектора, поскольку это поле будет одинаковым у всех искомых векторов. На приведенном выше рисунке видно, что у всех трех векторов — одинаковое значение в колонке SERVICEIDTYPE.
Представление 2 (V2)#
Недостаток представления V1 состоит в том, что размер колонок ID СЕРВИСА, ID КЛИЕНТА и ID транзакции является не управляемым и может превысить размер, который задан в БД ПЖ (на момент написания документации — 100 символов). Это может произойти из-за того, что длины идентификатора агрегата и корневого типа агрегата являются переменными величинами. Так как максимальная поддерживаемая DataSpace длина идентификатора равна 254 символа, и максимальная длина имени корневого класса также равна 254 символа, такие строки не могут поместиться в БД ПЖ.
Для решения данной проблемы было разработано представление 2 (V2).
Пример представления 2:

Описание таблицы:
ДАТА СОБЫТИЯ — дата и время (с указанием миллисекунд) создания вектора при его формировании модулем, создающим транзакцию (обычно — это модуль dataspace-core).
ID СЕРВИСА — уникальный идентификатор вектора. Пример значения: 22948533-052c-493b-8bea-bf26d76e8f8a_fe21c1, где:
22948533-052c-493b-8bea-bf26d76e8f8a — уникальное значение длиной 36 символов;
_ — разделитель;
fe21c1 — первые 6 знаков от результата вычисления хеш по функции md5, где входной строкой является значение колонки ID КЛИЕНТА для представления V1. Таким образом размер колонки ID СЕРВИСА всегда будет равен 43 символам.
SERVICEIDTYPE — тип агрегата. Пример значения: PaymentDetails. По умолчанию если значение имеет размер более 100 символов, в ПЖ подставляется первые 100 символов имени типа агрегата. Таким образом размер колонки SERVICEIDTYPE ограничен 100 символами.
ID СОБЫТИЯ — уникальный идентификатор вектора, сформированный самим ПЖ.
КОД ОПЕРАЦИИ — версия агрегата.
ID КЛИЕНТА — идентификатор агрегата. Пример значения: 7257526704546775041. По умолчанию если значение имеет размер более 100 символов, в ПЖ подставляется первые 100 символов идентификатора агрегата. Таким образом, размер колонки ID КЛИЕНТА ограничен 100 символами.
РЕЖИМ ФОРМИРОВАНИЯ — состояние StandIn в момент формирования вектора (NORMAL или STANDIN).
Дата записи — дата и время (с указанием миллисекунд) записи вектора в журнал ПЖ.
partitionDate — дата записи вектора в журнал ПЖ.
ID транзакции — уникальный идентификатор транзакции вектора, используется в режиме с подтверждениями commits. Пример значения: 5e1ed659-9c7b-4531-bbb3-60d0ffaa91c9_fe21c18fdc3d05de2ac9b36d55979952, где:
5e1ed659-9c7b-4531-bbb3-60d0ffaa91c9 — уникальное значение длиной 36 символов;
_ — разделитель;
fe21c18fdc3d05de2ac9b36d55979952 — результат вычисления хеш по функции md5, где входной строкой является значение колонки ID КЛИЕНТА для представления V1, значение длиной 32 символа. Кроме того, данное значение подставляется в служебное поле ПЖ, по которому выполняется раскладывание векторов по партициям. Таким образом, размер колонки ID транзакции всегда будет равен 69 символов.
Система инициатор — будет установлено значение DATASPACE при формировании вектора любым модулем DataSpace.
Оператор — значение будет установлено в зависимости от модуля DataSpace, сформировавшего вектор:
DATASPACE — вектор создал модуль dataspace-core или dataspace-bundle;
SM — вектор создал модуль dataspace-cr-state-machine;
DM — вектор создал модуль dataspace-cr-duplication-service;
MG — вектор создал модуль dataspace-cr-migration-service.
Продукт — имеет значение только в случае мультитранзакций, когда в одной транзакции затрагивается несколько агрегатов. В этом случае формируется несколько векторов в соответствии с числом затронутых агрегатов. Значение поля является числом и показывает, сколько всего векторов сформировано вместе с данным. Пример значения: 3#c710461687154732b90a669da9cd6f, где:
3 — всего сформировано векторов (или всего затронуто агрегатов) включая и текущий вектор;
# — разделитель;
c710461687154732b90a669da9cd6f — результат вычисления хеш по функции md5, где входной строкой является первая часть колонки ID транзакции (уникальное значение длиной 36 символов). В ПЖ подставляется первые 32 символа вычисленного таким образом значения. Чтобы найти, какие три вектора сформированы одной и той же транзакцией, нужно организовать поиск в фильтре по колонке Продукт, значение взять из текущего вектора, поскольку это поле будет одинаковым у всех искомых векторов. На приведенном выше рисунке видно, что у всех трех векторов — одинаковое значение в поле Продукт.