Перейти к основному содержимому

Установка RPLW в DropApp

Порядок установки​

  1. Проверьте и подготовьте параметры в common репозитории стенда для воркера (RPLW).
  2. Используя средства Pipeline, выполните миграцию конфигурационных файлов GraDeLy на узел.
  3. Внесите в конфигурационные файлы GraDeLy на узле необходимые изменения.
  4. Проверьте и подготовьте параметры k8s в namespace.
  5. Удалите устаревшие ресурсы Kubernetes.
  6. Настройте секреты в системе управления секретами HashiCorp Vault.
  7. Настройте интеграцию с компонентом IGEG.
  8. Настройте интеграцию с компонентом Журналирование (LOGA).
  9. Настройте интеграцию с компонентом Объединенный мониторинг Unimon (MONA).
  10. Настройте интеграцию с Kafka.
  11. Настройте интеграцию с компонентом OTTS.
  12. Настройте интеграцию с HashiCorp Vault.
  13. Предустановите конфигурацию.
  14. Произведите полную установку GraDeLy.
  15. Определите максимальную производительность.
Внимание!

Убедитесь, что создан пользователь (роль) в БД источника и приемника для выполнения репликации и выданы ему необходимые права (обязательный). Воспользуйтесь Подготовкой БД источника и БД приемника для работы с GraDeLy.

Шаг 1. Проверьте и подготовьте параметры в common репозитории стенда для воркера (RPLW) (обязательный)​

Последовательность действий​

  • Параметры ${стенд}/installer/system/efs/config/parameters/ssl.conf

    Для RPLW:

    ssl.ose.istio.rplw.kafka.fqdns - FQDN серверов kafka через запятую
    ssl.ose.istio.rplw.kafka.ips - IP-адреса серверов kafka через запятую в порядке, совпадающем с предыдущем значением; если IP не используется, выставляется значение none
    ssl.ose.istio.rplw.psql.fqdns - FQDN серверов БД источников/приемников Postgres через запятую
    ssl.proxy.type - тип proxy на ингресс-контроллере (nginx или haproxy)
    ssl.ose.secman.host - адрес сервера secman
    ssl.ose.secman.port - порт для подключения к серверу secman
    rplw.ose.deployment.spec.template.metadata.annotations.vault.hashicorp.com.namespace - имя namespace в vault, где хранятся секреты проекта
    rplw.ose.deployment.spec.template.metadata.annotations.vault.hashicorp.com.role.module - имя роли в vault, от которой будут выполняться API-вызовы vault-agent для namespace module
    rplw.ose.deployment.spec.template.metadata.annotations.vault.hashicorp.com/client-max-retries - максимальное количество попыток переподключения к серверу vault
    rplw.ose.deployment.spec.template.metadata.annotations.vault.hashicorp.com/agent-limits-cpu - максимальное значение ресурсов по CPU для sidecar vault-agent
    rplw.ose.deployment.spec.template.metadata.annotations.vault.hashicorp.com/agent-limits-mem - максимальное значение ресурсов по RAM для sidecar vault-agent
    rplw.ose.deployment.spec.template.metadata.annotations.vault.hashicorp.com/agent-requests-cpu - минимальное значение ресурсов по CPU для sidecar vault-agent
    rplw.ose.deployment.spec.template.metadata.annotations.vault.hashicorp.com/agent-requests-mem - минимальное значение ресурсов по CPU для sidecar vault-agent
  • Параметры ${стенд}/parameters/common.conf.yml

    Для RPLW:

    DB_SCHEMA_worker - схема БД приемника, для проливки скриптов LB
    RPLW_POSTGRES_DB_URL_worker - адрес в БД приемника в формате jdbc:postgresql://x.x.x.x:port/db_name, если кластер БД то jdbc:postgresql://x.x.x.x:port,x.x.x.x:port/db_name?targetServerType=master&prepareThreshold=0
    registry - адрес registry
    registry_path - путь до директории с компонентом в registry
    registry_path_igeg - путь до компонента образа istio
    registry_path_otts - путь до компонента образа ott
    registry_path_loga - путь до компонента образа fluent-bit
  • Параметры ${стенд}/installer/system/efs/config/parameters/_global.resources.conf

    global.platform.auth.host - адреса backend Keycloak через запятую
    global.platform.iam.auth.host - адрес Keycloak
    global.platform.iam.auth.port - порт Keycloak
    global.platform.audit.proxy.https.host - адрес Audit c ОТТ
    global.platform.audit.proxy.https.host_no_ott - адрес Audit без ОТТ
    global.platform.audit.proxy.https.port - порт Audit
    global.platform.audit.proxy.https.url.path - путь до endpoint аудита PVM

    global.platform.secman.kv.basepath - адрес хранилища секретов kv в Secman
    global.platform.secman.pki.basepath - адрес хранилища секретов pki в Secman
    global.platform.secman.kv.jdbcpath - имя секрета сертификатов БД конфигураций в kv Secman
    global.platform.secman.kv.auditpath - имя секрета сертификатов Audit конфигураций в kv Secman
    global.platform.secman.kv.ottpath - имя секрета сертификатов OTT конфигураций в kv Secman
    global.platform.secman.pki.ott - путь до секрета в PKI (OTT)
    global.platform.secman.kv.ingresspath - путь до KV Ingress
    global.platform.secman.pki.audit - путь до секрета в PKI (Audit)
    global.platform.secman.pki.logger - путь до секрета в PKI (Logger)
    global.platform.secman.kv.iamsecret - секрет от Keycloak
    global.platform.secman.kv.loggerpath - путь до секрета в KV (Logger)
  • Параметры ${стенд}/installer/system/efs/config/parameters/_global.ott.conf

    Для RPLW:

    global.platform.rplw.ott.module.id - Имя модуля, указанное в поле CN запроса и сертификата клиента ОТТ
    global.platform.rplw.ott.service.hosts - Адрес сервера OTTS
  • Параметры ${стенд}/installer/system/efs/config/parameters/openShift.conf

    global.platform.logger.kafka.bootstrap.servers
    global.platform.logger.kafka.topic
    global.platform.ose.kafka.ports
    # Лимит использования Pod-ами эфемерного хранилища
    global.ose.deployment.spec.template.spec.containers.resources.limits.ephemeral-storage
  • Параметры для каждого из двух namespaces ${стенд}/multiClusters.json

    {
    "datacenters": {
    "<nameCluster>": {
    "openshiftCluster": "<url>",
    "openshiftSATokenCred": "<token>",
    "openshiftProjectName": "<namespace>",
    "openshiftControlPlaneProject": "<nameCP>",
    "openshiftControlPlaneIstiodPort": "<portCP>",
    "openshiftControlPlaneIstiodService": "<istiodName>",
    "openshiftControlPlaneJaegerPort": "<jaegerPort>",
    "openshiftControlPlaneJaegerService": "<jaegerService>",
    "openshiftNewRoute": "<routeFQDN>",
    "openshiftAppsDomain": "<domain>",
    "openshiftRoutersFQDN": [
    "<addressCluster>"
    ],
    "overrides": []
    }
    }
    }

    где

    <nameCluster> – имя кластера k8s;
    <url> – адрес кластера k8s;
    <token> – токен с доступом для деплоя в namespace;
    <namespace> – имя namespace k8s;
    <nameCP> – имя controlPanel k8s;
    <portCP> – порт controlPanel k8s;
    <istiodName> – имя istiod k8s;
    <jaegerPort> – порт jaeger k8s;
    <jaegerService> – имя jaegerService k8s;
    <routeFQDN> – часть имени FQDN для формирования Route;
    <domain> – домен кластера ("apps.dap.devpub.example.ru");
    <addressCluster> – адрес кластера k8s.

Проверка результата​

Параметры в common репозитории стенда для воркера подготовлены.

Шаг 2. Мигрируйте конфигурационные файлы GraDeLy (обязательный)​

Последовательность действий​

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

Данные для шаблонизации и миграции находятся в папке дистрибутива conf/config/parameters.

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

Для RPLW:

└── conf
└── config
└── parameters
├── rplw.all.conf
├── rplw.istio.all.conf
├── rplw-module.conf
├── rplw.fluentbit-sidecar.all.conf

Проверка результата​

Конфигурационные файлы мигрированы.

Шаг 3. Внесите в конфигурационные файлы GraDeLy на узле необходимые изменения (обязательный)​

Последовательность действий​

Для реализации поддержки нескольких схем доступа к секретам приложения и потребителей нужно заполнить нижеследующие параметры в rplw-module.conf:

# Для каждой интеграции адрес секрета KV, хранимый в vault, представляется в виде конкатинации двух параметров <имя_модуля>.ose.secman.kv.<имя_интеграции>.basepath и <имя_модуля>.ose.secman.kv.<имя_интеграции>.secret_name
# Для каждой интеграции секрета PKI, генерируемы vault, происходит по двум параметрам: <имя_модуля>.ose.secman.pki.<имя_интеграции>.basepath - движок PKI (имеет список разрешенных common names) и <имя_модуля>.ose.secman.pki.<имя_интеграции>.common_name - common name
# Для входящего трафика и интеграции с ОТТ, внесен тогглер (true/false) <имя_модуля>.ose.secman.kv.<ingress/ott>.add-old-ca-chain, который контролирует подключение KV секрета, для добавления цепочки сертификатов в корневой сертификат (согласно архитектуре: на grdl-console-ui нет ОТТ)
# Для интеграции с БД, Kafka и "из консоли в воркера" KV конкатинация состоит из <имя_модуля>.ose.secman.kv.<имя_интеграции>.basepath и FQDN имени сервиса интеграции, соотвественно данных параметров в ConfigMap нет

rplw-module.ose.secman.kv.psql-cred.basepath=
rplw-module.ose.secman.pki.ingress.basepath=
rplw-module.ose.secman.pki.ingress.common_name=
rplw-module.ose.secman.kv.ingress.add-old-ca-chain=
rplw-module.ose.secman.kv.ingress.old-ca-chain.secret_name=
rplw-module.ose.secman.kv.ingress.old-ca-chain.secret_path=
rplw-module.ose.secman.kv.ingress.basepath=
rplw-module.ose.secman.pki.ott.basepath=
rplw-module.ose.secman.pki.ott.common_name=
rplw-module.ose.secman.kv.ott.add-old-ca-chain=
rplw-module.ose.secman.kv.ott.old-ca-chain.secret_name=
rplw-module.ose.secman.kv.ott.old-ca-chain.secret_path=
rplw-module.ose.secman.kv.ott.basepath=
rplw-module.ose.secman.kv.ott.secret_name=
rplw-module.ose.secman.pki.audit.basepath=
rplw-module.ose.secman.pki.audit.common_name=
rplw-module.ose.secman.kv.audit.basepath=
rplw-module.ose.secman.kv.audit.secret_name=
rplw-module.ose.secman.pki.to_console.basepath=
rplw-module.ose.secman.pki.to_console.common_name=
rplw-module.ose.secman.kv.to_console.basepath=
rplw-module.ose.secman.kv.to_console.secret_name=
rplw-module.ose.secman.pki.logger.basepath=
rplw-module.ose.secman.pki.logger.common_name=
rplw-module.ose.secman.kv.logger.basepath=
rplw-module.ose.secman.kv.logger.secret_name=
rplw-module.ose.secman.pki.psql-eg.basepath=
rplw-module.ose.secman.pki.psql-eg.common_name=
rplw-module.ose.secman.kv.psql-eg.basepath=
rplw-module.ose.secman.pki.kafka.basepath=
rplw-module.ose.secman.pki.kafka.common_name=
rplw-module.ose.secman.kv.kafka.basepath=
rplw-module.secrets.engine=
rplw-module.hot-reload-dir-signing=
  • rplw-module.conf:

    # Имя приложения. Изменять не требуется.
    application-module.name=rplw-module
    # Автоматическое формирование FQDN. Изменять не требуется.
    rplw-module.ose.istio.ingress.route.spec.host.http.consoleFQDN={{ lookup('custom_vars', 'application-console.name') }}-{{ lookup('custom_vars', 'distrib.release.version') }}.{{ lookup('custom_vars', 'global.multiClusters.openshiftNewRoute') }}
    # Url для подключения module к console при старте
    rplw-module.console.url=http://{{ lookup('custom_vars', 'rplw-module.ose.istio.ingress.route.spec.host.http.consoleFQDN') }}/
    # Параметры логирования
    rplw-module.log.root.level=info
    rplw-module.logger.root.level=INFO
    rplw-module.logger.org.springframework.level=INFO
    rplw-module.logger.org.springframework.web.level=INFO
    rplw-module.logger.ru.gradely.level=INFO
    rplw-module.label=
    # Rate limiter
    # Включение Rate limiter
    rplw-module.rate-limiter-enabled=false
    # Префикс метрик
    rplw-module.rate-limiter-metric-prefix=grdl_module
    rplw-module.rate-limiter-buckets=[{"uri":"/general","maxTokens":1000,"refillIntervalSec":1}]
    # Включение работы воркера под ИТУЗ
    rplw-module.db.admin-role-enable=true
    # Автосоздание системных таблиц при использовании ИТУЗ
    rplw-module.auto-create-system-tables-enable=false
    # Автосоздание ресурсов на БД-источнике: publication и replication slot.
    # Для воркеров в контейнерной среде параметр может включаться централизованно через конфигурацию поставки.
    rplw-module.db.auto-create-resources.enabled=false
    # Автоматическое добавление новых таблиц в publication при обработке DDL CREATE TABLE.
    rplw-module.db.auto-create-resources.ddl.enabled=false
    # Режим инициализации DDL-инфраструктуры для автосопровождения publication.
    rplw-module.db.auto-create-resources.ddl.init-mode=SQL
    # Схема для служебных объектов DDL-инициализации.
    rplw-module.db.auto-create-resources.ddl.schema=grdl
    # Разрешенные проекты для данного воркера
    rplw-module.allowed-projects=
    # Путь до каталога с секретом в SECMAN:
    rplw-module.ose.secman.kv.ddl.basepath=
    # Имя секрета, в котором содержатся role_id и secret_id, для авторизации в secman по rest-api. Секрет хранится в KV2
    # Структура секрета:
    # ключ role_id, значение - сам roleid
    # ключ secret_id, значение - сам secret_id
    rplw-module.ose.secman.kv.ddl.secret_name=

    # Список путей к хранилищам кастомных секретов для БД
    # Пример:
    # Заполнено до движка KV2
    # rplw-module.psql.json.list=[{"as_name":"test","creds":[{"prefix":"A/IFT/RPLW/KV2/","secret_path":"ift1"}],[{"prefix":"A/IFT/RPLW/KV2/","secret_path":"ift2"}]}]
    # diff-init-module.secrets.engine=KV2
    #
    # Заполнено до движка PG
    # rplw-module.psql.json.list=[{"as_name":"test","creds":[{"prefix":"A/IFT/RPLW/PG/","secret_path":"ift1"}],[{"prefix":"A/IFT/RPLW/PG/","secret_path":"ift2"}]}]
    # diff-init-module.secrets.engine=PG
    #
    # Заполнено для работы по старому по FQDN
    # rplw-module.psql.json.list= ОСТАВИТЬ ПУСТЫМ
    # rplw-module.secrets.engine= Заполнить PG или KV2

    rplw-module.psql.json.list=
  • rplw.istio.all.conf:

    # Включение/отключение sidecar istio-proxy
    rplw.ose.deployment.spec.template.annotations.istio.inject=true
    # Включение/отключение секретов для pull image из docker registry
    rplw.ose.deployment.spec.template.spec.imagePullSecrets.enabled=true
    # Имя секрета
    rplw.ose.deployment.spec.template.spec.imagePullSecrets.name={registry_name}

    # Управление PeerAuthentication
    # Включение/отключение развертывания манифеста PeerAuthentication
    rplw.ose.istio.peer-authentication.enable=true
    # Управление режимом работы:
    rplw.ose.istio.peer-authentication.mode=STRICT
  • rplw.fluentbit-sidecar.all.conf:

    fluent-bit-sidecar.ose.deployment.spec.template.spec.containers.fluent-bit-sidecar.resources.limits.cpu=200m
    fluent-bit-sidecar.ose.deployment.spec.template.spec.containers.fluent-bit-sidecar.resources.limits.memory=600Mi
    fluent-bit-sidecar.ose.deployment.spec.template.spec.containers.fluent-bit-sidecar.resources.limits.ephemeral-storage=${global.ose.deployment.spec.template.spec.containers.resources.limits.ephemeral-storage|2Gi}
    fluent-bit-sidecar.ose.deployment.spec.template.spec.containers.fluent-bit-sidecar.resources.requests.cpu=200m
    fluent-bit-sidecar.ose.deployment.spec.template.spec.containers.fluent-bit-sidecar.resources.requests.memory=600Mi

    fluent-bit-sidecar.kafka.bootstrap.servers=${global.platform.logger.kafka.bootstrap.servers}
    fluent-bit-sidecar.kafka.topic=${global.platform.logger.kafka.topic}

Проверка результата​

Изменения в конфигурационные файлы внесены.

Шаг 4. Проверьте и подготовьте параметры k8s в namespace (обязательный)​

Последовательность действий​

Для этого создайте imagePullSecret:

kind: Secret
apiVersion: v1
metadata:
name: ${rplw.ose.deployment.spec.template.spec.imagePullSecrets.name}
data:
.dockerconfigjson: >-
"Строка подключения к docker registry в base64"
type: kubernetes.io/dockerconfigjson

Проверка результата​

Параметры k8s подготовлены.

Шаг 5. Удалите все устаревшие ресурсы Kubernetes (обязательный)​

Список ресурсов для удаления​

  • Gateways
  • Destination rules
  • Virtualservices
  • Serviceentries
  • Ingress
  • Services
  • ConfigMap
  • Deployments
  • Virtual Services

Проверка результата​

Устаревшие ресурсы k8s удалены.

Шаг 6. Настройте секреты в системе управления секретами HashiCorp Vault (обязательный)​

Последовательность действий​

Воспользуйтесь подразделом Администрирование через DropApp раздела Сценарии администрирования документа Руководство администратора.

Проверка результата​

Секреты настроены.

Шаг 7. Интеграция с компонентом граничного прокси (IGEG) (обязательный)​

Последовательность действий​

Интеграция с граничным прокси настраивается Администратором стенда в ${стенд}/multiClusters.json

Убедитесь, что в конфигурации ConfigMap rplw.istio.all.conf установлен параметр: rplw.ose.deployment.spec.template.annotations.istio.inject=true и эта аннотация применена в Deployment для module.

Проверка результата​

Интеграция с IGEG настроена.

Шаг 8. Интеграция с компонентом Журналирование (LOGA) (необязательный)​

Последовательность действий​

Пример файла rplw.fluentbit-sidecar.all.conf для интеграции с LOGA:

fluent-bit-sidecar.ose.deployment.spec.template.spec.containers.fluent-bit-sidecar.resources.limits.cpu=200m
fluent-bit-sidecar.ose.deployment.spec.template.spec.containers.fluent-bit-sidecar.resources.limits.memory=600Mi
fluent-bit-sidecar.ose.deployment.spec.template.spec.containers.fluent-bit-sidecar.resources.limits.ephemeral-storage=${global.ose.deployment.spec.template.spec.containers.resources.limits.ephemeral-storage|2Gi}
fluent-bit-sidecar.ose.deployment.spec.template.spec.containers.fluent-bit-sidecar.resources.requests.cpu=200m
fluent-bit-sidecar.ose.deployment.spec.template.spec.containers.fluent-bit-sidecar.resources.requests.memory=600Mi

fluent-bit-sidecar.kafka.bootstrap.servers=${global.platform.logger.kafka.bootstrap.servers}
fluent-bit-sidecar.kafka.topic=${global.platform.logger.kafka.topic}

Проверка результата​

Интеграция с LOGA настроена.

Шаг 9. Интеграция с компонентом Объединенный мониторинг Unimon (MONA) (необязательный)​

Последовательность действий​

Для интеграции с MONA требуется предварительная настройка стенда администраторами.

Параметры берутся из настроек стенда.

Проверка результата​

Интеграция с MONA настроена.

Шаг 10. Интеграция с Kafka (обязательный)​

Последовательность действий​

Для интеграции с Kafka требуется предварительная настройка стенда Администраторами.

Параметры берутся из настроек стенда.

Проверка результата​

Интеграция с Kafka настроена.

Шаг 11. Интеграция с компонентом OTTS (обязательный)​

Последовательность действий​

Настройка интеграции производится на подах Ingress Gateway и Egress Gateway каждого Namespace.

Пример grdl.all.conf:

# Container limits
grdl.ott.limits.cpu = 200m
grdl.ott.limits.memory = 600Mi
grdl.ott.limits.ephemeral-storage = 1Gi
grdl.ott.requests.cpu = 200m
grdl.ott.requests.memory = 600Mi
# App vars
grdl.ott.module.id = {{ lookup('vars','global.platform.grdl.ott.module.id') }}
grdl.ingress.ott.audit2.proxy.url = http://localhost:6992
grdl.egress.ott.audit2.proxy.url = http://localhost:6991

Пример ConfigMap для Ingress Gateway:

kind: ConfigMap
apiVersion: v1
metadata:
name: grdl-console-ott-ingress-cm
labels:
owner: ott-sidecar
data:
OTT_CERTSTORE_TYPE: PEM
OTT_MODULE_ID: ott-client-grdl
OTT_CLIENT_CRT: /vault/secrets/certs/ott/ott_cert.pem
OTT_CLIENT_PRIVATE_KEY: /vault/secrets/certs/ott/ott_key.pem
OTT_SERVICE_TLS_CRT: /vault/secrets/certs/ott/ott_root.pem
OTT_SERVICE_CRT: /vault/secrets/certs/ott/ott-service.pem # обеспечение обратной совместимости с OTT сервером версии до 4.3.1
OTT_SERVICE_CLIENT_TRUSTED_CRT_RATE: '60' # период обновления кеша сертификатов серверов OTT, в секундах (при подключении к OTT серверу 4.3.1+)
OTT_OPER_MODE: validate # <mode> = "sign" для egress GW, "validate" - для ingress GW; не задавать этот параметр при интеграции со сборкой envoy от synapse security
OTT_SERVICE_HOSTS: >-
ott-server-host1:port,ott-server-host2:port # список серверов:портов сервиса OTTS для балансировки нагрузки, или аналогичный список nginx OTTS
JAVA_TOOL_OPTIONS: -Dlogging.config=/mnt/ott-logback/logback.xml -Dlogback.configurationFile=/mnt/ott-logback/logback.xml -XX:MaxRAMPercentage=55.0 -Dspring.profiles.active=probes
OTT_AUTH_TLS_TRUST_MODE: 'true'
# изменить значения параметров ниже при необходимости, по умолчанию - не менять
OTT_CLIENT_MMT-COMPATIBILITY-MODE: 'false' # режим совместимости с ММТ 3 поколения, включать для взаимодействия с Платформой 3-го поколения, ожидаемая структура path HTTP-запроса: /<receiver_id>/<api.name>/<api.method> или /<api.name>/<api.method>
OTT_GRPC_PORT: /mnt/ott-uds-socket/ott.socket
OTT_SERVICE_URL: 'https://stub-host:stub-port/ott-service/rest/token' # шаблон URL сервиса OTTS, при балансировке значения будут подставляться из OTT_SERVICE_HOSTS
OTT_AUTHZ_VERSION: '1.0' # версия метода авторизации
OTT_AUTHZ_REALM: ott
OTT_HTTP_PORT: '8090' # порт OTTS Sidecar для readiness probe, при необходимости можно выбрать любой другой свободный порт
OTT_ANONYMOUS_REQUESTS_ENABLED: 'false' # анонимный режим, для включения необходимо выставить в 'true'
OTT_CLIENT_DEFAULT_REALM: mmt
OTT_CLIENT_MMT_RESOURCE_ATTRID: 'urn:censored:names:censored:1.0:api:interface:fullname'
OTT_CLIENT_MMT_ACTION_ATTRID: 'urn:censored:names:censored:1.0:action:id'
OTT_APPLICATION_ATTRIBUTE_ID: 'urn:censored:names:censored:1.0:module:id' # здесь строка остается неизменной, на свой идентификатор приложения менять не нужно
примечание

При использовании IAM необходимо указать параметр OTT_AUTH_TLS_TRUST_MODE: 'true'

Пример ConfigMap для Egress Gateway:

kind: ConfigMap
apiVersion: v1
metadata:
name: grdl-console-ott-egress-cm
labels:
owner: ott-sidecar
data:
OTT_CERTSTORE_TYPE: PEM
OTT_MODULE_ID: ott-client-grdl
OTT_CLIENT_CRT: /vault/secrets/certs/ott/ott_cert.pem
OTT_CLIENT_PRIVATE_KEY: /vault/secrets/certs/ott/ott_key.pem
OTT_SERVICE_TLS_CRT: /vault/secrets/certs/ott/ott_root.pem
OTT_SERVICE_CRT: /vault/secrets/certs/ott/ott-service.pem # обеспечение обратной совместимости с OTT сервером версии до 4.3.1
OTT_SERVICE_CLIENT_TRUSTED_CRT_RATE: '60' # период обновления кеша сертификатов серверов OTT, в секундах (при подключении к OTT серверу 4.3.1+)
OTT_OPER_MODE: sign # <mode> = "sign" для egress GW, "validate" - для ingress GW; не задавать этот параметр при интеграции со сборкой envoy от synapse security
OTT_SERVICE_HOSTS: >-
ott-server-host1:port,ott-server-host2:port # список серверов:портов сервиса OTTS для балансировки нагрузки, или аналогичный список nginx OTTS
JAVA_TOOL_OPTIONS: -Dlogging.config=/mnt/ott-logback/logback.xml -Dlogback.configurationFile=/mnt/ott-logback/logback.xml -XX:MaxRAMPercentage=55.0 -Dspring.profiles.active=probes
# изменить значения параметров ниже при необходимости, по умолчанию - не менять
OTT_CLIENT_MMT-COMPATIBILITY-MODE: 'false' # режим совместимости с ММТ 3 поколения, включать для взаимодействия с Платформой 3-го поколения, ожидаемая структура path HTTP-запроса: /<receiver_id>/<api.name>/<api.method> или /<api.name>/<api.method>
OTT_GRPC_PORT: /mnt/ott-uds-socket/ott.socket
OTT_SERVICE_URL: 'https://stub-host:stub-port/ott-service/rest/token' # шаблон URL сервиса OTTS, при балансировке значения будут подставляться из OTT_SERVICE_HOSTS
OTT_AUTHZ_VERSION: '1.0' # версия метода авторизации
OTT_AUTHZ_REALM: ott
OTT_HTTP_PORT: '8090' # порт OTTS Sidecar для readiness probe, при необходимости можно выбрать любой другой свободный порт
OTT_ANONYMOUS_REQUESTS_ENABLED: 'false' # анонимный режим, для включения необходимо выставить в 'true'
OTT_CLIENT_DEFAULT_REALM: mmt
OTT_CLIENT_MMT_RESOURCE_ATTRID: 'urn:censored:names:censored:1.0:api:interface:fullname'
OTT_CLIENT_MMT_ACTION_ATTRID: 'urn:censored:names:censored:1.0:action:id'
OTT_APPLICATION_ATTRIBUTE_ID: 'urn:censored:names:censored:1.0:module:id' # здесь строка остается неизменной, на свой идентификатор приложения менять не нужно

Подробное описание интеграции доступно в документации на продукт One-Time Password (OTP)/OTT (версия 5.15)

Проверка результата​

Интеграция с OTTS настроена.

Шаг 12. Интеграция с HashiCorp Vault (обязательный)​

Последовательность действий​

HashiCorp Vault — это система управления секретами и шифрованием на основе идентификационных данных. Взаимодействие с сервером SecMan производится с помощью Vault Agent sidecar, который поставляется в целевой pod с помощью инжектора.

Пример инжектора в Deployment:

# ...
template:
metadata:
labels:
secman-injector: enabled
# ...
примечание

Инжектор Vault Agent изменяет спецификации pod, чтобы включить контейнеры Vault Agent, которые отображают секреты Vault в разделяемом томе памяти с использованием шаблонов Vault Agent. Выводя секреты на общий том, контейнеры внутри модуля могут использовать секреты Vault, не зная о Vault. Инжектор — это Kubernetes Mutation Webhook Controller. Контроллер перехватывает события модуля и применяет изменения к модулю, если в запросе существуют аннотации. Эта функциональность предоставляется проектом vault-k8s и может быть автоматически установлена и настроена с помощью диаграммы Vault Helm.

Параметры инжектора и действий с секретами HashiCorp Vault передаются в блоке аннотаций.

Пример записи сертификата из Key Value хранилища HashiCorp Vault в файловую систему пода с использованием языка шаблонов GO Template:

template:
metadata:
labels:
# ...
annotations:
# ...
vault.hashicorp.com/agent-inject-secret-ott_root.pem: 'true'
vault.hashicorp.com/secret-volume-path-ott_root.pem: /vault/secrets/certs/ott
vault.hashicorp.com/agent-inject-file-ott_root.pem: ott_root.pem
vault.hashicorp.com/agent-inject-template-ott_root.pem: |
{{ '{{- with secret "' +
'DEV_censored/A/IFT3/GRDL/KV2/' +
'ott' +
'" -}}' }}
{{ '{{ .Data.data.cacert }}' }}
{{ '{{ end -}}' }}
# ...

GraDeLy поддерживает два типа секретов:

  • KV-секреты — секреты, сгенерированные с движком KV Secrets Engine.
  • PG — секреты, расположенные в PG-хранилище.

Конфигурационные параметры генерации секретов:

rplw-module.k8s.secman.engine.ott=KV
rplw-module.k8s.secman.engine.ingress=PKI
rplw-module.k8s.secman.engine.audit=KV
rplw-module.k8s.secman.engine.toconsole=PKI
rplw-module.k8s.secman.engine.logger=KV
rplw-module.k8s.secman.engine.psql=PKI
rplw-module.k8s.secman.engine.kafka=KV

Поддержка alias для KV2​

В конфигурации воркера установите параметры:

rplw-module.secrets.engine=kv2
rplw-module.psql.json.list=[{"as_name":"test","creds":[{"prefix":"A/IFT/AS/KV2/","secret_path":"jdbc-1"},{"prefix":" A/IFT/AS/KV2/","secret_path":"jdbc-2"},{"prefix":" A/IFT/AS/KV2/","secret_path":"jdbc-3"}]}]
примечание

В опциях соединения к БД в UI укажите параметр "secret_path": "<Путь до секрета в HashiCorp Vault>"

Для формирования путей до секретов в HashiCorp Vault по старой логике с использованием FQDN баз данных оставьте пустым параметр конфигураций rplw-module.psql.json.list=.

Поддержка alias для PG​

В конфигурации воркера установите параметры:

gdl.secrets.engine=pg
rplw-module.psql.json.list=[{"as_name":"test","creds":[{"prefix":"DEV/database/pg/static-creds/","secret_path":"secret-rec"},{"prefix":"DEV/database/pg/static-creds/","secret_path":"secret_src"}]}]
примечание

В опциях соединения к БД в UI укажите параметр "secret_path": "<Путь до секрета в HashiCorp Vault>" Если указанный параметр не заполнен, а gdl.secrets.engine=pg, то возникнет ошибка.

Проверка результата​

Интеграция с HashiCorp Vault настроена.

Шаг 13. Предустановленные конфигурации (обязательный)​

Последовательность действий​

rplw.all.conf:

rplw.worker.count = 2 # количество подов воркера при деплое

rplw.ose.deployment.spec.template.spec.containers.ott-sidecar.startupProbe.failureThreshold=30
rplw.ose.deployment.spec.template.spec.containers.ott-sidecar.livenessProbe.failureThreshold=30
rplw.ose.deployment.spec.template.spec.containers.ott-sidecar.readinessProbe.failureThreshold=15

rplw.fluentbit-sidecar.all.conf:

# Параметры fluent-controller
# Перечитать конфигурацию fluent-bit
rplw.fluentbit-sidecar.conf.reload.enabled=true
# Использовать механизм Secman Hotreload
rplw.fluentbit-sidecar.vault.reload.enabled=true

rplw.istio.all.conf:

# Управление приоритетом компонентов
istio.ose.deployment.spec.template.spec.priorityClassName=

# количество реплик ingress/egress
istio.ose.istio.ingress.deployment.spec.replicas=2

# Istio control plane
rplw.ose.istio.control-plane-project={{ lookup('custom_vars', 'global.multiClusters.openshiftControlPlaneProject') }}
rplw.ose.istio.control-plane-istiod-service={{ lookup('custom_vars', 'global.multiClusters.openshiftControlPlaneIstiodService') }}
rplw.ose.istio.control-plane-istiod-port={{ lookup('custom_vars', 'global.multiClusters.openshiftControlPlaneIstiodPort') }}

# Jaeger collector
rplw.ose.istio.control-plane-jaeger-service={{ lookup('custom_vars', 'global.multiClusters.openshiftControlPlaneJaegerService') }}
rplw.ose.istio.control-plane-jaeger-port={{ lookup('custom_vars', 'global.multiClusters.openshiftControlPlaneJaegerPort') }}

rplw.ose.deployment.spec.template.spec.containers.istio-proxy.readinessProbe.failureThreshold=30

# Kafka ports
rplw.ose.istio.egress.se.tcp.kafka.number={{ lookup('custom_vars', 'global.platform.ose.kafka.ports') }}

rplw.ose.deployment.spec.template.spec.containers.egress.resources.limits.cpu=1000m
rplw.ose.deployment.spec.template.spec.containers.egress.resources.limits.memory=200Mi
rplw.ose.deployment.spec.template.spec.containers.egress.resources.requests.cpu=1000m
rplw.ose.deployment.spec.template.spec.containers.egress.resources.requests.memory=200Mi

rplw.ose.deployment.spec.template.spec.containers.ingress.resources.limits.cpu=200m
rplw.ose.deployment.spec.template.spec.containers.ingress.resources.limits.memory=200Mi
rplw.ose.deployment.spec.template.spec.containers.ingress.resources.requests.cpu=200m
rplw.ose.deployment.spec.template.spec.containers.ingress.resources.requests.memory=200Mi

rplw.ose.istio.vault-token.aud=vault

rplw-module.conf:

# Управление приоритетом компонентов
rplw-module.ose.deployment.spec.template.spec.priorityClassName=

# Параметр добавляющий аргументы запуска приложения через jvm переменную JAVA_OPTS. Будут помещены в конфигмап someFpName1.conf;
rplw-module.ose.configmap.javaArguments=-XX:+UseContainerSupport -XX:InitialRAMPercentage=40.0 -XX:MaxRAMPercentage=80.0 -XX:+UseSerialGC

# количество реплик
rplw-module.ose.deployment.spec.replicas=2

rplw-module.ose.deployment.spec.template.spec.containers.rplw-module.resources.limits.cpu=2000m
rplw-module.ose.deployment.spec.template.spec.containers.rplw-module.resources.limits.memory=4000Mi
rplw-module.ose.deployment.spec.template.spec.containers.rplw-module.resources.limits.ephemeral-storage={{ lookup('custom_vars', 'global.ose.deployment.spec.template.spec.containers.resources.limits.ephemeral-storage', default='500Mi') }}
rplw-module.ose.deployment.spec.template.spec.containers.rplw-module.resources.requests.cpu=2000m
rplw-module.ose.deployment.spec.template.spec.containers.rplw-module.resources.requests.memory=4000Mi

rplw-module.ose.kafka.port=9093

rplw-module.kafka.message-format=PARSED

rplw-module.auto-create-topics-enable=true
# Для воркеров в контейнерной среде параметр по умолчанию включен.
# При включении воркер создает основной и служебные Kafka-топики процесса; при выключении топики должны быть подготовлены заранее.

rplw-module.label=

rplw-module.hot-reload-enable=true
rplw-module.hot-reload-poll-interval=5000
rplw-module.hot-reload-retry-count=10
rplw-module.hot-reload-fail-safe-enable=true
rplw-module.hot-reload-dir-postgres=/vault/secrets/databases

rplw-module.vault.pki.mount-path=PKI
rplw-module.vault.pki.refresh-period=10m
rplw-module.vault.pki.fetch-cn='*.solution.sbt'
rplw-module.vault.pki.fetch-role=role-ga-secman-grdl-ift
rplw-module.vault.pki.fetch-ttl=2592000
rplw-module.vault.pki.alt-names=*.ift-grdl.apps.dap.devpub-01.solution.sbt,*.vdc11.db.dev.sbt,*.ift2-grdl.apps.dap.devpub-02.solution.sbt,*.ift3-grdl.apps.dap.devpub-01.solution.sbt,*.nt01-grdl.apps.dap.ntpub-01.solution.sbt,solution.sbt,db.dev.sbt,*.ift4-grdl.apps.dap.devpub-02.solution.sbt,*.grdl.apps.dap.devpub-02.solution.sbt,*.ift-grdl.apps.dap.devpub-01.solution.sbt,*.nt02-grdl.apps.dap.ntpub-01.solution.sbt,*.ift4-grdl.apps.dap.devpub-02.solution.sbt,*.solution.sbt,*.dap.ntpub-01db.solution.sbt
rplw-module.vault.pki.ip-sans=

rplw-module.capture-cache-size=12000
rplw-module.apply-cache-size=15
rplw-module.kafka-consumer-queue-size=12000

rplw-module.ose.deployment.spec.template.spec.containers.resources.limits.cpu=1000m
rplw-module.ose.deployment.spec.template.spec.containers.resources.limits.memory=200Mi
rplw-module.ose.deployment.spec.template.spec.containers.resources.requests.cpu=1000m
rplw-module.ose.deployment.spec.template.spec.containers.resources.requests.memory=200Mi

rplw-module.ose.deployment.spec.template.spec.containers.egress.resources.limits.cpu=400m
rplw-module.ose.deployment.spec.template.spec.containers.egress.resources.limits.memory=200Mi
rplw-module.ose.deployment.spec.template.spec.containers.egress.resources.requests.cpu=400m
rplw-module.ose.deployment.spec.template.spec.containers.egress.resources.requests.memory=200Mi

rplw-module.ose.deployment.spec.template.spec.containers.ingress.resources.limits.cpu=200m
rplw-module.ose.deployment.spec.template.spec.containers.ingress.resources.limits.memory=200Mi
rplw-module.ose.deployment.spec.template.spec.containers.ingress.resources.requests.cpu=200m
rplw-module.ose.deployment.spec.template.spec.containers.ingress.resources.requests.memory=200Mi

rplw-module.ose.deployment.spec.template.spec.containers.rplw-module.livenessProbe.failureThreshold=3
rplw-module.ose.deployment.spec.template.spec.containers.rplw-module.readinessProbe.failureThreshold=3

rplw-module.feature.SelfAntiAffinity.enabled=false

# Rate limiter
rplw-module.rate-limiter-buckets=[{"uri":"/general","maxTokens":1000,"refillIntervalSec":1}]

# Список БД находящихся на том же ЦОД что и воркер
rplw-module.db.urls=["fqdn1","fqdn2"]

# Список путей к хранилищам кастомных секретов для БД
# Пример:
# Заполнено до движка KV2
# rplw-module.psql.json.list=[{"as_name":"test","creds":[{"prefix":"A/IFT/RPLW/KV2/","secret_path":"ift1"}],[{"prefix":"A/IFT/RPLW/KV2/","secret_path":"ift2"}]}]
# diff-init-module.secrets.engine=KV2
#
# Заполнено до движка PG
# rplw-module.psql.json.list=[{"as_name":"test","creds":[{"prefix":"A/IFT/RPLW/PG/","secret_path":"ift1"}],[{"prefix":"A/IFT/RPLW/PG/","secret_path":"ift2"}]}]
# diff-init-module.secrets.engine=PG
#
# Заполнено для работы по старому по FQDN
# rplw-module.psql.json.list= ОСТАВИТЬ ПУСТЫМ
# rplw-module.secrets.engine= Заполнить PG или KV2

rplw-module.psql.json.list=

Проверка результата​

Конфигурации предустановлены.

Шаг 14. Произведите полную установку GraDeLy (обязательный)​

Последовательность действий​

Для GraDeLy предусмотрена автоматизированная установка через компонент Deploy tools продукта Platform V DevOps Tools (DOT).

При выполненных предыдущих пунктах файлы сценария миграции, обновления БД повторно можно не выполнять.

Полный список файлов сценария для установки:

  • MIGRATION_FP_CONF;
  • FP_CONF_CHECK;
  • OPENSHIFT_DEPLOY;
  • OPENSHIFT_INGRESS_EGRESS_DEPLOY.

Проверка результата​

Установка проведена.

Шаг 15. Определите максимальную производительность (не обязательный)​

Последовательность действий​

Для определения максимальной нагрузки, которую следует задать с помощью механизма Rate Limiter, проведите тест определения максимальной производительности.

Внимание!

Нагрузка должна быть ограничена с помощью механизма Rate Limiter на уровне, не превышающем показатели теста максимальной производительности.

Сценарий тестирования​

При тестировании происходит пошаговое увеличение нагрузки с нуля до предельной (с шагом 20% от плановой). Пошаговое увеличение происходит до тех пор, пока не нарушится критерий успешности по количеству ошибок и/или времени отклика (что наступит раньше). Время работы теста на каждом шаге после стабилизации нагрузки составляет 10 минут.

Цель тестирования​

По результатам тестирования устанавливается:

  • уровень нагрузки L0 — последний шаг нагрузки, на котором не были нарушены критерии успешности;
  • уровень нагрузки Llim — предельный уровень нагрузки, при котором не был нарушен критерий по количеству ошибок;
  • уровень утилизации CPUlim — утилизация CPU на уровне нагрузки Llim.

Ожидаемый результат​

  • Определен уровень максимальной производительности. L0 удовлетворяет одному из следующих уровней нагрузки (при использовании ресурсов всеми подами не больше, чем на OSE):

    • Lmax для предыдущего релиза;
    • Запросите аналитическую оценку команды по плановой нагрузке на сервис на год вперед, если не достигнут Lmax (при суммарных ресурсах как на OSE);
    • Используйте критерий 10х от промышленной нагрузки на сервис, если не достигнута плановая нагрузка на год вперед.
  • Определен уровень нагрузки Llim.

  • Определен уровень утилизации CPUlim.

Профиль нагрузки​

Моделирование нагрузки производится с использованием средств нагрузочного тестирования путем эмуляции действий определенного количества пользователей. Каждый виртуальный пользователь (программный процесс, эмулирующий действия физического пользователя АС) циклически выполняет пользовательский сценарий.

Подача нагрузки​
  • JMeter подает нагрузку на БД Source Pangolin, выполняя PL/pgSQL-функцию NewOrder, которая включает в себя три операции INSERT и одну операцию UPDATE;
  • Первый модуль захвата и изменений GraDeLy вычитывает сгенерированные данные из БД Source Pangolin и записывает их в Kafka;
  • Модуль применения изменений вычитывает данные из Kafka и применяет их на БД Replica Pangolin.
Функция NewOrder — это бизнес-транзакция для выполнения нового заказа с помощью одной транзакции базы данных.
Представляет собой транзакцию чтения-записи среднего веса с высокой частотой выполнения. Эта транзакция является основой рабочей нагрузки.
Позволяет моделировать переменную нагрузку, характерную для оперативной активности базы данных в производственных средах.
Структура транзакции NewOrder​
CREATE OR REPLACE FUNCTION benchbase.new_order(w_id smallint, d_id bigint, c_id integer, o_entry_d timestamp without time zone, i_ids integer[], i_w_ids integer[], i_qtys integer[])
RETURNS benchbase.t_order_res
LANGUAGE plpgsql
AS $function$
DECLARE
getWarehouseTaxRate text := 'SELECT W_TAX FROM benchbase.WAREHOUSE WHERE W_ID = $1';
getDistrict text := 'SELECT D_TAX, nextval(''benchbase.D_NEXT_O_ID'') FROM benchbase.DISTRICT WHERE D_ID = $1 AND D_W_ID = $2';
getCustomer text := 'SELECT C_DISCOUNT, C_LAST, C_CREDIT FROM benchbase.CUSTOMER WHERE C_W_ID = $1 AND C_D_ID = $2 AND C_ID = $3';
createOrder text := 'INSERT INTO benchbase.OORDER (O_ID, O_D_ID, O_W_ID, O_C_ID, O_ENTRY_D, O_CARRIER_ID, O_OL_CNT, O_ALL_LOCAL) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)';
createNewOrder text := 'INSERT INTO benchbase.NEW_ORDER (NO_O_ID, NO_D_ID, NO_W_ID) VALUES ($1, $2, $3)';
getItemInfo text := 'SELECT I_PRICE, I_NAME, I_DATA FROM benchbase.ITEM WHERE I_ID = $1';
getStockInfo text := 'SELECT S_QUANTITY, S_DATA, S_YTD, S_ORDER_CNT, S_REMOTE_CNT, S_DIST_%s FROM benchbase.STOCK WHERE S_I_ID = $1 AND S_W_ID = $2';
updateStock text := 'UPDATE benchbase.STOCK SET S_QUANTITY = $1, S_YTD = $2, S_ORDER_CNT = $3, S_REMOTE_CNT = $4 WHERE S_I_ID = $5 AND S_W_ID = $6';
createOrderLine text := 'INSERT INTO benchbase.ORDER_LINE (OL_O_ID, OL_D_ID, OL_W_ID, OL_NUMBER, OL_I_ID, OL_SUPPLY_W_ID, OL_DELIVERY_D, OL_QUANTITY, OL_AMOUNT, OL_DIST_INFO) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)';

all_local boolean := TRUE;
ol_cnt integer;
items benchbase.t_order_item[];
item benchbase.t_order_item;
customer_info benchbase.t_order_customer;
c_discount float;
o_carrier_id integer;
stock_info benchbase.t_order_stock;
w_tax float;
d_tax float;
d_next_o_id integer;
brand_generic char;
ol_amount float;
total float := 0;
item_data_s benchbase.t_order_item_data;
item_data benchbase.t_order_item_data[];
misc benchbase.t_order_misc;

BEGIN
ol_cnt = array_length(i_ids, 1);
ASSERT ol_cnt != 0;
ASSERT ol_cnt = array_length(i_w_ids, 1);
ASSERT ol_cnt = array_length(i_qtys, 1);

FOR i IN 1..ol_cnt LOOP
all_local = all_local AND i_w_ids[i] = w_id;
EXECUTE getItemInfo INTO item USING i_ids[i];
ASSERT item IS NOT NULL;
items = array_append(items, item);
END LOOP;
ASSERT ol_cnt = array_length(items, 1);
EXECUTE getWarehouseTaxRate INTO w_tax USING w_id;
EXECUTE getDistrict INTO d_tax, d_next_o_id USING d_id, w_id;
EXECUTE getCustomer INTO customer_info USING w_id, d_id, c_id;
c_discount = customer_info.C_DISCOUNT;
o_carrier_id = 0;
EXECUTE createOrder USING d_next_o_id, d_id, w_id, c_id, o_entry_d, o_carrier_id, ol_cnt, cast(all_local as integer);
EXECUTE createNewOrder USING d_next_o_id, d_id, w_id;

FOR i IN 1..ol_cnt LOOP
EXECUTE FORMAT(getStockInfo, to_char(d_id, 'FM09')) INTO stock_info USING i_ids[i], i_w_ids[i];
stock_info.S_YTD = stock_info.S_YTD + i_qtys[i];
IF stock_info.S_QUANTITY >= i_qtys[i] + 10 THEN
stock_info.S_QUANTITY = stock_info.S_QUANTITY - i_qtys[i];
ELSE
stock_info.S_QUANTITY = stock_info.S_QUANTITY + 91 - i_qtys[i];
END IF;
stock_info.S_ORDER_CNT = stock_info.S_ORDER_CNT + 1;

IF i_w_ids[i] != w_id THEN
stock_info.S_REMOTE_CNT = stock_info.S_REMOTE_CNT + 1;
END IF;

EXECUTE updateStock USING stock_info.S_QUANTITY, stock_info.S_YTD, stock_info.S_ORDER_CNT, stock_info.S_REMOTE_CNT, i_ids[i], i_w_ids[i];

IF position('ORIGINAL' IN items[i].I_DATA) != 0 AND position('ORIGINAL' IN stock_info.S_DATA) != 0 THEN
brand_generic = 'B';
ELSE
brand_generic = 'G';
END IF;

ol_amount = i_qtys[i] * items[i].I_PRICE;
total = total + ol_amount;
EXECUTE createOrderLine USING d_next_o_id, d_id, w_id, i, i_ids[i], i_w_ids[i], o_entry_d, i_qtys[i], ol_amount, stock_info.S_DIST;
item_data_s = ROW(items[i].I_NAME, stock_info.S_QUANTITY, brand_generic, items[i].I_PRICE, ol_amount);
item_data = array_append(item_data, item_data_s);
END LOOP;
total = total * (1 - c_discount) * (1 + w_tax + d_tax);
misc = ROW(w_tax, d_tax, d_next_o_id, total);
RETURN ROW(customer_info, misc, item_data);
END;
$function$
;
Вызов функции NewOrder​
select benchbase.new_order((CEIL(RANDOM() * 10))::smallint, (CEIL(RANDOM() * 10))::int8, CEIL(RANDOM() * 3000)::integer, current_timestamp::timestamp, ARRAY[CEIL(RANDOM() * 100000)::int], ARRAY[CEIL(RANDOM() * 10)::int], ARRAY[1]);

Схема данных​

Схема данных

Тестовые данные​

Тестовые данные сгенерированы с помощью BenchBase с использованием бенчмарка TPC-C.

Пример конфигурации для генерации тестовых данных​
<?xml version="1.0"?>
<parameters>


<type>POSTGRES</type>
<driver>org.postgresql.Driver</driver>
<url> </url>
<username> </username>
<password> </password>
<reconnectOnConnectionFailure>true</reconnectOnConnectionFailure>


<isolation>TRANSACTION_READ_COMMITTED</isolation>
<batchsize>100</batchsize>


<scalefactor>10</scalefactor>


<terminals>1000</terminals>
<works>
<work>
<time>1200</time>
<rate>3000</rate>
<weights>45,43,4,4,4</weights>
</work>
</works>


<transactiontypes>
<transactiontype>
<name>NewOrder</name>
</transactiontype>
<transactiontype>
<name>Payment</name>
</transactiontype>
<transactiontype>
<name>OrderStatus</name>
</transactiontype>
<transactiontype>
<name>Delivery</name>
</transactiontype>
<transactiontype>
<name>StockLevel</name>
</transactiontype>
</transactiontypes>
</parameters>

Тестирование базовой конфигурации​

grdl.properties​
gdl.apply-cache-size=20
gdl.capture-cache-size=12000
gdl.kafka-consumer-queue-size=12000
Параметры модуля применения изменений Applier​

Параметры модуля применения изменений Applier

Параметры соединения БД Replica​
{
"max.pool.size": 20,
"apply.thread.count": 18,
"transaction.size": 2000,
"db.linger.ms": 3000
}
Параметры соединения Kafka​
{
"max.poll.records": "1",
"batch.size": 16384,
"max.request.size": 209715200,
"compression.type": "zstd",
"compression.zstd.level": 3
}
Метрики теста​
  • Модуль захвата изменений capture: vm-gdev-db-nosw-515.vdc11.db.dev.sbt
  • Модуль применения изменений applier: vm-gdev-db-nosw-516.vdc11.db.dev.sbt
Network recieve/transmit​

network_recieve_transmit_basic

OPS(insert/update/delete)​
  • vm-grdl-db-psql-430.vdc11.db.dev.sbt — БД Source
  • vm-grdl-db-psql-433.vdc11.db.dev.sbt — БД Replica

ops_basic

Итог​
  • Максимальная производительность репликации OPS: 28900
  • Максимальная производительность репликации MB/s: 8.2

Тестирование минимальной конфигурации​

grdl.properties​
gdl.apply-cache-size=20
gdl.capture-cache-size=12000
gdl.kafka-consumer-queue-size=500
Параметры модуля применения изменений Applier​

Параметры модуля применения изменений Applier

Параметры соединения БД Replica​
{
"max.pool.size": 5,
"apply.thread.count": 2,
"transaction.size": 500,
"db.linger.ms": 1000
}
Параметры соединения Kafka​
{
"max.poll.records": "1",
"batch.size": 16384,
"max.request.size": 209715200,
"compression.type": "zstd",
"compression.zstd.level": 3
}
Метрики теста​
  • Модуль захвата изменений capture: vm-gdev-db-nosw-513.vdc11.db.dev.sbt
  • Модуль применения изменений applier: vm-gdev-db-nosw-514.vdc11.db.dev.sbt
Network recieve/transmit​

network_recieve_transmit_min

OPS(insert/update/delete)​
  • vm-grdl-db-psql-430.vdc11.db.dev.sbt — БД Source
  • vm-grdl-db-psql-433.vdc11.db.dev.sbt — БД Replica

ops_min

Итог​
  • Максимальная производительность репликации OPS: 3900
  • Максимальная производительность репликации MB/s: 1.15

Проверка результата​

Максимальная производительность определена.