Асинхронная репликация
Reindexer поддерживает механизм асинхронной репликации.
У каждого экземпляра сервера, задействованного в репликации, может быть роль Leader
или Follower
.
В качестве Leader
может выступать сервер Reindexer Standalone
, Built-in
, Built-in server
(подробнее о вариантах использования — в разделе «Установка Reindexer»).
Роль Follower
может быть у сервера Standalone
и Built-in server
: Leader
-у нужен доступ к RPC-интерфейсам Follower
-ов.
Начиная с версии 4.x.x в Reindexer реализована push-репликация.
При таком механизме Leader
инициирует отправку сведений об изменениях Follower
-ам.
В версии 3.x.x использовался механизм асинхронной pull-репликации.
При переходе с Reindexer 3.x.x на 4.x.x ряд настроек необходимо выполнить вручную (подробнее — в разделе Настройки асинхронной репликации при миграции с Reindexer версии 3.x.x на 4.x.x).
Механизмы асинхронной репликации в Reindexer
Для реализации репликации в Reindexer используется 3 различных механизма:
Механизм | Когда используется | Особенности |
---|---|---|
Полная синхронизация с использованием снимка неймспейса (force-sync) | 1. При начальной синхронизации для копирования полной структуры и данных из неймспейса Leader в Follower или от одного Follower к другому.2. В случае ошибки с репликацией WAL (например, WAL устарел, или появились несовместимые изменения в структуре индексов) |
В этом режиме Leader создает моментальный снэпшот неймспейса (используется стратегия COW ) и отправляет все свои индексы и данные Follower |
Запись из локального журнала WAL (wal-sync) |
Когда Leader устанавливает сетевое соединение с Follower для синхронизации данных (например, при потере связи с Follower ) |
Leader запрашивает LSN из WAL Follower -а, делает запрос к своему локальному WAL (каждая запись в нем — это информация про отдельный документ, либо update/delete-запрос), на выходе формирует снэпшот, содержащий только недостающие записи из WAL , и применяет из него все записи. В результате все данные в WAL Leader и Follower совпадают |
Онлайн-обновления WAL в реальном времени (онлайн репликация) |
Когда установлено соединение между Leader и Follower |
Leader отправляет поток обновлений WAL на всех подключенных Follower -ов. Этот режим требует меньше ресурсов процессора и памяти Leader |
Каскадная репликация
Reindexer также поддерживает каскадную репликацию.
В этом случае может быть только один Leader
.
Но у Follower
-ов могут быть свои Follower
-ы:
Leader
/ \
Follower1 Follower2
| / \
Follower1.1 Follower2.1 Follower2.2
На этой схеме Follower1
и Follower2
реплицируют данные своим Follower
-ам, но при этом не предоставляют возможность изменения данных для внешних клиентов.
Настройка асинхронной репликации в Reindexer, начиная с версии 4.x.x
Настройка репликации в Reindexer возможна двумя способами: через служебный неймспейс #config
и с помощью файлов конфигурации.
Настройка репликации через служебный неймспейс #config
Репликация настраивается на стороне Leader
.
Для этого в служебном неймспейсе #config
:
-
Задаются общие параметры репликации. Подробнее — в разделе «Настройка общих параметров репликации».
-
Устанавливаются специальные параметры для асинхронной репликации.
Настройка специальных параметров асинхронной репликации
Специальные параметры для асинхронной репликации задаются в служебном неймспейсе #config
ноды-Leader
, в айтеме async_replication
:
{
"type": "async_replication",
"async_replication": {
"role": "none",
"sync_threads": 4,
"syncs_per_thread": 2,
"online_updates_timeout_sec": 20,
"online_updates_delay_msec": 100,
"sync_timeout_sec": 60,
"retry_sync_interval_msec": 30000,
"enable_compression": true,
"batching_routines_count": 100,
"force_sync_on_logic_error": false,
"force_sync_on_wrong_data_hash": false,
"log_level": "info",
"max_wal_depth_on_force_sync": 1000,
"namespaces": [],
"nodes": [
{
"dsn": "cproto://192.168.1.5:6534/mydb",
"namespaces": []
}
]
}
}
Здесь:
-
role
— роль экземпляра сервера в репликации. Возможные значения:none
— репликация отключена,follower
— сервер участвует в репликации какFollower
,leader
— сервер участвует в репликации какLeader
.
-
sync_threads
— количество потоков репликации. -
syncs_per_thread
— Максимальное количество одновременных полных синхронизаций для каждого потока репликации. -
online_updates_timeout_sec
— время ожидания ответа отFollower
для режима онлайн-репликации. Задается в секундах. -
online_updates_delay_msec
— задержка между записью в локальную базу и репликацией. Более высоие значения улучшают батчинг, существенно снижая потребление CPU при реплицировании, но это так же непрямую влияет на задержку попадания данных на реплику. -
sync_timeout_sec
— время на запись чанка из снэпшота. Если запись не произошла за это время, то соединение разрывается и происходит полная синхронизация. Задается в секундах. -
retry_sync_interval_msec
— таймаут повторной попытки синхронизации при возникновении сетевых ошибок. -
enable_compression
— флаг для включения/отключения сжатия сетевого трафика. -
batching_routines_count
— количество корутин, одновременно занимающихся отправкой данных при онлайн-репликации для каждогоFollower
-а. Увеличение числа корутин снизит задержки, связанные с сетью, за счёт большей асинхронности, но увеличит потребление памяти. -
log_level
— уровень логирования репликатора при запуске. Возможные значения: none, error, warning, info, trace. -
max_wal_depth_on_force_sync
— максимальное количество записейWAL
, которые будут скопированы после запуска полной синхронизации. Увеличение значения этого параметра может помочь избежатьforce-syncs
синхронизации после переключенияLeader
, а также увеличивает расход оперативной памяти во время синхронизации. -
online_updates_delay_msec
— задержка реплицирования для онлайн-репликации. Использование этой задержки позволяет значительно сократить потребление CPU за счёт объединения отдельных записей в батчи (по умолчанию используется задежрка 100 мс). Напрямую влияет на время, за которое одиночные записи реплицируются наFollower
-ов. Задаётся в милисекундах. -
namespaces
— список неймспейсов для репликации. Если он пустой, будет выполняться репликация всех неймспейсов из базы данных. Все реплицируемые неймспейсы наFollower
-ах будут иметь режим read-only. -
nodes
— списокFollower
-ов и их настройки:dsn
— DSN ноды—Follower
-а. Должен задаваться в cproto-формате. Содержит адрес и порт для доступа кFollower
по протоколу RPC и имя БДFollower
, в которую будут реплицироваться данные.namespaces
— необязательный список неймспейсов для репликации на данную ноду-Follower
. Если он не задан, будет использоваться значение из общей конфигурации репликации.
Настройка репликации с помощью файлов конфигурации
При этом способе настройки используются YAML-файлы конфигурации:
replication.conf
— для настройки общих параметров репликации,async_replication.conf
— для настройки специальных параметров асинхронной репликации.
Их необходимо разместить в директории реплицируемой базы данных.
Файлы replication.conf
и async_replication.conf
считываются при старте СУБД.
Если в этот момент они существуют, то их содержимое будет синхронизироваться в рантайме со служебным неймспейсом #config
: то, что записано в файлы, будет перенесено в неймспейс, и наоборот.
Если же файлов нет в директории реплицируемой базы данных при старте сервера, будут применяться настройки репликации из неймспейса #config
, а содержимое добавленных replication.conf
и async_replication.conf
будет игнорироваться до перезапуска.
При этом, если файлов нет при старте сервера, создаваться автоматически они не будут.
Содержимое файла конфигурации replication.conf
аналогично содержимому поля replication
служебного неймспейса config
.
Пример файла конфигурации для настройки общих параметров репликации.
Содержимое файла конфигурации async_replication.conf
аналогично содержимому поля async_replication
служебного неймспейса config
.
Пример файла конфигурации для настройки специальных параметров асинхронной репликации.
Проверка статуса репликации
Сведения о статусе репликации доступны в служебном неймспейсе #memstats
. Пример запроса для их получения через reindexer_tool
:
Reindexer> SELECT name,replication FROM #memstats WHERE name='media_items'
В ответ вернется JSON-объект со сведениями о статусе репликации для неймспейса (в примере выше проверяется статус репликации для неймспейса media_items
):
{
"items": [
{
"name": "media_items",
"replication": {
"last_lsn": 3,
"last_lsn_v2": {
"server_id": 0,
"counter": 3
},
"temporary": false,
"incarnation_counter": 0,
"data_hash": 6806236826,
"data_count": 3,
"updated_unix_nano": 1655797373139806200,
"ns_version": {
"server_id": 0,
"counter": 9
},
"clusterization_status": {
"leader_id": 0,
"role": "simple_replica"
},
"wal_count": 3,
"wal_size": 108
}
}
],
"namespaces": [
"#memstats"
],
"cache_enabled": false
}
Здесь:
-
last_lsn
— (deprecated-поле) ЗначениеLSN
. -
last_lsn_v2
: -LSN
последней операции по изменению данных неймспейса на ноде. При репликации значенияLSN
для каждой записиLeader
иFollower
будут иметь одинаковые значения.server_id
— id ноды, являющейся источником этогоLSN
.counter
— количествоLSN
на ноде.
-
temporary
— флаг, указывающий, является ли неймспейс временным. -
incarnation_counter
— количество переключений междуLeader
иFollower
. -
data_hash
— хэш данных неймспейса. -
data_count
— количество записей в неймспейсе. -
updated_unix_nano
— время выполнения последнего обновления данных. -
ns_version
:server_id
— id ноды, id ноды, являющейся источником этогоLSN
.counter
— текущая версия неймспейса.
-
clusterization_status
:leader_id
— server_id ноды, которая является лидером для этой реплики,role
— текущая роль в репликации. Возможные значения:simple_replica
— асинхронная read-only реплика;cluster_replica
— один изFollower
-ов в синхронном RAFT-кластере;none
—Leader
в асинхронной репликации, в синхронном кластере, либо неймспейс не участвует в репликации.
-
wal_count
— количество записей вWAL
. -
wal_size
— размерWAL
.
Интерактивное управление репликацией
В Reindexer также поддерживается несколько команд для интерактивного управления репликацией через reindexer_tool
или веб-интерфейс.
Перезапуск репликации
При отправке запроса на Leader
процесс репликации перезапускается полностью. Пример запроса через reindexer_tool
Reindexer> \upsert #config { "type":"action","action":{ "command":"restart_replication" } }
Сброс роли в репликации
Команда будет полезна, если вы хотите отменить участие Follover
-а в репликации и сделать его неймспейсы доступными для изменения, отключив режим read-only
.
Пример запроса для сброса роли в репликации через reindexer_tool
:
Reindexer> \upsert #config { "type":"action","action":{ "command":"reset_replication_role" } }
Сброс роли в репликации для определенного неймспейса
Позволяет отключить на Follower
-е репликацию определенного неймспейса и сделать его доступным для изменения (отключить режим read-only
). Пример запроса через reindexer_tool
:
Reindexer> \upsert #config { "type":"action","action":{ "command":"reset_replication_role", "namespace": "ns_name" } }
Помимо сброса роли в репликации (в том числе и для определенного неймспейса) и отключения режима
read-only
для ноды, ее нужно вывести из репликации в настройкахLeader
. Для этого удалите данногоFollower
-а из поляnodes
в неймспейсе#config
Leader
-а. Если этого не сделать, произойдет force-sync и нода снова станетFollower
-ом.
Управление уровнем логирования репликатора
Команда позволяет менять уровень логирования асинхронного и кластерного (синхронного) репликаторов без их перезапуска. Логирование осуществляется через core-логгер, поэтому для info/trace-логов репликатора требуется уровень core-логирования не ниже, чем info.
Reindexer> \upsert #config { "type":"action","action":{ "command":"set_log_level", "type": "async_replication", "level":"trace" } }
Возможные значения types
:
async_replication
(для логов асинхронного репликатора),cluster
(для логов синхронного репликатора и логов RAFT).
Возможные значения levels
:
none
,error
,warning
,info
,trace
.
Настройки асинхронной репликации при миграции с Reindexer версии 3.x.x на 4.x.x
В версии Reindexer 3.x.x была реализована асинхронная pull-репликация. Ее настройки несовместимы с настройками репликации Reindexer 4.x.x. Поэтому вам придется выполнить конфигурацию вручную.
Для этого требуется ряд изменений в объектах replication
и async_replication
в служебных неймспейсах #config
.
Id серверов и кластеров в объекте replication
служебного неймспейса #config
для Leader
-а и Follower
-ов изменять при этом не нужно.
Пример миграции для одноуровневой схемы асинхронной репликации
В качестве примера рассмотрим миграцию для следующей схемы репликации:
leader(192.168.10.1)
/ \
follower1(192.168.10.2) follower2(192.168.10.3)
Настройки для follower1
Настройки репликации для follower1
в объекте replication
:
{
"type":"replication",
"replication":{
"role":"slave",
"master_dsn":"cproto://192.168.10.1/db",
"cluster_id":2,
"server_id":1,
"force_sync_on_logic_error": false,
"force_sync_on_wrong_data_hash": false,
"namespaces":
- "ns1"
}
}
{
"type": "replication",
"replication": {
"cluster_id": 2,
"server_id": 1
}
}
Deprecated параметры должны быть удалены из настроек Follower
-а.
Reindexer> \upsert #config { "type": "replication", "replication": { "server_id": 1, "cluster_id": 2 } }
Настройки для follower2
Настройки репликации для follower2
в объекте replication
:
{
"type":"replication",
"replication":{
"role":"slave",
"master_dsn":"cproto://192.168.10.3/db",
"cluster_id":2,
"server_id":2,
"force_sync_on_logic_error": false,
"force_sync_on_wrong_data_hash": false,
"namespaces":
- "ns2"
- "ns3"
}
}
{
"type": "replication",
"replication": {
"cluster_id": 2,
"server_id": 2
}
}
Deprecated-параметры должны быть удалены из настроек Follower
-а.
Reindexer> \upsert #config { "type": "replication", "replication": { "server_id": 2, "cluster_id": 2 } }
Настройки для всех Follower
В ходе миграции для всех Follower
-ов нужно задать роль follower
в объекте async_replication
служебного неймспейса #config
:
{
"type": "async_replication",
"async_replication": {
"role": "follower"
}
}
Пример запроса на изменение настроек через reindeхer_tool
:
Reindexer> \upsert #config { "type": "async_replication", "async_replication": { "role":"follower" } }
Настройки для Leader
Настройки репликации для leader
в объекте replication
:
{
"type": "replication",
"replication": {
"role": "master",
"master_dsn": "",
"cluster_id": 2,
"server_id": 0
}
}
{
"type": "replication",
"replication": {
"cluster_id": 2,
"server_id": 0
}
}
Reindexer> \upsert #config { "type": "replication", "replication": { "server_id": 0, "cluster_id": 2 } }
Настройки репликации для leader
в объекте async_replication
для Reindexer 4.x.x:
Для leader
в ходе миграции нужно создать новую конфигурацию в объекте async_replication
служебного неймспейса #config
:
{
"type": "async_replication",
"async_replication": {
"role": "leader",
"sync_threads": 4,
"syncs_per_thread": 2,
"online_updates_timeout_sec": 60,
"retry_sync_interval_msec": 30000,
"enable_compression": true,
"batching_routines_count": 100,
"force_sync_on_logic_error": false,
"force_sync_on_wrong_data_hash": false,
"namespaces": [],
"nodes": [
{
"dsn": "cproto://192.168.10.2:6534/mydb",
"namespaces": [
"ns1"
]
},
{
"dsn": "cproto://192.168.10.3:6534/mydb",
"namespaces": [
"ns2",
"ns3"
]
}
]
}
}
Пример НТТР-запроса для создания новой конфигурации:
curl --location --request PATCH 'http://192.168.10.1/api/v1/db/testdb/namespaces/%23config/items' \
--header 'Content-Type: application/json' \
--data-raw '{
"type": "async_replication",
"async_replication": {
"role": "leader",
"sync_threads": 4,
"syncs_per_thread": 2,
"online_updates_timeout_sec": 60,
"retry_sync_interval_msec": 30000,
"enable_compression": true,
"batching_routines_count": 100,
"force_sync_on_logic_error": false,
"force_sync_on_wrong_data_hash": false,
"namespaces": [],
"nodes": [
{
"dsn": "cproto://192.168.10.2:6534/mydb",
"namespaces": [
"ns1"
]
},
{
"dsn": "cproto://192.168.10.3:6534/mydb",
"namespaces": [
"ns2",
"ns3"
]
}
]
}
}'
Миграция с Reindexer версии 3.x.x на 4.x.x при использовании каскадной асинхронной репликации
Миграция для каскадной репликации не сильно отличается от миграции для других схем.
Как и в случае с одноуровневой схемой репликации, потребуется изменить конфигурацию в объектах replication
и async_replication
в служебных неймспейсах #config
нод.
Ниже представлены примеры конфигурации для нод, участвующих в каскадной репликации до и после миграции, для схемы:
leader(192.168.10.1)
|
follower1(192.168.10.2)
|
follower2(192.168.10.3)
Настройки для follower1
Объект replication
неймспейса #config
для follower1
:
{
"type": "replication",
"replication": {
"role": "slave",
"master_dsn": "cproto://192.168.10.1/db",
"cluster_id": 2,
"server_id": 1,
"force_sync_on_logic_error": false,
"force_sync_on_wrong_data_hash": false,
"namespaces": []
}
}
{
"type": "replication",
"replication": {
"cluster_id": 2,
"server_id": 1
}
}
Так как follower1
будет выступать в роли Leader
-а для follower2
из примера, для него нужно еще задать настройки в объекте async_replication
неймспейса #config
:
{
"type": "async_replication",
"async_replication": {
"role": "leader",
"sync_threads": 4,
"syncs_per_thread": 2,
"online_updates_timeout_sec": 60,
"retry_sync_interval_msec": 30000,
"enable_compression": true,
"batching_routines_count": 100,
"force_sync_on_logic_error": false,
"force_sync_on_wrong_data_hash": false,
"namespaces": [],
"nodes": [
{
"dsn": "cproto://192.168.10.3:6534/mydb"
}
]
}
}
Обратите внимание, что в настройках
follower1
(который выступает в ролиLeader
дляfollower2
) вnodes
не указывается список неймспейсов для репликации для конкретной ноды-Follower
. Список неймспейсов для репликации берется из массиваnamespaces
объектаasync_replication
.
Настройки для follower2
Объект replication
неймспейса #config
для follower2
:
{
"type":"replication",
"replication":{
"role":"slave",
"master_dsn":"cproto://192.168.10.2/db",
"cluster_id":2,
"server_id":2,
"force_sync_on_logic_error": false,
"force_sync_on_wrong_data_hash": false,
"namespaces": []
}
}
{
"type": "replication",
"replication": {
"cluster_id": 2,
"server_id": 2
}
}
Также для follower2
нужно установить соответствующую роль в объекте async_replication
неймспейса #config
:
{
"type": "replication",
"async_replication": {
"role": "follower"
}
}
Настройки для leader
Объект replication
неймспейса #config
для leader
:
{
"type": "replication",
"replication": {
"role": "master",
"master_dsn": "",
"cluster_id": 2,
"server_id": 0
}
}
{
"type": "replication",
"replication": {
"cluster_id": 2,
"server_id": 0
}
}
Настройки для leader
в объекте async_replication
неймспейса #config
:
{
"type": "async_replication",
"async_replication": {
"role": "leader",
"sync_threads": 4,
"syncs_per_thread": 2,
"online_updates_timeout_sec": 60,
"retry_sync_interval_msec": 30000,
"enable_compression": true,
"batching_routines_count": 100,
"force_sync_on_logic_error": false,
"force_sync_on_wrong_data_hash": false,
"namespaces": [],
"nodes": [
{
"dsn": "cproto://192.168.10.2:6534/mydb"
}
]
}
}