F.74. proxima — комбинация прокси, балансировщика нагрузки, пула соединений и кеша данных в оперативной памяти #

proxima — это расширение Postgres Pro Enterprise, объединяющее функциональность прокси-сервера, балансировщика нагрузки, пула соединений и кеша данных в оперативной памяти.

F.74.1. Обзор #

Расширение proxima можно использовать на одноузловом сервере Postgres Pro Enterprise, в стандартном кластере Postgres Pro Enterprise конструкции ведущий-ведомый, а также в BiHA-кластере. Расширение предоставляет следующие возможности:

  • Прокси-сервер: proxima становится единой точкой клиентских подключений и перенаправляет запросы на ведущий сервер или лидеру BiHA-кластера.

  • Пул соединений: proxima управляет обслуживающими процессами, чтобы сократить потребление системных ресурсов и предотвратить снижение производительности.

  • Балансировщик нагрузки: встроенная функциональность для балансировки нагрузки на чтение между репликами кластера по заданному алгоритму балансировки.

  • Кеш данных в оперативной памяти: proxima содержит экспериментальный встроенный модуль KVik, который предоставляет высокопроизводительное хранилище данных с поддержкой протокола RESP (Redis Serialization Protocol) и основных команд, таких как SET, GET и DEL, а также аннулирования кеша.

  • Поддержка SSL: расширение proxima можно настроить для работы с SSL-соединениями.

  • Мониторинг: при использовании расширения proxima с решением BiHA доступно множество метрик для отслеживания состояния proxima.

  • Динамический выделенный сеанс: proxima поддерживает сеанс между клиентом и обслуживающим процессом на протяжении всего времени существования клиентского подключения.

F.74.2. Особенности и ограничения #

В этом разделе перечислены особенности и ограничения, которые необходимо учитывать при использовании proxima.

F.74.2.1. Общие особенности и ограничения #

  • Расширение proxima не управляет репликацией между узлами кластера. Для обеспечения согласованности данных на всех узлах используйте Встроенная отказоустойчивость (BiHA) или настройте репликацию вручную.

  • Архитектуры процессоров Эльбрус, ppc64le и s390x не поддерживаются.

  • При использовании в стандартном кластере конструкции ведущий-ведомый или в BiHA-кластере сразу после запуска расширение proxima может записывать в журнал сообщения об ошибках подключения или синхронизации. Это нормальное поведение, потому что узлы запускаются в разное время. Сообщения об ошибках прекратятся вскоре после запуска.

  • На текущий момент в proxima отсутствует механизм автоматической установки динамических выделенных сеансов при использовании расширений, которые хранят своё состояние в рамках сеанса. В таких случаях необходимо вручную включить принудительный динамический выделенный сеанс.

  • Динамический выделенный сеанс не устанавливается при выполнении команды CREATE STATISTICS во временном пространстве имён.

  • Чтобы пул соединений обрабатывал большое число клиентских подключений, установите предел количества открытых файлов, превышающий число планируемых подключений:

    sudo echo '* soft nofile {значение}' >> /etc/security/limits.conf
    sudo echo '* hard nofile {значение}' >> /etc/security/limits.conf
    ulimit -n {значение}

    Например, если планируемое число клиентских подключений — 10000, в {значении} укажите 11000.

F.74.2.2. Особенности и ограничения функциональности KVik #

При использовании функциональности кеширования данных в памяти (KVik) учитывайте следующие ограничения:

  • В настоящее время функциональность KVik является экспериментальной и не рекомендована для использования в производственной среде.

  • Кеш данных не реплицируется на узлы кластера.

  • Аннулирование кеша не поддерживается для следующих операторов: ALTER TABLE, ALTER TABLE SET TABLESPACE, TRUNCATE и VACUUM FULL. Выполнение запроса, который содержит какой-либо из этих операторов, к кешированной таблице отключает аннулирование. Аннулирование можно повторно включить, перезапустив Postgres Pro Enterprise.

  • KVik не работает с представлениями. Поддерживаются только обычные таблицы.

  • Обращение к системным каталогам с помощью команд KVik не поддерживается.

  • TTL для ключей пока не поддерживается.

  • Авторизация не поддерживается.

  • Ключи хранятся в виде строк.

F.74.2.3. Особенности и ограничения при работе в BiHA-кластере #

  • В расширении proxima есть специальный режим работы для BiHA-кластера. При установке в BiHA-кластере proxima автоматически получает от biha все необходимые конфигурационные параметры, например:

    • количество узлов кластера

    • идентификаторы, адреса и порты узлов

    • роли узлов (лидер, последователь или главный последователь)

  • Вы можете установить расширение proxima в существующий BiHA-кластер или включить расширение при подготовке кластера с нуля.

  • Расширение proxima регистрирует ряд функций-обработчиков для получения уведомлений о событиях в кластере. Например, при смене лидера proxima получает уведомление об этом событии и автоматически перенаправляет трафик на нового лидера. Функции-обработчики размещаются в таблице biha.callbacks базы данных biha_db на узлах BiHA-кластера. Не удаляйте функции-обработчики, так как в этом случае proxima не сможет реагировать на события в кластере.

  • Когда расширение proxima включено в BiHA-кластере, узлы кластера подключаются друг к другу с помощью порта P2L + 1. Чтобы обеспечить нормальную работу, номер порта P2L должен быть одинаковым на всех узлах, а порт P2L + 1 должен быть свободен. За подробной информацией о портах P2L и P2F обратитесь к Подразделу F.74.6.

  • Если состояние узла изменяется на FRONT FOLLOWER или LEADER, proxima на этом узле перестаёт видеть другие узлы до тех пор, пока они не выйдут из состояния UNKNOWN. Это значит, что этот экземпляр proxima завершает подключения к другим экземплярам proxima, что, в свою очередь, отключает все активные клиенты от этого узла.

  • Расширение proxima балансирует нагрузку по всем узлам кластера в соответствии с заданным алгоритмом балансировки. Если используется несколько сегментов, запросы на порт P2F в сегменте-лидере могут также перенаправляться на узлы в сегменте-последователе, работающие только на чтение. Чтобы расширение proxima не перенаправляло запросы на узлы сегмента-последователя, можно задать алгоритм балансировки weighted_round_robin в параметре proxima.load_balancer_algorithm и указать веса узлов с помощью параметра proxima.load_balancer_node_weight. Для узлов, на которые расширение proxima не должно перенаправлять нагрузку, необходимо задать наименьший вес, а для узлов, на которые нужно перенаправлять нагрузку, — наибольший. Это решение полностью не исключает возможность перенаправления запросов на нежелательные узлы, но помогает свести её к минимуму.

F.74.3. Установка и настройка #

Расширение proxima — это встроенное расширение Postgres Pro Enterprise. Чтобы включить и настроить proxima, выполните следующие действия:

  1. Остановите сервер Postgres Pro Enterprise с помощью pg_ctl:

    pg_ctl stop -D каталог_PGDATA
  2. Добавьте proxima в shared_preload_libraries в файле postgresql.conf:

    shared_preload_libraries = 'proxima'

    При использовании многоузлового кластера повторите этот шаг для каждого узла.

  3. В зависимости от конфигурации Postgres Pro Enterprise задайте параметры конфигурации proxima в postgresql.conf:

    • Для одноузлового сервера задайте следующий параметр конфигурации:

      proxima.cluster_mode = 'standalone'
    • Для стандартного кластера конструкции ведущий-ведомый задайте следующие параметры конфигурации:

      proxima.cluster_mode = 'guc'
      proxima.cluster_config = 'id_узла0,адрес_узла0,порт_узла0,роль_узла0;id_узла1,адрес_узла1,порт_узла1,роль_узла1;'
      proxima.cluster_node_id = id_узла

      Например:

      proxima.cluster_mode = 'guc'
      proxima.cluster_config = '0,192.168.0.57,4590,P;1,192.168.0.77,4590,S;'
      proxima.cluster_node_id = 0

      Убедитесь, что на всех узлах указаны одинаковые значения proxima.cluster_config, а значения proxima.cluster_node_id уникальны для каждого узла.

    • Для BiHA-кластера задайте следующий параметр конфигурации:

      proxima.cluster_mode = 'biha'

      При использовании proxima с biha не требуется указывать параметры конфигурации кластера, так как proxima получает эту информацию напрямую от biha.

  4. (Необязательно) При необходимости задайте прочие параметры конфигурации.

    Если никакие параметры не заданы, proxima использует значения по умолчанию. За подробной информацией о конфигурационных параметрах и их значениях по умолчанию обратитесь к Подразделу F.74.12.1.

  5. Запустите узел с помощью pg_ctl:

    pg_ctl start -D каталог_PGDATA

F.74.4. Подключение к proxima #

В этом разделе приведены примеры строк подключения к proxima для различных языковых интерфейсов.

В примерах ниже используется порт P2L (по умолчанию 4545), где все подключения перенаправляются на ведущий узел кластера (лидер). Однако, чтобы использовать расширение proxima в качестве балансировщика нагрузки и распределять нагрузку на чтение между репликами кластера, необходимо также настроить подключение через порт P2F (по умолчанию 4547). За подробной информацией обратитесь к Подразделу F.74.6.1.

В строках подключения, созданных специально для подключений на чтение и запись или только на чтение, т.е. с использованием либо порта P2L, либо порта P2F, не обязательно указывать параметры target_session_attrs (psql/libpq, Python, Go) или targetServerType (JDBC), так как подключения распределяются силами proxima.

F.74.4.1. psql/libpq #

Подключение к proxima с помощью библиотеки psql/libpq выглядит следующим образом:

psql -d  "dbname=postgres host=node3,node4,node2,node1 port=4545,4545,4545,4545 user=username password=password"
psql postgres://username:password@node1:4545,node2:4545,node3:4545,node4:4545/postgres

F.74.4.2. Python #

Подключение к proxima с помощью библиотеки psycopg2 выглядит следующим образом:

import psycopg2
from psycopg2 import pool

pool = psycopg2.pool.SimpleConnectionPool(
                       min_size=1,
                       max_size=5,
                       user="pguser",
                       password="*****",
                       host="node1,node2,node3,node4",
                       port="4545,4545,4545,4545",
                       database="postgres")

connection = pool.getconn()

F.74.4.3. JDBC #

Подключение к proxima с помощью JDBC выглядит следующим образом:

String url = "jdbc:postgresql://node1:4545,node2:4545,node3:4545,node4:4545/postgres?loadBalanceHosts=true";
Properties props = new Properties();


props.setProperty("user","postgres");
props.setProperty("password","********");

Connection conn = DriverManager.getConnection(url, props);

Здесь в переменной url содержится строка подключения, где перечислены все доступные узлы. Если не указывать дополнительные параметры подключения драйвера JDBC, то подключение к кластеру будет происходить через первый доступный для подключения узел. Данный вариант не всегда может быть удобным. Поэтому в строке подключения добавлены параметры, позволяющие использовать разные узлы для разных подключений.

Параметр loadBalanceHosts со значением true позволяет перебирать узлы, подключаясь к какому-то одному из них.

F.74.4.4. Go #

Способы подключения к proxima для Go схожи со способами, принятыми в JDBC или Python. Необходимо использовать перечисление узлов, их TCP-портов, параметры подключения, а также выбрать подходящий драйвер.

Одним из таких драйверов для Go является pgx версий 4 или 5.

Ниже представлен пример строки подключения и создания пула для подключения к кластеру:

dbURL := "postgres://username:password@node1:4545,node2:4545,node3:4545,node4:4545/postgres"
dbPool, err := pgxpool.New(context.Background(), dbURL)

F.74.5. Аутентификация #

Расширение proxima использует правила аутентификации, указанные в файле pg_hba.conf. Поддерживаются следующие методы аутентификации:

F.74.5.1. Проксирование аутентификации на главный узел (лидер) #

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

Указать, где должна выполняться аутентификация пользователей, можно с помощью параметра конфигурации proxima.auth_policy, который поддерживает режимы local и leader.

Режим leader автоматически устанавливается на рефери BiHA-кластера и означает, что аутентификация выполняется на лидере. Это необходимо, так как на узле-рефери недостаточно информации для локальной аутентификации пользователей.

Примечание

Рефери можно развернуть в режимах работы referee или referee_with_wal. Если используется режим referee, рекомендуется сначала запустить лидера с включённым расширением proxima, а затем добавить рефери. Это необходимо потому, что proxima создаёт функции-обработчики на лидере кластера, которые затем реплицируются на другие узлы, кроме рефери в режиме referee. Однако если добавить рефери после включения proxima, все необходимые функции-обработчики будут скопированы утилитой bihactl.

На других узлах кластера для параметра proxima.auth_policy по умолчанию задано значение local. Это означает, что аутентификация производится локально на узлах. Однако, если в кластере часто создаются базы данных или пользователи, отстающие асинхронные реплики могут не аутентифицировать нового пользователя сразу после создания пользователя или базы данных на главном узле (лидере), так как они ещё отсутствуют на реплике. Чтобы избежать такой проблемы, можно задать значение leader для параметра proxima.auth_policy на всех узлах кластера.

F.74.6. Балансировщик нагрузки #

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

Расширение proxima предоставляет следующие порты для обработки клиентских сеансов:

  • Порт Proxy-to-Leader (P2L) перенаправляет всю нагрузку на ведущий узел (лидер). Номер порта по умолчанию — 4545, его можно изменить с помощью параметра proxima.port. Номер порта P2L должен быть одинаковым на всех узлах кластера.

  • Порт Proxy-to-Follower (P2F) распределяет читающую нагрузку между репликами в кластере. Номер порта по умолчанию — 4547, его можно изменить с помощью параметра proxima.p2f_port.

Примечание

В BiHA-кластере запросы перенаправляются на лидера в состоянии LEADER_RW. Однако читающая нагрузка, направленная на порт P2F, может также перенаправляться на лидера в состоянии LEADER_RO. За подробной информацией о состояниях узлов BiHA-кластера обратитесь к таблице biha.status_v.

Чтобы распределить нагрузку между узлами кластера, настройте клиентское приложение таким образом, чтобы нагрузка на запись направлялась на порт P2L, а на чтение — на порт P2F. За подробной информацией обратитесь к разделу Подразделу F.74.6.1.

Важно

Расширение proxima прикрепляет клиентский сеанс к определённому узлу кластера и таким образом обеспечивает выполнение всех транзакций в рамках этого сеанса на одном узле. Если узел выйдет из строя во время сеанса, клиентское соединение будет разорвано.

F.74.6.1. Настройка балансировщика нагрузки #

Расширение proxima позволяет настроить распределение нагрузки между узлами кластера. В примере ниже вы настроите распределение нагрузки для кластера из трёх узлов с адресами 192.168.0.1, 192.168.0.2 и 192.168.0.3, используя порты proxima по умолчанию — 4545 (P2L) и 4547 (P2F).

  1. Настройте клиентское приложение таким образом, чтобы пишущая нагрузка направлялась на порт P2L , а читающая — на порт P2F.

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

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

  2. (Необязательно) Укажите алгоритм балансировки нагрузки на чтение с помощью параметра proxima.load_balancer_algorithm.

  3. В строке подключения перечислите следующие адреса узлов в формате, который отвечает требованиям используемой библиотеки:

    192.168.0.1:4545
    192.168.0.1:4547
    192.168.0.2:4545
    192.168.0.2:4547
    192.168.0.3:4545
    192.168.0.3:4547

    Если вы используете libpq, обратитесь к Подразделу 36.1.1.3, чтобы узнать требования и синтаксис для указания множества адресов в строке подключения.

В результате при подключении к порту 4545 (P2L) пишущая нагрузка будет перенаправлена на ведущий узел (лидер). При подключении к порту 4547 (P2F) читающая нагрузка будет перенаправлена на одну из реплик в соответствии с выбранным алгоритмом.

F.74.7. Кеширование данных в памяти с модулем KVik #

Предупреждение

В настоящее время функциональность KVik является экспериментальной и не рекомендована для использования в производственной среде.

KVik — это экспериментальный встроенный модуль расширения proxima, предназначенный для кеширования данных в памяти. Модуль встроен в расширение proxima и работает внутри процесса proxima. KVik предоставляет высокопроизводительное хранилище данных в памяти с поддержкой протокола RESP (Redis Serialization Protocol). Использование KVik позволяет избежать развёртывания дополнительных серверов баз данных в памяти и настройки автоматической синхронизации с реляционными базами данных.

KVik предоставляет следующие ключевые возможности:

  • Поддержка протокола RESP и основных команд, таких как GET, SET и DEL.

  • Повышенная производительность для GET-операций, а также снижение читающей нагрузки на базу данных Postgres Pro Enterprise.

  • Хранение пар ключ-значение в строковом представлении.

  • Кеширование отсутствия записи при GET-запросах.

  • Аннулирование кеша.

  • Поддержка аутентификации.

  • Поддержка SSL-шифрования.

За примером настройки и использования KVik обратитесь к Подразделу F.74.7.1.

За подробной информацией об ограничениях KVik обратитесь к Подразделу F.74.2.2.

F.74.7.1. Начало работы с KVik #

Важно

В настоящий момент функциональность кеширования данных в памяти поддерживается только для одноузловых инсталляций Postgres Pro Enterprise. За подробной информацией об ограничениях и особенностях кеширования данных в памяти обратитесь к Подразделу F.74.2.2.

В этой инструкции приведён пример настройки и использования KVik. В примере показано, как подготовить экземпляр Postgres Pro Enterprise для работы с кешированием данных в памяти, настроить KVik, а затем протестировать работу KVik, выполняя запросы через утилиту redis-cli с помощью команд KVik.

Предварительные требования

Прежде чем начать пользоваться кешированием в памяти, подготовьте сервер Postgres Pro Enterprise следующим образом:

  1. Создайте базу данных mydb, которая будет принимать запросы по протоколу RESP (Redis Serialization Protocol).

  2. В базе данных mydb создайте таблицу test для работы с KVik:

    CREATE TABLE mydb.public.test (
      id INT PRIMARY KEY,
      val TEXT
    );
  3. Создайте пользователя myuser для аутентификации RESP-запросов в Postgres Pro Enterprise. Пользователь должен иметь права на выполнение операций DDL и DML.

    Важно

    В настоящий момент авторизация на уровне KVik не поддерживается, поэтому управлять правами пользователя myuser необходимо с помощью средств Postgres Pro Enterprise. За подробной информацией об ограничениях и особенностях кеширования данных в памяти обратитесь к Подразделу F.74.2.2.

Настройка модуля KVik

  1. Остановите сервер Postgres Pro Enterprise с помощью pg_ctl:

    pg_ctl stop -D каталог_PGDATA
  2. В файле postgresql.conf добавьте следующие параметры конфигурации:

    proxima.kvik_enabled = on
    proxima.kvik_memory_limit = 10
    proxima.kvik_port = 4550
    proxima.kvik_connections_to_pg = 2
    proxima.kvik_username = 'myuser'
    proxima.kvik_dbname = 'mydb:4'
    walsender_plugin_libraries = 'proxima'
    proxima.kvik_walsender_username = 'postgres'

    За подробной информацией о параметрах конфигурации KVik и их доступных значениях обратитесь к Подразделу F.74.12.1.7.

  3. Запустите сервер с помощью pg_ctl:

    pg_ctl start -D каталог_PGDATA

Проверка работы модуля KVik

  1. Используя утилиту redis-cli, выполните проверку подключения к KVik на порту 4550 с помощью команды PING:

    redis-cli -p 4550 PING
  2. Добавьте запись в таблицу test с помощью команды SET:

    redis-cli -p 4550 SET 'CRUD:mydb.public.test:{"id":1}' '{"id":1,"val": "test1"}'
    redis-cli -p 4550 SET 'CRUD:mydb.public.test:{"id":2}' '{"id":2,"val": "test2"}'
  3. (Необязательно) Убедитесь, что в таблице test были сделаны записи:

    SELECT * FROM mydb.public.test;
  4. Прочитайте записи из таблицы test с помощью команды GET:

    redis-cli -p 4550 GET 'CRUD:mydb.public.test:{"id":1}'
    redis-cli -p 4550 GET 'CRUD:mydb.public.test:{"id":2}'
  5. Удалите запись test1 из таблицы test с помощью команды DEL:

    redis-cli -p 4550 DEL 'CRUD:mydb.public.test:{"id":1}'
  6. Проверьте статистику KVik с помощью команды STAT:

    redis-cli -p 4550 STAT

    Значение store_size должно быть 1.

  7. Чтобы проверить аннулирование кеша:

    1. Аннулируйте весь кеш для таблицы test с помощью команды INVALIDATE:

      redis-cli -p 4550  INVALIDATE 'CRUD:mydb.public.test'
    2. Проверьте статистику KVik с помощью команды STAT:

      redis-cli -p 4550 STAT

      Значение store_size должно быть 0.

    3. Убедитесь, что запись test2 присутствует в таблице test:

      SELECT * FROM mydb.public.test;

F.74.7.2. Аннулирование кеша #

Аннулирование кеша — это процесс удаления устаревших данных из кеша. Аннулирование необходимо для сохранения согласованности при изменении кеша как через KVik, так и через SQL, а также на многоузловых конфигурациях Postgres Pro Enterprise.

KVik поддерживает аннулирование как положительного, так и отрицательного кеша. Положительный кеш хранит успешные результаты запросов. Отрицательный кеш хранит информацию об отсутствующих данных, что помогает предотвратить повторяющиеся запросы к Postgres Pro, которые возвращают NULL или No data. Положительный кеш аннулируется на основе информации WAL, в то время как для аннулирования отрицательного кеша используется специальный алгоритм.

Аннулирование кеша производится автоматически, без указания времени жизни (time to live, TTL) или каких-либо действий со стороны пользователей. Управлять автоматическим аннулированием устаревших кешированных данных можно с помощью специальных параметров конфигурации. Однако автоматическое аннулирование работает асинхронно, поэтому для того, чтобы обеспечить аннулирование всех необходимых записей кеша к нужному времени, можно выполнить аннулирование кеша вручную с помощью команды INVALIDATE.

Примечание

DDL-операции, такие как удаление таблиц или добавление столбцов, не аннулируются автоматически. Их необходимо аннулировать вручную с помощью команды INVALIDATE.

F.74.7.2.1. Настройка аннулирования кеша #

Используйте параметры конфигурации для настройки аннулирования кеша следующим образом:

  • Убедитесь, что в walsender_plugin_libraries есть значение proxima:

    walsender_plugin_libraries = 'proxima'
  • Используйте параметр конфигурации proxima.kvik_walsender_username, чтобы изменить пользователя, который по умолчанию используется для аутентификации запросов к специальному процессу walsender Postgres Pro Enterprise для аннулирования кеша. Убедитесь, что у нового пользователя есть атрибут REPLICATION.

  • Используйте параметр конфигурации proxima.kvik_neg_inv_time, чтобы изменить максимальное время аннулирования отрицательного кеша по умолчанию.

F.74.7.3. Настройка аутентификации для KVik #

KVik поддерживает следующие методы аутентификации:

Метод аутентификации можно указать с помощью параметра конфигурации proxima.kvik_auth_method. Метод аутентификации по умолчанию — trust.

Примечание

При использовании метода аутентификации password рекомендуется настроить SSL-шифрование.

Если задан метод password, клиентский сеанс необходимо начинать с команды AUTH для проверки пароля пользователя. Если переданы корректные имя пользователя и пароль, клиентский сеанс может продолжить отправлять запросы. Попытка отправить запрос без аутентификации вернёт ошибку.

F.74.7.4. Настройка SSL для KVik #

KVik поддерживает SSL-шифрование для входящих клиентских подключений к порту proxima.kvik_port.

Чтобы настроить SSL для KVik:

  1. Остановите узлы кластера с помощью pg_ctl.

  2. Получите и установите сертификат и закрытый ключ.

    Их можно либо получить в независимом центре сертификации (CA), либо сгенерировать самостоятельно с помощью утилиты для управления сертификатами, такой как OpenSSL.

  3. В postgresql.conf укажите пути к сертификату и закрытому ключу:

    proxima.ssl_key = '/путь/к/key.pem'
    proxima.ssl_cert = '/путь/к/cert.pem'

    Если параметры proxima.ssl_cert и proxima.ssl_key не заданы, proxima использует сертификат и ключ, настроенные для Postgres Pro в ssl_cert_file и ssl_key_file.

  4. Включите SSL для KVik, установив для параметра proxima.kvik_ssl_enabled значение on:

    proxima.kvik_ssl_enabled = on
  5. Запустите узлы с помощью pg_ctl.

  6. Проверьте работу SSL с помощью утилиты redis-cli. В примере ниже происходит проверка работы SSL для команды STAT:

    • Чтобы проверить шифрование трафика без проверки достоверности сертификата сервера, выполните:

      redis-cli --tls -p 4550 --insecure STAT

      --tls включает шифрование TLS/SSL, а --insecure отключает проверку сертификата.

    • Чтобы проверить шифрование трафика с проверкой достоверности сертификата сервера, выполните:

      redis-cli --tls -p 4550 --cacert путь_к_сертификату STAT

      или

      redis-cli --tls -p 4550 --cacertdir путь_к_каталогу_с_сертификатом STAT

      --cacert указывает путь к сертификату CA, которым подписан сертификат сервера. При использовании самоподписанного сертификата сервера, укажите тот же сертификат сервера.

      --cacertdir указывает каталог, в котором находятся сертификаты, которыми подписан сертификат сервера.

F.74.7.5. Изменение параметров конфигурации на лету #

Ряд параметров конфигурации KVik можно изменять и применять изменения на лету, т.е. без перезапуска кластера. Информация о том, поддерживается ли изменение на лету для каждого конкретного параметра, предоставлена в Подразделе F.74.12.1.7.

В этом примере показано, как изменить значение параметра proxima.kvik_memory_limit:

  1. Измените значение proxima.kvik_memory_limit:

    ALTER SYSTEM SET proxima.kvik_memory_limit = 2GB;
  2. Перезагрузите конфигурацию Postgres Pro:

    SELECT pg_reload_conf();

F.74.8. Динамический выделенный сеанс #

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

Примечание

Если вы используете расширения, которые хранят своё состояние в рамках сеанса, вам нужно вручную включить принудительный динамический выделенный сеанс. За дополнительной информацией обратитесь к Подразделу F.74.8.2.

Расширение proxima автоматически устанавливает динамический выделенный сеанс, если запрос содержит следующие объекты или функции SQL:

Сеанс остаётся выделенным, пока упомянутые выше объекты не будут удалены.

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

F.74.8.1. Хранилище подготовленных операторов #

Предупреждение

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

Чтобы не устанавливать динамический выделенный сеанс для запросов с подготовленными операторами, proxima предоставляет функциональность хранилища подготовленных операторов. Когда клиент создаёт подготовленный оператор, его текст и параметры сохраняются в хранилище proxima. Если proxima перенаправляет клиента на другой обслуживающий процесс, новый обслуживающий процесс извлекает подготовленный оператор из хранилища и подготавливает его локально. Таким образом, при работе с подготовленными операторами установка выделенного сеанса не требуется.

Хранилище подготовленных операторов находится в процессе proxima, и управлять им напрямую невозможно. Когда клиент создаёт или удаляет подготовленный оператор, обслуживающий процесс передаёт proxima информацию о необходимости обновить хранилище соответствующим образом. Размер хранилища зависит от количества подключённых клиентов и созданных подготовленных операторов. Каждый клиент использует примерно 104 байта памяти для системной информации. Каждый хранимый подготовленный оператор использует примерно 58 байт, а общее количество потребляемой памяти зависит от имени запроса, текста запроса, указания типов параметров и т.д. Учитывайте эту информацию при выделении оперативной памяти для вашего кластера.

Функциональностью хранилища подготовленных операторов можно управлять следующим образом:

  • Чтобы включить хранилище подготовленных операторов, используйте параметр конфигурации proxima.ps_enabled. Когда для параметра proxima.ps_enabled задано значение on, proxima назначает каждому клиенту уникальный идентификатор сеанса и передаёт этот идентификатор обслуживающему процессу. Обслуживающие процессы извлекают подготовленные операторы из хранилища с учётом полученных идентификаторов. Этот механизм обеспечивает недоступность подготовленных операторов определённого клиента для клиентов с другими идентификаторами сеанса.

  • Чтобы сделать подготовленные операторы, созданные одним клиентом, доступными для всех, используйте параметр конфигурации proxima.ps_shared. Когда для параметра proxima.ps_shared задано значение on, все клиенты используют единый идентификатор сеанса, а подготовленные операторы становятся видимыми для всех обслуживающих процессов в рамках одного узла.

    Важно

    • Подготовленные операторы могут быть общими только в рамках одного узла. Так как proxima распределяет нагрузку на чтение между репликами кластера в соответствии с заданным алгоритмом балансировки, разные клиенты могут быть перенаправлены на разные узлы. Соответственно, подготовленный оператор, созданный Клиентом 1 на Узле 1, будет недоступен для Клиента 2, подключённого к Узлу 2.

    • Когда для параметра proxima.ps_shared задано значение on, команда DEALLOCATE ALL не очищает хранилище proxima, так как подготовленные операторы являются общими и могут быть использованы другими клиентами.

  • Чтобы изменить максимальное количество подготовленных операторов в обслуживающем процессе, задайте значение для параметра конфигурации proxima.ps_cache_size с помощью команды SET, например:

    SET proxima.ps_cache_size = 64;

Примечание

Параметры конфигурации proxima.ps_enabled и proxima.ps_shared контролируют только процесс выдачи идентификаторов сеанса расширением proxima, а не поведение обслуживающих процессов. Изменение этих параметров, включая изменение через SIGHUP, не влияет на ранее подключившихся клиентов, так как их идентификаторы сеанса остаются неизменными. Изменения применяются только к новым клиентам.

F.74.8.2. Управление динамическими выделенными сеансами вручную #

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

Управлять принудительным динамическим выделенным сеансом можно следующим образом:

  • Чтобы включить принудительный динамический выделенный сеанс, выполните следующую команду:

    SET proxima.force_dedicated = true;
  • Чтобы отключить принудительный динамический выделенный сеанс, выполните следующую команду:

    SET proxima.force_dedicated = false;
  • Чтобы проверить, является ли текущий сеанс выделенным, используйте параметр proxima.is_dedicated:

    SHOW proxima.is_dedicated;

    Возвращённое значение t означает, что сеанс выделенный, в то время как f означает, что сеанс не выделенный.

F.74.9. Мониторинг #

Расширение proxima предоставляет функциональность мониторинга для отслеживания состояния proxima с помощью ряда метрик. Сейчас мониторинг доступен для BiHA-кластеров с включённым расширением proxima.

Расширение proxima регистрирует схему proxima в базе данных biha_db, где создаёт специальные представления для запросов метрик. За подробной информацией о просмотре метрик и примером SQL-запроса обратитесь к Подразделу F.74.9.3.

F.74.9.1. Передача метрик между узлами кластера #

Чтобы все метрики кластера были доступны на всех узлах, каждый узел раз в секунду передаёт свои метрики другим узлам. Если от узла в течение десяти секунд не поступали метрики, например, из-за потери соединения или падения узла, запрос не будет возвращать значения счётчиков с этого узла.

F.74.9.2. Особенности запросов через порты P2L и P2F #

Так как метрики запрашиваются с помощью обычного SQL, источником метрик всегда выступает узел, на котором выполняется запрос. При выполнении запроса учитывайте следующее:

  • При подключении через порт P2L метрики будут получены с лидера кластера.

  • При подключении к порту P2F proxima может распределить идущие подряд запросы между разными узлами. Так как доставка метрик происходит с задержкой, в некоторых случаях идущие подряд запросы могут показывать уменьшение интегральных счётчиков.

За подробной информацией о портах P2L и P2F обратитесь к Подразделу F.74.6.

Чтобы обеспечить монотонность роста счётчиков, при обработке результата всегда берите максимальное значение между текущими и ранее полученными значениями метрик.

F.74.9.3. Просмотр метрик мониторинга #

Просматривать метрики мониторинга в BiHA-кластере можно с помощью стандартных SQL-запросов к представлениям метрик:

  • Чтобы просмотреть все метрики кластера:

    SELECT * FROM proxima.proxima_metrics;
  • Чтобы просмотреть все метрики определённого узла:

    SELECT * FROM proxima.proxima_metrics WHERE node_id = идентификатор_узла;
  • Чтобы просмотреть метрики определённого класса, выполните запрос к представлению соответствующего класса. Например:

    SELECT * FROM proxima.proxima_metrics_client;

За подробной информацией о возможностях мониторинга обратитесь к Подразделу F.74.9.

За подробной информацией о доступных метриках обратитесь к Подразделу F.74.12.2.

Ниже приведён пример запроса на просмотр всех метрик узла с идентификатором 0, а также результат запроса (обрезан, так как метрик очень много):

postgres=# SELECT * FROM proxima.proxima_metrics WHERE node_id = 0;
                  name                    |    class     | node_id |        value
-------------------------------------------+--------------+---------+----------------------
thread.1.active_time_ns                   | thread-load  |       0 |          12590006201
thread.1.purged_coroutines                | thread-load  |       0 |                    6
thread.1.transferred_coroutines_accepted  | thread-load  |       0 |                    2
thread.1.wakeup_requests_accepted         | thread-load  |       0 |                    0
thread.1.futex_wakeup_requests_accepted   | thread-load  |       0 |                22752
thread.1.active_coroutines_called         | thread-load  |       0 |                72905
thread.1.evrun_once                       | thread-load  |       0 |                38456
thread.1.evrun_nowait                     | thread-load  |       0 |                 8700
thread.1.scheduler.coroctx_in_use         | thread-load  |       0 |                   19
thread.1.scheduler.coroctx_cached         | thread-load  |       0 |                    6
thread.1.scheduler.cs_active              | thread-load  |       0 |                    1
thread.1.scheduler.cs_inactive            | thread-load  |       0 |                    1
thread.1.scheduler.cs_waiting_futex       | thread-load  |       0 |                    5
thread.1.scheduler.cs_wakeup_futex        | thread-load  |       0 |                    0
thread.1.scheduler.cs_waiting_io          | thread-load  |       0 |                   12
memory.lgist-0                            | memory       |       0 |                    0
memory.lgist-1                            | memory       |       0 |                    8
memory.lgist-2                            | memory       |       0 |                   15
memory.lgist-3                            | memory       |       0 |                  162
memory.lgist-4                            | memory       |       0 |                  737
memory.lgist-5                            | memory       |       0 |                 1490
memory.lgist-6                            | memory       |       0 |                  174
memory.lgist-7                            | memory       |       0 |                  295
memory.lgist-8                            | memory       |       0 |                   70
memory.lgist-9                            | memory       |       0 |                   32
memory.lgist-10                           | memory       |       0 |                   20
memory.lgist-11                           | memory       |       0 |                    9
memory.lgist-12                           | memory       |       0 |                    1
memory.lgist-13                           | memory       |       0 |                   71
memory.lgist-14                           | memory       |       0 |                   61
memory.lgist-15                           | memory       |       0 |                    0
memory.lgist-16                           | memory       |       0 |                    6
memory.lgist-17                           | memory       |       0 |                    1
memory.lgist-18                           | memory       |       0 |                    0
memory.lgist-19                           | memory       |       0 |                    0
memory.lgist-20                           | memory       |       0 |                    0
memory.lgist-21                           | memory       |       0 |                    0
memory.lgist-22                           | memory       |       0 |                    1
memory.lgist-23                           | memory       |       0 |                    0
memory.lgist-24                           | memory       |       0 |                    0
memory.usage                              | memory       |       0 |              6581078
memory.traffic                            | memory       |       0 |              7983836
client.lfe.now_connected                  | client       |       0 |                    1
client.lfe.accepted                       | client       |       0 |                    1
client.lfe.rejected                       | client       |       0 |                    0
client.lfe.disconnected                   | client       |       0 |                    0
client.lfe.auth_password                  | client       |       0 |                    0
client.lfe.auth_md5                       | client       |       0 |                    0
client.lfe.auth_scram_sha256              | client       |       0 |                    0
client.lfe.auth_trust                     | client       |       0 |                    1
client.lfe.auth_tls_accepted              | client       |       0 |                    0
client.lfe.auth_tls_rejected              | client       |       0 |                    0
client.rfe.now_connected                  | client       |       0 |                    0
client.rfe.connected                      | client       |       0 |                    0
client.rfe.disconnected                   | client       |       0 |                    0
client.lbe.enter_dedicated                | client       |       0 |                    0

F.74.10. Общее администрирование #

В этом разделе приведены инструкции по администрированию proxima.

F.74.10.1. Конфигурирование SSL #

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

F.74.10.1.1. Включение SSL для входящих клиентский подключений #

Включите SSL для входящих клиентский подключений:

  1. Остановите узлы кластера с помощью pg_ctl.

  2. Получите и установите сертификат и закрытый ключ.

    Их можно либо получить в независимом центре сертификации (CA), либо сгенерировать самостоятельно с помощью утилиты для управления сертификатами, такой как OpenSSL.

  3. В postgresql.conf укажите пути к сертификату и закрытому ключу:

    proxima.ssl_key = '/путь/к/key.pem'
    proxima.ssl_cert = '/путь/к/cert.pem'

    Если параметры proxima.ssl_cert и proxima.ssl_key не заданы, proxima использует сертификат и ключ, настроенные для Postgres Pro в ssl_cert_file и ssl_key_file.

  4. Включите SSL для входящих подключений с помощью proxima.ssl_enabled:

    proxima.ssl_enabled = on
  5. (Необязательно) Чтобы проверить клиентские сертификаты, укажите путь к файлу с публичными сертификатами центра сертификации с помощью параметра конфигурации proxima.ssl_ca.

    Этот параметр обязателен, если вы используете метод аутентификации по сертификату.

  6. Запустите узлы с помощью pg_ctl.

Все клиентские подключения к порту proxima теперь защищены SSL.

F.74.10.1.2. Включение SSL-аутентификации для внутренних подключений #

Настройте SSL-аутентификацию для внутренних подключений между узлами кластера. В этой процедуре описана настройка SSL-аутентификации для кластера из двух узлов.

  1. Остановите узлы кластера с помощью pg_ctl.

  2. Для каждого узла кластера получите и установите сертификат и закрытый ключ.

    Их можно либо получить в независимом центре сертификации (CA), либо сгенерировать самостоятельно с помощью утилиты для управления сертификатами, такой как OpenSSL.

  3. Включите SSL для взаимодействия между узлами кластера с помощью параметра proxima.p2p_ssl_enabled:

      proxima.p2p_ssl_enabled = on
      
  4. Задайте параметры конфигурации proxima.p2p_auth_methods и proxima.ssl_trusted_certs_dir следующим образом:

    proxima.p2p_auth_methods = 'ssl'
    proxima.ssl_trusted_certs_dir = путь_к_каталогу_с_сертификатами
  5. Запустите узлы с помощью pg_ctl.

  6. Проверьте журнал, чтобы убедиться, что SSL-аутентификация прошла успешно.

    Следующие записи в журнале свидетельствуют о том, что в качестве метода аутентификации используется SSL и что аутентификация прошла успешно:

    [auth]: using SSL authentication
    [auth]: authentication success

F.74.10.2. Отключение и включение расширения proxima #

Расширение proxima можно временно отключить и затем вновь включить с помощью параметра конфигурации proxima.enabled:

  1. В файле postgresql.conf установите параметр proxima.enabled с необходимым значением:

    • Чтобы отключить proxima, установите параметр proxima.enabled со значением off:

      proxima.enabled = off
    • Чтобы включить proxima, установите параметр proxima.enabled со значением on:

      proxima.enabled = on
  2. Отправьте сигнал SIGHUP процессу proxima:

    kill -SIGHUP proxima_pid

    Здесь proxima_pid — ID процесса proxima.

F.74.10.3. Миграция #

При миграции кластера Postgres Pro Enterprise с proxima всегда отключайте proxima перед началом миграции BiHA-кластера. По окончании миграции повторно включите proxima. Расширение proxima в BiHA-кластере можно включать и отключать с помощью функции biha.enable_proxima.

F.74.10.4. Удаление proxima #

Чтобы отключить использование proxima:

  1. На всех узлах кластера удалите расширение из shared_preload_libraries в файле postgresql.conf.

  2. Перезапустите узлы с помощью команды pg_ctl.

F.74.11. Устранение неполадок #

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

F.74.11.1. База данных или пользователь не найдены #

Расширение proxima выполняет аутентификацию локально на узле, а не перенаправляет запрос доступа на ведущий узел или лидера. Если база данных или пользователь, к которым вы пытаетесь подключиться, не найдены, выполните следующие действия:

  1. Убедитесь, что между узлами настроена репликация с помощью стандартного механизма репликации или с помощью BiHA.

  2. Если репликация настроена и работает, подождите некоторое время, так как данные могли ещё не дойти до реплики.

F.74.11.2. Не удалось подключиться к proxima #

Если не удаётся подключиться к proxima, выполните следующие действия:

  1. Убедитесь, что для подключения используется порт proxima.port.

  2. Убедитесь, что файл pg_hba.conf настроен корректно.

F.74.11.3. Сообщение в журнале: «connection cannot be established» (невозможно установить соединение) #

Если вы видите в журнале это сообщение от proxima, выполните следующие действия:

  1. Убедитесь, что все узлы включены и нет проблем с сетью.

  2. Если вы используете режим работы кластера guc, убедитесь, что значения proxima.cluster_node_id настроены верно и совпадают с ID, указанными в proxima.cluster_config.

F.74.11.4. Сообщение в журнале: «failed to create cluster manager» (не удалось создать менеджер кластера) #

Если вы используете режим работы кластера guc , убедитесь, что proxima.cluster_config настроен корректно:

  • указаны все необходимые значения

  • набор значений для каждого узла оканчивается точкой с запятой (;)

F.74.11.5. Сообщение в журнале: «postgres: cannot accept new connection, error: Too many open files» (невозможно принять новое подключение, ошибка: Слишком много открытых файлов) #

Увеличьте максимальное число открытых файлов с помощью команды ulimit -S -n.

F.74.11.6. Сообщение в журнале: «router: trying to route session, last error: сообщение_об_ошибке» (попытка маршрутизировать сеанс, последняя ошибка: сообщение_об_ошибке) #

Это сообщение в журнале может появиться при подключении к узлам кластера.

Выполните следующие действия:

  • При работе с BiHA-кластером убедитесь, что значение параметра конфигурации proxima.port (порт P2L) одинаковое на всех узлах кластера. После того как вы задали одинаковые номера портов P2L, повторите попытку подключения.

  • Если дело не в разных номерах портов P2L, проверьте сообщение_об_ошибке:

    • Если сообщение содержит «failed to find leader config» (не удалось обнаружить конфигурацию лидера), дождитесь, когда узел получит информацию о ведущем узле (лидере). После получения информации подключение будет установлено.

    • Если сообщение содержит «load balancer error: are there any RO nodes in the cluster? Aborting» (ошибка балансировщика нагрузки: в кластере есть узлы в состоянии RO? Прерывание выполнения), убедитесь, что в кластере есть узлы в состоянии RO, и подключитесь повторно.

F.74.11.7. KVik: Слишком большое количество ложноположительных аннулирований SET-запросов #

Проблема может быть вызвана большим количеством SET-запросов. В результате данные могут не попадать в кеш.

Чтобы избежать этой проблемы, выполните одно из следующих действий:

  • Увеличьте количество подключений с помощью параметра конфигурации proxima.kvik_dbname.

  • Не используйте KVik для нагрузок с высоким количеством SET-запросов.

F.74.12. Справка #

F.74.12.1. Параметры конфигурации #

F.74.12.1.1. Общие параметры #
proxima.address (text) #

Указывает IP-адреса, на которых proxima принимает подключения. Можно указать адреса IPv4 или IPv6, а также каталоги Unix-сокетов. Значения должны быть разделены запятыми. Адреса можно указать следующим образом:

  • Любое количество IPv4-адресов, каждый из которых должен соответствовать адресу одного из локальных сетевых интерфейсов. Адрес 0.0.0.0 представляет все интерфейсы. Если он указан, все прочие указанные IPv4-адреса игнорируются.

  • Любое количество IPv6-адресов, каждый из которых должен соответствовать адресу одного из локальных сетевых интерфейсов. Адрес ::0 представляет все интерфейсы. Если он указан, все прочие указанные IPv6-адреса игнорируются.

  • Любое количество путей к каталогам Unix-сокетов. Имя Unix-сокета указывается в формате .s.PGSQL.порт, где порт — это номер, соответствующий одному из портов P2L, P2F или KVik. Имена сокетов имитируют сокеты PostgreSQL, чтобы для подключения через proxima можно было использовать psql или pgbench .

    Указанные пути должны быть абсолютными и начинаться с косой черты. Можно также указать макрос /$[индекс], где индекс — это номер каталога из списка, заданного в параметре конфигурации unix_socket_directories. Если значение unix_socket_directories не задано или индекс превышает количество каталогов, используется каталог /tmp. Имена каталогов не должны содержать пробелы, все пробелы игнорируются при разборе.

Значение по умолчанию — 0.0.0.0,::0,$/[0].

proxima.enabled (boolean) #

Временно включает и отключает расширение proxima. Доступны следующие значения:

  • off: временно останавливает расширение proxima.

  • on: запускает расширение proxima после временной остановки.

proxima.force_dedicated (boolean) #

Включает и отключает принудительные динамические выделенные сеансы. Доступны следующие значения:

  • true: включает принудительный динамический выделенный сеанс.

  • false: отключает принудительный динамический выделенный сеанс.

За подробной информацией обратитесь к разделу Подраздел F.74.8.2.

proxima.is_dedicated (boolean) #

Позволяет проверить, является ли текущий сеанс выделенным. Возвращает одно из следующих значений:

  • t: сеанс выделенный.

  • f: сеанс не выделенный.

За подробной информацией обратитесь к разделу Подраздел F.74.8.2.

proxima.load_balancer_algorithm (text) #

Определяет алгоритм балансировки для распределения нагрузки на чтение между репликами в кластере. Поддерживаются следующие значения:

  • round-robin: нагрузка распределяется между репликами по очереди.

  • weighted-round-robin: нагрузка распределяется между репликами по очереди, пропорционально их настроенным весам. Если выбран этот алгоритм, задайте веса узлов с помощью параметра конфигурации proxima.load_balancer_node_weight.

  • adaptive: нагрузка распределяется по репликам аналогично алгоритму weighted-round-robin. Однако для алгоритма adaptive значения весов реплик зависят от нагрузки на процессор, оперативную память и ввод-вывод диска в каждый момент времени. Чем выше нагрузка на реплике, тем меньше запросов будет на неё перенаправляться. Алгоритм adaptive определяет, как потребление каждого ресурса влияет на выбор узла во время балансировки. Долю каждого ресурса можно указать с помощью параметров proxima.load_balancer_cpu_weight, proxima.load_balancer_io_weight и proxima.load_balancer_ram_weight.

  • adaptive-cpu: нагрузка распределяется между репликами в зависимости от загрузки процессора. Чем выше загрузка на реплике, тем меньше запросов на неё перенаправляется.

  • adaptive-io: нагрузка распределяется по репликам в зависимости от загрузки ввода-вывода диска. Чем выше загрузка на реплике, тем меньше запросов на неё перенаправляется. Можно также задать среднее время ожидания на выполнение одной операции при обращении к диску с помощью параметров proxima.load_balancer_io_max_latency_ms и proxima.load_balancer_io_min_latency_ms.

  • adaptive-ram: нагрузка распределяется по репликам в зависимости от потребления оперативной памяти. Чем выше потребление на реплике, тем меньше запросов на неё перенаправляется.

  • least-connections: нагрузка распределяется на реплику с самым низким числом активных подключений.

  • random: нагрузка распределяется между репликами в случайном порядке.

Значение по умолчанию — round-robin.

proxima.load_balancer_node_weight (integer) #

Указывает вес текущего узла для алгоритма weighted-round-robin, заданного в параметре конфигурации proxima.load_balancer_node_weight. Процент запросов, перенаправленных на узел k, вычисляется по следующей формуле:

Pk = (nodek.weight / Σi nodei.weight) × 100%

В расчёте учитываются только узлы, являющиеся репликами.

Значение параметра можно изменить без перезапуска узла, отправив сигнал SIGHUP.

Диапазон допустимых значений: от 1 до 10000. Значение по умолчанию — 100.

proxima.load_balancer_cpu_weight (integer) #

Указывает долю влияния потребления ресурсов процессора на определение веса узла. Значение может быть задано в диапазоне от 0 до 10000. Значение по умолчанию — 100. Параметр активен, когда для параметра proxima.load_balancer_algorithm задано значение adaptive.

proxima.load_balancer_io_weight (integer) #

Указывает долю влияния загрузки ввода-вывода диска на определение веса узла. Значение может быть задано в диапазоне от 0 до 10000. Значение по умолчанию — 100. Параметр активен, когда для параметра proxima.load_balancer_algorithm задано значение adaptive. Можно также задать среднее время ожидания на выполнение одной операции при обращении к диску с помощью параметров proxima.load_balancer_io_max_latency_ms и proxima.load_balancer_io_min_latency_ms.

proxima.load_balancer_io_max_latency_ms (integer) #

Указывает максимальное время ожидания на выполнение одной операции при обращении к диску, в миллисекундах. Если текущее значение счётчика system.io_avg_latency_ms выше, чем значение proxima.load_balancer_io_max_latency_ms, узел получает наименьшую возможную долю веса, которая зависит от загрузки ввода-вывода диска. Значение может быть задано в диапазоне от 0 до 2^32-1. Значение по умолчанию — 40. Параметр активен, когда для параметра proxima.load_balancer_algorithm задано значение adaptive или adaptive-io.

proxima.load_balancer_io_min_latency_ms (integer) #

Указывает минимальное время ожидания для выполнения одной операции при обращении к диску, в миллисекундах. Если текущее значение счётчика system.io_avg_latency_ms меньше, чем значение proxima.load_balancer_io_min_latency_ms, узел получает наибольшую возможную долю веса узла, которая зависит от загрузки ввода-вывода диска. Значение может быть задано в диапазоне от 0 до 2^32-1. Значение по умолчанию — 10. Параметр активен, когда для параметра proxima.load_balancer_algorithm задано значение adaptive или adaptive-io.

proxima.load_balancer_ram_weight (integer) #

Указывает долю влияния потребления оперативной памяти на определение веса узла. Значение может быть задано в диапазоне от 0 до 10000. Значение по умолчанию — 100. Параметр активен, когда для параметра proxima.load_balancer_algorithm задано значение adaptive.

proxima.port (integer) #

Указывает порт Proxy-to-Leader (P2L) — TCP-порт, на котором proxima принимает входящие клиентские подключения и перенаправляет все запросы на ведущий узел (лидер).

Диапазон допустимых значений: от 0 до 65535. Значение по умолчанию — 4545. Значение для параметра proxima.port должно быть одинаковым на всех узлах кластера.

За подробной информацией о портах P2L и P2F обратитесь к Подразделу F.74.6.

proxima.p2f_port (integer) #

Указывает порт Proxy-to-Follower (P2F) — TCP-порт, на котором proxima принимает входящие клиентские подключения и распределяет читающую нагрузку между репликами в кластере.

Диапазон допустимых значений: от 0 до 65535. Значение по умолчанию — 4547.

За подробной информацией о портах P2L и P2F обратитесь к Подразделу F.74.6.

proxima.p2p_auth_methods (text) #

Указывает метод аутентификации для внутреннего взаимодействия между узлами кластера. Поддерживаются следующие методы:

Значение по умолчанию — trust. Можно перечислить несколько методов через запятую, например:

proxima.p2p_auth_methods = 'trust,ssl'

Если перечислить несколько методов, они будут применяться следующим образом в порядке убывания приоритета: ssl, trust.

proxima.p2p_ssl_enabled (boolean) #

Включает или отключает SSL для внутреннего взаимодействия между узлами кластера. Значение по умолчанию — off.

proxima.ssl_enabled (boolean) #

Включает или выключает SSL для входящих клиентских подключений к proxima.port. Значение по умолчанию — off. Если включить SSL и не задать параметры proxima.ssl_key и proxima.ssl_cert, proxima будет использовать SSL-сертификат, настроенный для Postgres Pro.

proxima.ssl_ca (text) #

Указывает путь к файлу с публичными сертификатами центра сертификации для проверки клиентских сертификатов. Параметр обязателен при использовании метода аутентификации по сертификату.

proxima.ssl_cert (text) #

Указывает путь к сертификату, который будет использоваться для SSL-соединения через proxima.port. Если значение не указано, proxima использует сертификат, указанный в ssl_cert_file. Если параметр задан, вам также нужно указать значение для proxima.ssl_key.

proxima.ssl_key (text) #

Указывает путь к файлу закрытого ключа. Если параметр не задан, proxima использует ключ, указанный в ssl_key_file. Если параметр задан, вам также нужно указать значение для proxima.ssl_cert.

proxima.ssl_trusted_certs_dir (text) #

Указывает путь к каталогу с доверенными сертификатами при настройке SSL-аутентификации с помощью proxima.p2p_auth_methods.

proxima.log_level (enum) #

Указывает уровень детализации сообщений proxima. Возможные значения: error, warning, info, verbose, debug. Значение по умолчанию — info.

proxima.workers (integer) #

Указывает число потоков, запускаемых для обработки запросов обслуживающим процессом proxima. Диапазон допустимых значений: от 1 до 65535. Чем выше значение, тем больше запросов может быть обработано. Значение по умолчанию — 4.

F.74.12.1.2. Конфигурирование кластера #
proxima.cluster_mode (text) #

Устанавливает режим работы кластера. Возможные режимы:

  • standalone — режим для одноузловой базы данных Postgres Pro.

  • guc — режим для стандартного кластера Postgres Pro конструкции ведущий-ведомый. Конфигурация кластера определяется параметрами proxima.cluster_config и proxima.cluster_node_id.

  • biha — режим для BiHA-кластера. В этом режиме конфигурация кластера передаётся расширением biha.

Значение по умолчанию — standalone. Значение этого параметра должно быть одинаковым на всех узлах кластера.

proxima.cluster_config (text) #

Устанавливает конфигурацию кластера для режима работы кластера guc. Значение этого параметра должно быть одинаковым на всех узлах кластера. Параметры подключения и идентификации необходимо указать для каждого узла следующим образом:

'id_узла,адрес_узла,порт_узла,роль_узла'

где:

  • id_узла — это идентификатор узла, в качестве которого необходимо указать значение в диапазоне от 0 до 255. Идентификатор узла должен быть уникальным для каждого узла в кластере.

  • адрес_узла — это IP-адрес узла для внутреннего соединения между узлами кластера.

  • порт_узла — это порт узла для внутреннего соединения между узлами кластера. Этот порт должен отличаться от proxima.port.

  • роль_узла — это роль узла в кластере. Возможные значения P (Primary, ведущий) и S (Standby, ведомый).

Пример значения proxima.cluster_config для кластера, состоящего из трёх узлов:

'0,127.0.0.1,4090,P;1,127.0.0.1,4091,S;2,127.0.0.1,4092,S;'
proxima.cluster_node_id (integer) #

Указывает уникальный идентификатор узла для режима работы кластера guc. Этот параметр не должен изменяться после запуска и до остановки кластера. Идентификатор узла должен быть уникальным для каждого узла кластера. Значение можно указать в диапазоне от 0 до 255. Значение по умолчанию — 0.

Список идентификаторов узлов должен всегда начинаться с 0 и заканчиваться n-1, где n — общее число узлов. Например, для кластера из трёх узлов идентификаторы узлов должны быть 0, 1, 2.

F.74.12.1.3. Настройка аутентификации #
proxima.auth_policy (text) #

Указывает, где должна выполняться аутентификация. Возможные значения:

  • local: аутентификация выполняется локально на узле с применением правил HBA и системного каталога узла. Это значение по умолчанию для всех узлов, кроме рефери.

  • leader: аутентификация выполняется на главном узле (лидере) с применением правил HBA и системного каталога главного узла (лидера). В BiHA-кластере это значение автоматически задаётся для рефери.

  • За подробной информацией обратитесь к разделу Проксирование аутентификации на главный узел (лидер).

F.74.12.1.4. Настройка хранилища подготовленных операторов #

Следующие параметры управляют хранилищем подготовленных операторов:

proxima.ps_enabled (boolean) #

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

Значение параметра можно изменить без перезапуска узла, отправив сигнал SIGHUP.

Возможные значения: on, off. Значение по умолчанию — off.

proxima.ps_shared (boolean) #

Включает совместное использование подготовленных операторов для всех клиентов. При включении все клиенты используют единый идентификатор сеанса, что делает подготовленные операторы, созданные одним клиентов, доступными для всех клиентов. Использование этого параметра конфигурации имеет смысл, только если для параметра proxima.ps_enabled задано значение on.

Значение параметра можно изменить без перезапуска узла, отправив сигнал SIGHUP.

Возможные значения: on, off. Значение по умолчанию — off.

proxima.ps_cache_size (integer) #

Определяет максимальное количество подготовленных операторов в обслуживающем процессе. Когда установленный предел достигается, подготовленные операторы вытесняются по стратегии LRU (Last Recently Used, удаление операторов, которые дольше всего не использовались). Если обслуживающий процесс попытается использовать вытесненный подготовленный оператор, ему придётся обратиться к хранилищу для повторного разбора запроса.

Этот параметр конфигурации влияет только на обслуживающие процессы. Его можно изменить в любое время с помощью команды SET.

Значение может быть задано в диапазоне от 8 до 2147483647. Значение по умолчанию — 32.

F.74.12.1.5. Настройка локального пула обслуживающих процессов #

Следующие параметры устанавливают ограничения для пула локальных обслуживающих процессов — Postgres Pro, обрабатывающих клиентские запросы.

proxima.backend_pool_local_total_limit (integer) #

Устанавливает максимальное число обслуживающих процессов, которые могут быть созданы на узле. Диапазон допустимых значений: от 1 до max_connections. Значение по умолчанию — 100.

proxima.backend_pool_local_bucket_limit (integer) #

Устанавливает максимальное число обслуживающих процессов, которые могут быть созданы в рамках подключений, идентифицированных связкой user + database. Диапазон допустимых значений: от 1 до значения, указанного в proxima.backend_pool_local_total_limit. Значение по умолчанию — 100.

proxima.backend_pool_local_overdue_interval (float) #

Устанавливает время бездействия локального обслуживающего процесса в секундах. Если локальный обслуживающий процесс не используется клиентами дольше, чем установлено этим параметром, обслуживающий процесс будет остановлен. Диапазон допустимых значений: от 1.0 до 86400.0. Значение по умолчанию — 10.0.

F.74.12.1.6. Настройка пула удалённых обслуживающих процессов #

Следующие параметры устанавливают ограничения для пула удалённых обслуживающих процессов. Удалённые обслуживающие процессы — это логические каналы, которые могут быть установлены через мультиплексированное соединение между узлами кластера для проксирования запросов от ведомого узла (последователя) к ведущему узлу (лидеру). Настройка этих параметров может быть необходима только для кластеров из нескольких узлов. Значения по умолчанию являются оптимальными и их не рекомендуется изменять.

proxima.backend_pool_remote_total_limit (integer) #

Устанавливает максимальное число логических каналов между узлами кластера для проксирования запросов клиента. Диапазон допустимых значений: от 1 до 2^32-1. Значение по умолчанию — 100000.

proxima.backend_pool_remote_bucket_limit (integer) #

Устанавливает максимальное число логических каналов между узлами кластера для проксирования клиентских запросов в рамках подключений, идентифицированных связкой user + database. Диапазон допустимых значений: от 1 до значения, указанного в proxima.backend_pool_remote_total_limit. Значение по умолчанию — 1000.

proxima.backend_pool_remote_overdue_interval (float) #

Устанавливает время бездействия удалённого обслуживающего процесса в секундах. Если удалённый обслуживающий процесс не используется клиентами дольше, чем установлено этим параметром, логическое соединение между узлами кластера будет разорвано. Диапазон допустимых значений от 1.0 до 86400.0. Значение по умолчанию — 60.0.

F.74.12.1.7. Настройка KVik #
proxima.kvik_auth_method (text) #

Указывает метод аутентификации для KVik. За подробной информацией обратитесь к Подразделу F.74.7.3.

Значение параметра можно изменить без перезапуска узла, отправив сигнал SIGHUP.

Возможные значения: trust, password. Значение по умолчанию — trust.

proxima.kvik_connections_to_pg (text) #

Устанавливает число локальных обслуживающих процессов, выделенных для обработки RESP-запросов. Диапазон допустимых значений: от 1 до MAX_BACKENDS. Значение по умолчанию — 2.

proxima.kvik_dbname (text) #

Указывает базу данных KVik для RESP-запросов и максимально разрешённое число подключений к этой базе. Можно указать одну или несколько баз данных в следующем формате:

proxima.kvik_dbname = 'база_данных_1:число_подключений_к_базе данных_1, база_данных_2:число_подключений_к_базе_данных_2'

Например:

proxima.kvik_dbname = 'mydb1:4, mydb2:6'

Количество подключений к одной базе данных не должно превышать 12.

Если не указать число подключений, будет использовано значение, указанное в параметре proxima.kvik_connections_to_pg.

Этот параметр можно изменять на лету.

proxima.kvik_enabled (boolean) #

Включает или отключает кеширование данных и приём RESP-подключений на порту proxima.kvik_port. При значении on кеширование данных включено. При значении off кеширование данных отключено. Значение по умолчанию — off.

proxima.kvik_memory_limit (integer) #

Устанавливает размер оперативной памяти, выделенной для хранения кешированных записей. Значение можно задать в диапазоне от 1 до 1048576. Значение по умолчанию — 10 МБ, минимальное значение — 1 МБ. Для этого параметра конфигурации можно указать единицы измерения. Если единицы измерения не указаны, считается, что значение задано в мегабайтах.

Этот параметр можно изменять на лету. Можно как увеличивать, так и уменьшать значение. При уменьшении значения данные немедленно вытесняются.

proxima.kvik_neg_inv_time (integer) #

Указывает максимальное время аннулирования отрицательного кеша. Возможные значения — от 1 до 86400000. Значение по умолчанию — 5 мс. Для этого параметра конфигурации можно указать единицы измерения. Если единицы измерения не указаны, считается, что значение задано в миллисекундах.

Этот параметр можно изменять на лету.

proxima.kvik_port (integer) #

Указывает TCP-порт для приёма подключений по протоколу RESP. Можно задать значение в диапазоне от 0 до 65535. Значение по умолчанию — 4550.

Адрес настраивается в общем параметре proxima.address.

proxima.kvik_ssl_enabled (boolean) #

Включает или отключает SSL-шифрование для входящих клиентских подключений к порту proxima.kvik_port. Возможные значения: on, off. Значение по умолчанию — off. За подробной информацией о настройке SSL для KVik обратитесь к Подразделу F.74.7.4.

proxima.kvik_username (text) #

Указывает пользователя, от имени которого происходит аутентификация RESP-запросов в Postgres Pro Enterprise.

proxima.kvik_walsender_username (text) #

Указывает пользователя для аутентификации запросов к специальному процессу walsender Postgres Pro Enterprise для аннулирования кеша. Пользователь должен иметь атрибут REPLICATION. Значение по умолчанию — postgres.

F.74.12.2. Метрики мониторинга #

Все метрики мониторинга proxima разделены на несколько классов, чтобы их было удобно запрашивать через представления метрик.

Доступны следующие классы:

F.74.12.2.1. Представления метрик мониторинга #

При использовании в BiHA-кластере, proxima регистрирует схему proxima в базе данных biha_db, где создаёт представления для запроса метрик.

Доступны следующие представления:

F.74.12.2.2. Метрики потоков #

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

Имена метрик потоков имеют структуру thread.ID.имя_счётчика, где ID — внутренний идентификатор корутинового движка.

Доступны следующие счётчики:

Таблица F.59. Счётчики потоков

ИмяТипОписание
thread.ID.active_time_nsИнтегральныйКоличество наносекунд, в течение которого поток исполнял какую-либо полезную нагрузку.
thread.ID.purged_coroutinesИнтегральныйКоличество контекстов корутин, которые были разрушены из-за длительной невостребованности.
thread.ID.transferred_coroutines_acceptedИнтегральныйКоличество контекстов корутин, перенесённых для исполнения на этот поток.
thread.ID.wakeup_requests_acceptedИнтегральныйКоличество принятых запросов на пробуждение корутины.
thread.ID.futex_wakeup_requests_acceptedИнтегральныйКоличество принятых запросов на пробуждение корутины, заблокированной на фьютексе (futex).
thread.ID.active_coroutines_calledИнтегральныйКоличество вызовов активных корутин. Если удвоить это значение, можно получить количество переключений контекстов корутин в текущем потоке.
thread.ID.evrun_onceИнтегральныйКоличество вызовов библиотеки libev c блокировкой потока для ожидания событий, относящихся к вводу-выводу или активным таймерам.
thread.ID.evrun_nowaitИнтегральныйКоличество вызовов библиотеки libev без блокировки потока для ожидания событий, относящихся к вводу-выводу или активным таймерам.
thread.ID.scheduler.coroctx_in_useМгновенное значениеКоличество контекстов корутин, которые используются в настоящий момент.
thread.ID.scheduler.coroctx_cachedМгновенное значениеКоличество контекстов корутин, которые в текущий момент кешированны и не используются, но могут быть быстро предоставлены при создании новых корутин.
thread.ID.scheduler.cs_activeМгновенное значениеКоличество активных корутин.
thread.ID.scheduler.cs_inactiveМгновенное значениеКоличество корутин в неактивном состоянии.
thread.ID.scheduler.cs_waiting_futexМгновенное значениеКоличество корутин в ожидании фьютекса.
thread.ID.scheduler.cs_wakeup_futexМгновенное значениеКоличество корутин в очереди пробуждения при блокировке на фьютексе.
thread.ID.scheduler.cs_waiting_ioМгновенное значениеКоличество корутин в ожидании доступности чтения или записи на устройстве ввода-вывода или активации таймера (например, при блокировке в операции sleep).

Пример результата запроса метрик потоков выглядит следующим образом:

                 name                   |    class    | node_id |   value
------------------------------------------+-------------+---------+------------
thread.1.active_time_ns                  | thread-load |       0 | 6319387757
thread.1.purged_coroutines               | thread-load |       0 |          1
thread.1.transferred_coroutines_accepted | thread-load |       0 |          2
thread.1.wakeup_requests_accepted        | thread-load |       0 |          0
thread.1.futex_wakeup_requests_accepted  | thread-load |       0 |      10214
thread.1.active_coroutines_called        | thread-load |       0 |      32385
thread.1.evrun_once                      | thread-load |       0 |      17162
thread.1.evrun_nowait                    | thread-load |       0 |       4567
thread.1.scheduler.coroctx_in_use        | thread-load |       0 |         19
thread.1.scheduler.coroctx_cached        | thread-load |       0 |          1
thread.1.scheduler.cs_active             | thread-load |       0 |          1
thread.1.scheduler.cs_inactive           | thread-load |       0 |          1
thread.1.scheduler.cs_waiting_futex      | thread-load |       0 |          5
thread.1.scheduler.cs_wakeup_futex       | thread-load |       0 |          0
thread.1.scheduler.cs_waiting_io         | thread-load |       0 |         12
thread.2.active_time_ns                  | thread-load |       0 |     974064
thread.2.purged_coroutines               | thread-load |       0 |          0
thread.2.transferred_coroutines_accepted | thread-load |       0 |          0
thread.2.wakeup_requests_accepted        | thread-load |       0 |          0
thread.2.futex_wakeup_requests_accepted  | thread-load |       0 |          6
thread.2.active_coroutines_called        | thread-load |       0 |          7
thread.2.evrun_once                      | thread-load |       0 |        109
thread.2.evrun_nowait                    | thread-load |       0 |          0
thread.2.scheduler.coroctx_in_use        | thread-load |       0 |          1
thread.2.scheduler.coroctx_cached        | thread-load |       0 |          0
thread.2.scheduler.cs_active             | thread-load |       0 |          0
thread.2.scheduler.cs_inactive           | thread-load |       0 |          0
thread.2.scheduler.cs_waiting_futex      | thread-load |       0 |          1
thread.2.scheduler.cs_wakeup_futex       | thread-load |       0 |          0
thread.2.scheduler.cs_waiting_io         | thread-load |       0 |          0
...
F.74.12.2.3. Метрики трафика #

Метрики трафика отображают байты и/или сообщения, которые передаются через канал связи, а также количество сброшенных сообщений и повторных подключений, если они поддерживаются текущим каналом связи.

Имена метрик трафика имеют структуру traffic.CHANNEL.COUNTER, где:

  • CHANNEL — канал, данные которого отображаются в результате запроса. Поддерживаются следующие каналы:

    • fe (frontend) — передача данных между всеми клиентами и proxima.

    • be (backend) — данные, передаваемые между proxima и обслуживающими процессами proxima.

    • rpc (RPC, Remote Procedure Call) — данные, передаваемые между proxima и другими процессами текущего экземпляра базы данных.

    • nodeID.client — данные, передаваемые через клиентское подключение между текущим узлом и узлом с идентификатором ID.

    • nodeID.server — данные, передаваемые через серверное подключение между текущим узлом и узлом с идентификатором ID.

  • COUNTER — имя счётчика.

Доступны следующие счётчики:

Таблица F.60. Счётчики трафика

ИмяТипОписание
traffic.CHANNEL.rx_bytesИнтегральныйКоличество байтов, принятых по каналу связи.
traffic.CHANNEL.tx_bytesИнтегральныйКоличество байтов, отправленных по каналу связи.
traffic.CHANNEL.rx_msgsИнтегральныйКоличество принятых сообщений. Этот счётчик присутствует, только если канал поддерживает отслеживание отдельных сообщений.
traffic.CHANNEL.tx_msgsИнтегральныйКоличество отправленных сообщений. Этот счётчик присутствует, только если канал поддерживает отслеживание отдельных сообщений.
traffic.CHANNEL.rx_msgs_droppedИнтегральныйКоличество сброшенных сообщений. Этот счётчик присутствует, только если канал поддерживает сброс сообщений (dropping).
traffic.CHANNEL.reconnectsИнтегральныйКоличество повторных подключений после сбоев. Этот счётчик присутствует, только если канал поддерживает повторные подключения.

Пример результата запроса метрик трафика выглядит следующим образом:

               name                 |  class  | node_id |  value
--------------------------------------+---------+---------+----------
traffic.fe.rx_bytes                  | traffic |       0 |      943
traffic.fe.tx_bytes                  | traffic |       0 |    10632
traffic.be.rx_bytes                  | traffic |       0 |    13233
traffic.be.tx_bytes                  | traffic |       0 |     2099
traffic.node1.client.rx_bytes        | traffic |       0 |       32
traffic.node1.client.tx_bytes        | traffic |       0 | 64641815
traffic.node1.client.rx_msgs         | traffic |       0 |      124
traffic.node1.client.tx_msgs         | traffic |       0 |     7868
traffic.node1.client.rx_msgs_dropped | traffic |       0 |        0
traffic.node1.client.reconnects      | traffic |       0 |        1
traffic.node2.client.rx_bytes        | traffic |       0 |       32
traffic.node2.client.tx_bytes        | traffic |       0 | 64609591
traffic.node2.client.rx_msgs         | traffic |       0 |      124
traffic.node2.client.tx_msgs         | traffic |       0 |     7864
traffic.node2.client.rx_msgs_dropped | traffic |       0 |        0
traffic.node2.client.reconnects      | traffic |       0 |        1
traffic.rpc.rx_bytes                 | traffic |       0 |      100
traffic.rpc.tx_bytes                 | traffic |       0 |    12416
traffic.rpc.rx_msgs                  | traffic |       0 |        3
traffic.rpc.tx_msgs                  | traffic |       0 |        2
traffic.node2.server.rx_bytes        | traffic |       0 | 56532348
traffic.node2.server.tx_bytes        | traffic |       0 |       32
traffic.node2.server.rx_msgs         | traffic |       0 |     7868
traffic.node2.server.tx_msgs         | traffic |       0 |      124
traffic.node2.server.rx_msgs_dropped | traffic |       0 |        0
traffic.node2.server.reconnects      | traffic |       0 |        1
traffic.node1.server.rx_bytes        | traffic |       0 | 56504900
traffic.node1.server.tx_bytes        | traffic |       0 |       32
traffic.node1.server.rx_msgs         | traffic |       0 |     7864
traffic.node1.server.tx_msgs         | traffic |       0 |      124
traffic.node1.server.rx_msgs_dropped | traffic |       0 |        0
traffic.node1.server.reconnects      | traffic |       0 |        1
F.74.12.2.4. Метрики пула обслуживающих процессов #

Метрики пула обслуживающих процессов отображают характеристики запросов клиентов к пулу на предоставление обслуживающих процессов.

Имена метрик пула обслуживающих процессов имеют структуру backend_pool.SCOPE.COUNTER, где:

  • SCOPE определяет тип обслуживающего процесса: локальный или удалённый.

  • COUNTER — имя счётчика.

Доступны следующие счётчики:

Таблица F.61. Счётчики пула обслуживающих процессов

ИмяТипОписание
backend_pool.SCOPE.requestsИнтегральныйКоличество запросов на предоставление обслуживающих процессов к пулу обслуживающих процессов.
backend_pool.SCOPE.creationsИнтегральныйКоличество новых обслуживающих процессов, созданных при запросе у пула.
backend_pool.SCOPE.destructionsИнтегральныйКоличество разрушений (закрытий) обслуживающих процессов. Может случиться, когда обслуживающий процесс вытесняется из бакета пула или не используется долгое время.
backend_pool.SCOPE.unlinksИнтегральныйКоличество обслуживающих процессов, отвязанных от пула.
backend_pool.SCOPE.acquisitionsИнтегральныйКоличество обслуживающих процессов, предоставленных клиентам.
backend_pool.SCOPE.releasesИнтегральныйКоличество обслуживающих процессов, возвращённых клиентами в пул. В случае ряда ошибок обслуживающий процесс может быть разрушен клиентом, а не возвращён в пул. Это вызовет рост значения backend_pool.SCOPE.unlinks, но не backend_pool.SCOPE.releases.
backend_pool.SCOPE.stealsИнтегральныйКоличество «краж» обслуживающих процессов из других бакетов пула. Интенсивный рост этого значения означает, что система испытывает высокую нагрузку на множестве различных баз данных и/или от множества различных пользователей. Это указывает на недостаточный размер пула для текущей нагрузки, что приводит к деградации производительности системы.
backend_pool.SCOPE.errorsИнтегральныйКоличество ошибок, возникших при запросе обслуживающих процессов из пула. Это обобщённый счётчик. В некоторых случаях ошибки могут вызвать разрыв клиентских подключений. В других случаях ошибка может привести к повторению запроса обслуживающего процесса и быть прозрачной для клиента. Например, если пул отказывает в предоставлении обслуживающего процесса, так как его невозможно создать по причине превышения лимита max_connections, клиент будет ожидать в очереди.
backend_pool.SCOPE.request_duration.p*Процентиль (окно: T = 60 секунд, C = 1000 событий)Процентили времени между запросом обслуживающего процесса и фактическим предоставлением обслуживающего процесса клиенту. Это совокупный счётчик, значения которого могут сильно отличаться. Например, предоставление свободного обслуживающего процесса из пула может занимать микросекунды, создание нового — миллисекунды. Но если пул перегружен, и клиент должен ждать выполнения предыдущего запроса к базе данных, это может занять секунды, минуты, и даже часы. Другими словами, этот счётчик показывает распределение времени ожидания в очереди пула перед выполнением запроса.

Пример результата запроса метрик пула обслуживающих процессов выглядит следующим образом:

                 name                    |    class     | node_id |         value
-------------------------------------------+--------------+---------+------------------------
backend_pool.local.requests               | backend-pool |       0 |                     13
backend_pool.local.creations              | backend-pool |       0 |                      5
backend_pool.local.destructions           | backend-pool |       0 |                      3
backend_pool.local.unlinks                | backend-pool |       0 |                      4
backend_pool.local.acquisitions           | backend-pool |       0 |                     12
backend_pool.local.releases               | backend-pool |       0 |                     10
backend_pool.local.steals                 | backend-pool |       0 |                      0
backend_pool.local.errors                 | backend-pool |       0 |                      1
backend_pool.local.request_duration.p0    | backend-pool |       0 |   8.74983775227453e-06
backend_pool.local.request_duration.p5    | backend-pool |       0 |  8.765000496725975e-06
backend_pool.local.request_duration.p25   | backend-pool |       0 |  9.654992595293691e-06
backend_pool.local.request_duration.p50   | backend-pool |       0 | 1.0727600464262677e-05
backend_pool.local.request_duration.p75   | backend-pool |       0 | 1.1514681787272259e-05
backend_pool.local.request_duration.p95   | backend-pool |       0 |   0.008438241305000952
backend_pool.local.request_duration.p100  | backend-pool |       0 |   0.008452788451603185
backend_pool.remote.requests              | backend-pool |       0 |                      0
backend_pool.remote.creations             | backend-pool |       0 |                      0
backend_pool.remote.destructions          | backend-pool |       0 |                      0
backend_pool.remote.unlinks               | backend-pool |       0 |                      0
backend_pool.remote.acquisitions          | backend-pool |       0 |                      0
backend_pool.remote.releases              | backend-pool |       0 |                      0
backend_pool.remote.steals                | backend-pool |       0 |                      0
backend_pool.remote.errors                | backend-pool |       0 |                      0
backend_pool.remote.request_duration.p0   | backend-pool |       0 |                      0
backend_pool.remote.request_duration.p5   | backend-pool |       0 |                      0
backend_pool.remote.request_duration.p25  | backend-pool |       0 |                      0
backend_pool.remote.request_duration.p50  | backend-pool |       0 |                      0
backend_pool.remote.request_duration.p75  | backend-pool |       0 |                      0
backend_pool.remote.request_duration.p95  | backend-pool |       0 |                      0
backend_pool.remote.request_duration.p100 | backend-pool |       0 |                      0
F.74.12.2.5. Метрики клиентских подключений #

Метрики клиентских подключений включают счётчики подключений и их характеристики для различных каналов связи.

Имена метрик клиентских подключений имеют структуру client.CHANNEL.COUNTER, где:

  • CHANNEL — канал связи, данные которого отображаются в результате запроса. Поддерживаются следующие каналы:

    • lfe (local frontend) — клиенты, которые подключаются к proxima через один из портов для выполнения SQL-запросов.

    • lbe (local backend) — обслуживающие процессы Postgres Pro Enterprise, созданные proxima.

    • rfe (remote frontend) — клиенты, перенаправленные на текущий узел с другого узла.

    • rbe (remote backend) — внутренние каналы связи, созданные расширением proxima для перенаправления запросов на удалённый узел.

    • rpc (RPC, Remote Procedure Call) — данные, передаваемые между proxima и другими процессами текущего экземпляра базы данных.

  • COUNTER — имя счётчика.

Доступны следующие счётчики:

Таблица F.62. Счётчики клиентских подключений

ИмяТипОписание
client.lfe.now_connectedМгновенное значениеКоличество клиентов, фактически подключённых к текущему узлу.
client.lfe.acceptedИнтегральныйКоличество клиентов с успешно аутентифицированными подключениями.
client.lfe.rejectedИнтегральныйКоличество клиентов с подключениями, которые были отклонены, так как не были аутентифицированы.
client.lfe.failedИнтегральныйКоличество клиентов с подключениями, отклонёнными по причине ошибок процесса аутентификации.
client.lfe.disconnectedИнтегральныйКоличество клиентов с закрытыми подключениями.
client.lfe.auth_passwordИнтегральныйКоличество клиентов, аутентифицированных по паролю.
client.lfe.auth_md5ИнтегральныйКоличество клиентов, аутентифицированных по методу MD5.
client.lfe.auth_scram_sha256ИнтегральныйКоличество клиентов, аутентифицированных по методу SCRAM-SHA-256.
client.lfe.auth_ldapИнтегральныйКоличество клиентов, аутентифицированных по методу LDAP.
client.lfe.auth_trustИнтегральныйКоличество клиентов, подключение от которых попало под правила HBA в категории доверенных.
client.lfe.auth_rejectИнтегральныйКоличество клиентов, подключение от которых попало под правила HBA в категории запрещённых (reject).
client.lfe.auth_tls_acceptedИнтегральныйКоличество принятых TLS-подключений.
client.lfe.auth_tls_rejectedИнтегральныйКоличество отклонённых TLS-подключений.
client.lfe.auth_duration.p*Процентиль (окно: T = 60 секунд, C = 1000 событий)Распределение времени для процедуры аутентификации клиентов.
client.lbe.enter_dedicatedИнтегральныйКоличество подключений обслуживающих процессов, перешедших в выделенный сеанс.
client.lbe.leave_dedicatedИнтегральныйКоличество подключений обслуживающих процессов, покинувших выделенный сеанс.
client.lbe.dedicated_duration.p*Процентиль (окно: T = 60 секунд, C = 1000 событий)Распределение времени для подключений, оставшихся в выделенном сеансе.
client.rfe.now_connectedМгновенное значениеФактическое количество клиентов, перенаправленных на текущий узел для выполнения запроса.
client.rfe.connectedИнтегральныйКоличество клиентов, перенаправленных на текущий узел для выполнения запроса.
client.rfe.disconnectedИнтегральныйКоличество клиентов с закрытыми подключениями.
client.rbe.enter_dedicatedИнтегральныйКоличество подключений обслуживающих процессов, перешедших в выделенный сеанс.
client.rbe.leave_dedicatedИнтегральныйКоличество подключений обслуживающих процессов, покинувших выделенный сеанс.
client.rbe.dedicated_duration.p*Процентиль (окно: T = 60 секунд, C = 1000 событий)Распределение времени для подключений, оставшихся в выделенном сеансе.
client.rpc.now_connectedМгновенное значениеКоличество клиентов, подключённых в настоящий момент.
client.rpc.acceptedИнтегральныйКоличество клиентов с успешно принятыми подключениями с учётом прохождения процедуры аутентификации.
client.rpc.rejectedИнтегральныйКоличество клиентов с отклонёнными подключениями, в основном из-за ошибок аутентификации.
client.rpc.disconnectedИнтегральныйКоличество клиентов с закрытыми подключениями.

Пример результата запроса метрик клиентских подключений выглядит следующим образом:

                name                | class  | node_id | value
------------------------------------+--------+---------+-------
 client.lfe.now_connected           | client |       0 |     1
 client.lfe.accepted                | client |       0 |     1
 client.lfe.rejected                | client |       0 |     0
 client.lfe.failed                  | client |       0 |     0
 client.lfe.disconnected            | client |       0 |     0
 client.lfe.auth_password           | client |       0 |     0
 client.lfe.auth_md5                | client |       0 |     0
 client.lfe.auth_scram_sha256       | client |       0 |     0
 client.lfe.auth_ldap               | client |       0 |     0
 client.lfe.auth_trust              | client |       0 |     1
 client.lfe.auth_reject             | client |       0 |     0
 client.lfe.auth_tls_accepted       | client |       0 |     0
 client.lfe.auth_tls_rejected       | client |       0 |     0
 client.rfe.now_connected           | client |       0 |     0
 client.rfe.connected               | client |       0 |     0
 client.rfe.disconnected            | client |       0 |     0
 client.lbe.enter_dedicated         | client |       0 |     0
 client.lbe.leave_dedicated         | client |       0 |     0
 client.rbe.enter_dedicated         | client |       0 |     0
 client.rbe.leave_dedicated         | client |       0 |     0
 client.rpc.now_connected           | client |       0 |     1
 client.rpc.accepted                | client |       0 |     4
 client.rpc.rejected                | client |       0 |     0
 client.rpc.disconnected            | client |       0 |     3
 client.lfe.auth_duration.p0        | client |       0 |     0
 client.lfe.auth_duration.p5        | client |       0 |     0
 client.lfe.auth_duration.p25       | client |       0 |     0
 client.lfe.auth_duration.p50       | client |       0 |     0
 client.lfe.auth_duration.p75       | client |       0 |     0
 client.lfe.auth_duration.p95       | client |       0 |     0
 client.lfe.auth_duration.p100      | client |       0 |     0
 client.lbe.dedicated_duration.p0   | client |       0 |     0
 client.lbe.dedicated_duration.p5   | client |       0 |     0
 client.lbe.dedicated_duration.p25  | client |       0 |     0
 client.lbe.dedicated_duration.p50  | client |       0 |     0
 client.lbe.dedicated_duration.p75  | client |       0 |     0
 client.lbe.dedicated_duration.p95  | client |       0 |     0
 client.lbe.dedicated_duration.p100 | client |       0 |     0
 client.rbe.dedicated_duration.p0   | client |       0 |     0
 client.rbe.dedicated_duration.p5   | client |       0 |     0
 client.rbe.dedicated_duration.p25  | client |       0 |     0
 client.rbe.dedicated_duration.p50  | client |       0 |     0
 client.rbe.dedicated_duration.p75  | client |       0 |     0
 client.rbe.dedicated_duration.p95  | client |       0 |     0
 client.rbe.dedicated_duration.p100 | client |       0 |     0
F.74.12.2.6. Метрики RPC-сервера #

Доступны следующие счётчики:

Таблица F.63. Счётчики RPC-сервера

ИмяТипОписание
rpc.call_duration.p*Процентиль (окно: T = 60 секунд, C = 1000 событий)Время распределения выполнения команд.
rpc.err_not_foundИнтегральныйКоличество вызовов несуществующих функций.

Пример результата запроса метрик RPC-сервера выглядит следующим образом:

          name          | class | node_id |         value
------------------------+-------+---------+------------------------
 rpc.call_duration.p0   | rpc   |       0 |  4.315190768277686e-05
 rpc.call_duration.p5   | rpc   |       0 |  4.331642078668621e-05
 rpc.call_duration.p25  | rpc   |       0 |  6.386338595749277e-05
 rpc.call_duration.p50  | rpc   |       0 |   7.37059571607683e-05
 rpc.call_duration.p75  | rpc   |       0 |  8.217731456416661e-05
 rpc.call_duration.p95  | rpc   |       0 | 0.00011075225182228674
 rpc.call_duration.p100 | rpc   |       0 | 0.00011117317272816024
 rpc.err_not_found      | rpc   |       0 |                      0
F.74.12.2.7. Метрики KVik #

Метрики KVik собираются в течение всей работы модуля KVik. Каждый счётчик занимает 64 бита, поэтому переполнение счётчиков невозможно.

Доступны следующие счётчики:

Таблица F.64. Счётчики KVik

ИмяТипОписание
kvik.store_sizeМгновенное значениеКоличество хранимых записей.
kvik.store_memoryМгновенное значениеРазмер памяти, занимаемый хранимыми записями.
kvik.client_connectИнтегральныйКоличество успешных клиентских подключений.
kvik.client_disconnectИнтегральныйОбщее количество отключённых клиентских соединений.
kvik.client_requestsИнтегральныйОбщее количество запросов.
kvik.client_request_errorsИнтегральныйКоличество неуспешных запросов.
kvik.client_getsИнтегральныйКоличество GET-запросов.
kvik.client_setsИнтегральныйКоличество SET-запросов.
kvik.client_delsИнтегральныйКоличество DEL-запросов.
kvik.cache_hitИнтегральныйКоличество GET-запросов, при которых запрашиваемые значения были обнаружены в локальной копии кеша.
kvik.cache_hit_in_mainИнтегральныйКоличество GET-запросов, при которых запрашиваемые значения были обнаружены в глобальном кеше.
kvik.cache_missИнтегральныйКоличество GET-запросов, при которых запрашиваемые значения не были обнаружены в кеше.
kvik.cache_neg_write_countИнтегральныйОбщее количество записей отрицательного кеша.
kvik.cache_evictИнтегральныйКоличество вытесненных записей.
kvik.cache_invalidate_entryИнтегральныйКоличество аннулирований записей. Счётчик увеличивается, когда:
  • отрицательные значения удаляются из кеша (для кеша данных и метаданных)

  • команда INVALIDATE вызывается для конкретного ключа

  • положительный кеш аннулируется

kvik.cache_invalidate_tableИнтегральныйКоличество аннулирований таблиц. Счётчик увеличивается, когда:
  • таблица удаляется командой INVALIDATE

  • положительный кеш аннулируется

kvik.pass_to_mainИнтегральныйКоличество запросов, перенаправленных для обработки главному рабочему процессу.
kvik.sql_metaИнтегральныйКоличество запросов к Postgres Pro Enterprise на получение метаданных.
kvik.sql_getsИнтегральныйКоличество запросов к Postgres Pro Enterprise для получения данных. Значение может совпадать с kvik.cache_miss.
kvik.sql_setsИнтегральныйКоличество запросов к Postgres Pro Enterprise для установки данных. Значение может совпадать с kvik.client_sets.
kvik.sql_delsИнтегральныйКоличество запросов к Postgres Pro Enterprise на удаление данных. Значение может совпадать с kvik.client_dels.
kvik.sql_result_reusesИнтегральныйКоличество GET-запросов, заполненных результатом другого запроса для такого же ключа. Например, при одновременном получении двух запросов на один и тот же ключ для обработки первого запроса происходит обращение к Postgres Pro Enterprise, а второй запрос обрабатывается с использованием результатов первого запроса.

Пример вывода запроса к метрикам KVik выглядит следующим образом:

name                       | class | node_id | value
-------------------------------+---------+---------+-------
kvik.store_size            | kvik  |       0 |     0
kvik.store_memory          | kvik  |       0 |     0
kvik.client_connect        | kvik  |       0 |     0
kvik.client_disconnect     | kvik  |       0 |     0
kvik.client_requests       | kvik  |       0 |     0
kvik.client_request_errors | kvik  |       0 |     0
kvik.client_gets           | kvik  |       0 |     0
kvik.client_sets           | kvik  |       0 |     0
kvik.client_dels           | kvik  |       0 |     0
kvik.cache_hit             | kvik  |       0 |     0
kvik.cache_hit_in_main     | kvik  |       0 |     0
kvik.cache_miss            | kvik  |       0 |     0
kvik.cache_neg_write_count | kvik  |       0 |     0
kvik.cache_evict           | kvik  |       0 |     0
kvik.cache_invalidate_entry| kvik  |       0 |     0
kvik.cache_invalidate_table| kvik  |       0 |     0
kvik.pass_to_main          | kvik  |       0 |     0
kvik.sql_meta              | kvik  |       0 |     0
kvik.sql_gets              | kvik  |       0 |     0
kvik.sql_sets              | kvik  |       0 |     0
kvik.sql_dels              | kvik  |       0 |     0
kvik.sql_result_reuses     | kvik  |       0 |     0
F.74.12.2.8. Системные метрики #

Доступны следующие счётчики:

Таблица F.65. Системные счётчики

ИмяТипОписание
system.cpu_loadМгновенное значениеПроцент загрузки ЦП на узле.
system.avail_ram_bМгновенное значениеОбъём свободной оперативной памяти на узле, в байтах.
system.total_ram_bМгновенное значениеОбщий объём оперативной памяти на узле, в байтах.
system.io_avg_latency_msМгновенное значениеСреднее время ожидания выполнения одной операции при обращении к диску, в миллисекундах.

Пример результата запроса системных метрик выглядит следующим образом:

           name           | class  | node_id |       value
--------------------------+--------+---------+--------------------
 system.cpu_load          | system |       0 |  6.779661016949152
 system.avail_ram_b       | system |       0 |        22180810752
 system.total_ram_b       | system |       0 |        32619315200
 system.io_avg_latency_ms | system |       0 | 3.6666666666666665

F.74.12.3. Команды KVik #

В этом разделе перечислены команды, которые поддерживает KVik.

Переменная первичный_ключ, которая используется в примерах ниже, является первичным ключом, сериализованным в формате JSON.

Обратитесь к Подразделу F.74.7.1 за примерами использования команд KVik.

AUTH #

Обращается к Postgres Pro для проверки имени пользователя и пароля.

Команда используется следующим образом:

AUTH имя_пользователя пароль_пользователя

Примечание

Используйте эту команду, только если для KVik настроен метод аутентификации password.

DEL #

Удаляет данные из базы данных KVik.

Команду необходимо использовать с ключом в следующем формате:

CRUD:имя_базы_данных.имя_схемы.имя_таблицы:{первичный_ключ}

Примечание

Если выполнение команды возвращает ошибку, это не всегда означает, что изменения не были применены в базе данных.

Например:

DEL 'CRUD:mydb.public.test:{"id":1}'

Можно также использовать составной первичный ключ, например:

DEL 'CRUD:mydb.public.test:{"id":1,"suffix":"ex"}'
GET #

Читает данные из базы данных KVik.

Команду необходимо использовать с ключом в следующем формате:

CRUD:имя_базы_данных.имя_схемы.имя_таблицы:{первичный_ключ}

Например:

GET 'CRUD:mydb.public.test:{"id":1}'

Можно также использовать составной первичный ключ, например:

GET 'CRUD:mydb.public.test:{"id":1,"suffix":"ex"}'
INVALIDATE #

Аннулирует записи кеша в базе данных KVik.

Команду необходимо использовать в следующем формате:

-- Аннулировать весь кеш:
INVALIDATE CRUD

-- Аннулировать кеш для указанной базы данных:
INVALIDATE CRUD:имя_базы_данных

-- Аннулировать кеш для указанной таблицы:
INVALIDATE CRUD:имя_базы_данных.имя_схемы.имя_таблицы

-- Аннулировать кеш по указанному ключу:
INVALIDATE CRUD:имя_базы_данных.имя_схемы.имя_таблицы:{первичный_ключ}

Например:

redis-cli -p 4550 INVALIDATE 'CRUD'
PING #

Выполняет проверку подключения к KVik. Возвращает PONG, если подключение активно.

SET #

Добавляет или обновляет данные в базе данных KVik.

Команду необходимо использовать с парой ключ-значение в следующем формате:

SET 'CRUD:имя_базы_данных.имя_схемы.имя_таблицы:{первичный_ключ}' '{первичный_ключ, значение}'

Примечание

Если выполнение команды возвращает ошибку, это не всегда означает, что изменения не были применены в базе данных.

Например:

SET 'CRUD:mydb.public.test:{"id":1}' '{"id":1,"val":"test"}'

Можно также указать значение без первичного ключа:

SET 'CRUD:mydb.public.test:{"id":1}' '{"val":"test"}'

Можно также использовать составной первичный ключ:

SET 'CRUD:mydb.public.test:{"id":1,"suffix":"ex"}' '{"val": "test"}'
STAT #

Возвращает статистику KVik с набором метрик. За подробной информацией обратитесь к разделу Метрики KVik.

FAQ