По мере роста бизнеса и экспоненциального увеличения объёмов данных и запросов доступа, монолитная архитектура, в которой один кластер обрабатывает как запросы на запись, так и запросы на чтение, сталкивается с типичными проблемами, такими как конкуренция за ресурсы и перегрузка. Чтобы решить эти проблемы, CSS вводит read/write splitting между кластерами Elasticsearch.
Read/write splitting в Elasticsearch работает за счёт совместной работы кластеров Leader и Follower. Функция предоставляет следующие преимущества:
Рисунок 1 Read/write splitting

Как работает read/write splitting между кластерами Elasticsearch:
Кластер Leader синхронизирует изменения данных с кластером Follower через REST API. Поддерживаются два метода синхронизации:
Figure 2 иллюстрирует, как работает разделение чтения/записи.
Figure 2 Как работает разделение чтения/записи

Созданы два кластера Elasticsearch одной версии. Один функционирует как leader, другой — как follower. Кластер follower должен иметь возможность доступа к REST API (порт по умолчанию: 9200) кластера leader.
Войдите в Kibana и перейдите на страницу выполнения команд. Кластеры Elasticsearch поддерживают несколько методов доступа. В данном разделе в качестве примера используется Kibana для описания процедур операций.
Левая часть консоли — это command input box, а треугольный значок в её правом верхнем углу является execution button. Правая часть отображает результат выполнения.
PUT /_cluster/settings{"persistent" : {"cluster" : {"remote.rest" : {"{leader_name}" : {"seeds" : ["http://10.0.0.1:9200","http://10.0.0.2:9200","http://10.0.0.3:9200"] ,"username": "test","password": "*****"}}}}}
Параметр | Обязательно | Тип | Описание |
|---|---|---|---|
leader_name | Yes | String | Пользовательское имя задачи конфигурации leader cluster, используемое для идентификации подключения leader cluster в последующей конфигурации синхронизации индексов. Разрешены только буквы (как заглавные, так и строчные), цифры, символы подчеркивания (_) и дефисы (-). Пробелы и специальные символы (например . # @) не допускаются. |
seeds | Yes | String | Список адресов для доступа к кластеру‑лидеру.
|
username | Yes | String | Имя пользователя кластера‑лидера. Этот параметр требуется только при включённом режиме безопасности для кластера‑лидера. |
password | Yes | String | Пароль кластера‑лидера. Этот параметр требуется только при включённом режиме безопасности для кластера‑лидера. |
Пример ответа:
{"acknowledged" : true, //Whether the operation is successful"persistent" : {"cluster" : {"remote" : {"rest" : {"leader1" : {"seeds" : ["http://10.0.0.1:9200","http://10.0.0.2:9200","http://10.0.0.3:9200"] ,"username": "test","password": "*****"}}}}},"transient" : { }}
GET _remote/rest/info
Пример ответа:
{"leader1" : {"connected" : true //The two clusters are connected.}}
Режим синхронизации | Синхронизация указанного индекса | Синхронизация соответствующих индексов |
|---|---|---|
Логика синхронизации | Укажите вручную индекс, который необходимо синхронизировать из кластера‑источника в кластер‑приёмник. | Укажите шаблон соответствия индексов. Для каждого индекса (включая любые новые индексы, создаваемые в будущем), который соответствует этому шаблону в кластере‑источнике, система автоматически создаёт задачу, которая синхронизирует его с кластером‑приёмником. |
Сценарий | Когда необходимо точно контролировать область синхронизации индексов (например, синхронизировать только критически важные индексы). | Когда требуется синхронизировать множество динамически создаваемых индексов (например, индексы, автоматически именуемые по метке времени или предопределённым правилам). |
Изменение политики синхронизации | Задачу синхронизации можно переотправить для того же индекса. Это позволяет изменить политику синхронизации. | После запуска задачи синхронизации политику синхронизации изменить нельзя. Можно только создать новую задачу синхронизации индекса, соответствующую шаблону, чтобы заменить существующую. Процедура: Delete an existing task > Stopping Index Synchronization > Create a new task. |
Ниже описано, как настроить задачу каждого типа:
Выполните следующую команду в кластере‑подписчике, чтобы создать задачу синхронизации одного индекса.
Параметр | Обязательно | Тип | Значение по умолчанию | Описание |
|---|---|---|---|---|
remote_cluster | Да | String | N/A | Имя задачи конфигурации кластера‑лидера. Значение должно соответствовать значению leader_name, установленному в Connecting the Leader and Follower Clusters, например, leader1. |
remote_index | Yes | String | N/A | Имя индекса, который будет синхронизирован в кластере‑лидере. Введите имя существующего индекса в кластере‑лидере, например, data_leader. |
local_index | Yes | String | N/A | Имя индекса в кластере‑подписчике после синхронизации из кластера‑лидера, например, data_follower. Вы можете оставить его таким же, как remote_index, но это не рекомендуется. Это связано с тем, что использование одинаковых имён индексов в кластерах‑лидере и‑подписчике может вызвать путаницу при управлении индексами. |
settings | No | Map | N/A | Настройки индекса, которые необходимо изменить, и их целевые значения после синхронизации с кластером‑подписчиком. Этот параметр позволяет гибко настраивать параметры индекса (например, количество реплик и интервал обновления), чтобы они соответствовали аппаратным ресурсам или требованиям сервиса в кластере‑подписчике. Если параметр не задан, по умолчанию будут использоваться настройки индекса лидирующего кластера. Ключ и значение:
Следующие параметры нельзя изменять: number_of_shards, version.created, uuid, creation_date и soft_deletes.enabled. |
settings_sync_enable | No | Boolean | false | Определяет, следует ли периодически синхронизировать настройки индекса из лидирующего кластера. Допустимые значения:
|
settings_sync_patterns | No | String | * (соответствует всем настройкам) | Настройки индекса Leader-cluster, которые будут синхронизированы в follower cluster. Укажите имена настроек, которые необходимо синхронизировать.
Ограничения:
|
settings_sync_exclude_patterns | No | String | Null (исключает none) | Настройки индекса leader‑cluster, не синхронизируемые с follower‑cluster. Укажите имена настроек, которые не будут синхронизированы.
Ограничения:
|
alias_sync_enable | No | Boolean | false | Нужно ли периодически синхронизировать псевдонимы индексов из лидирующего кластера. Значение может быть:
|
state_sync_enable | No | Boolean | false | Нужно ли периодически синхронизировать статус индекса из лидирующего кластера. Значение может быть:
|
Выполните следующую команду в кластере‑подписчике для создания задачи синхронизации индексов по шаблону:
PUT auto_sync/pattern/${pattern_name}{"remote_cluster": "{leader_name}","remote_index_patterns": "{index_name}","local_index_pattern": "{{remote_index}}-sync","apply_exist_index": true,"settings": {"number_of_replicas": 4},"settings_sync_enable": true,"settings_sync_patterns": ["*"],"settings_sync_exclude_patterns": ["index.routing.allocation.*"],"alias_sync_enable": true,"state_sync_enable": true}
Параметр | Обязательно | Тип | Значение по умолчанию | Описание |
|---|---|---|---|---|
pattern_name | Да | String | N/A | Имя шаблона, соответствующего имени индекса. |
remote_cluster | Да | String | N/A | Имя задачи конфигурации лидирующего кластера. Значение должно быть согласовано со значением leader_name, установленным в Connecting the Leader and Follower Clusters, например, leader1. |
remote_index_patterns | Yes | String | N/A | Шаблон сопоставления индексов leader-cluster.
|
local_index_pattern | Yes | String | N/A | Шаблон именования индексов в follower cluster после синхронизации из leader cluster. Поддерживается замена шаблона. Например, если этот параметр установлен в {{remote_index}}-sync, имя индекса log1 изменяется на log1-sync после синхронизации. ВНИМАНИЕ: Если переключение leader/follower, вероятно, произойдёт, установите этот параметр в {{remote_index}}, чтобы обеспечить использование одинаковых имён индексов в кластерах leader и follower. |
apply_exist_index | Yes | Boolean | true | Нужно ли синхронизировать существующие индексы из кластера leader. Значение может быть:
|
settings | No | Map | N/A | Настройки индекса, которые необходимо изменить, и их целевые значения после синхронизации в кластер follower. Этот параметр позволяет гибко настраивать параметры индекса (например, количество реплик и интервал обновления), чтобы они соответствовали аппаратным ресурсам или требованиям сервиса в кластере follower. Если не настроено, по умолчанию будут использованы параметры индекса кластера leader. Ключ и значение:
Следующие параметры нельзя изменить: number_of_shards, version.created, uuid, creation_date и soft_deletes.enabled. |
settings_sync_enable | No | Boolean | false | Определяет, следует ли периодически синхронизировать настройки индекса из ведущего кластера. Значение может быть:
|
settings_sync_patterns | No | String | * (соответствует всем настройкам) | Настройки индекса кластера‑лидера, которые будут синхронизированы с кластером‑фолловером. Укажите имена настроек, которые необходимо синхронизировать.
Ограничения:
|
settings_sync_exclude_patterns | No | String | Null (не исключает ничего) | Настройки индекса кластера‑лидера, которые не будут синхронизированы с кластером‑фолловером. Укажите имена настроек, которые не следует синхронизировать.
Ограничения:
|
alias_sync_enable | No | Boolean | false | Определяет, следует ли периодически синхронизировать псевдонимы индексов из leader cluster. Значение может быть:
|
state_sync_enable | No | Boolean | false | Определяет, следует ли периодически синхронизировать статус индекса из ведущего кластера. Допустимые значения:
|
После включения синхронизации индекс в кластере‑подписчике становится только для чтения. Синхронизация выполняется периодически для обеспечения согласованности данных. Интервал синхронизации по умолчанию составляет 30 секунд. Чтобы изменить его, см. Changing the Index Synchronization Interval.
Выполните следующую команду в кластере‑подписчике, чтобы получить статус синхронизации указанного индекса:
GET {index_name}/sync_stats
Пример вывода приведён ниже:
{"indices" : {"data1_follower" : {"shards" : {"0" : [{"primary" : false, // Whether it is a primary shard"total_synced_times" : 27, // Total synchronization times"total_empty_times" : 25, // Total number of times when no data is synchronized between the leader and follower clusters because they have identical shards and data"total_synced_files" : 4, // Number of synchronized files"total_synced_bytes" : 3580, // Total size of synchronized files"total_paused_nanos" : 0, //Duration of synchronization pauses due to traffic throttling"total_paused_times" : 0, //Number of synchronization pauses due to traffic throttling"current" : {"files_count" : 0, //Number of files that are being synchronized"finished_files_count" : 0, //Number of files that have been synchronized"bytes" : 0, //Size of files that are being synchronized"finished_bytes" : 0 //Size of files that have been synchronized}},{"primary" : true, // Whether it is a primary shard"total_synced_times" : 28, // Total synchronization times"total_empty_times" : 26, // Total number of times when no data is synchronized between the leader and follower clusters because they have identical shards and data"total_synced_files": 20, // Number of synchronized files"total_synced_bytes": 17547, // Total size of synchronized files"total_paused_nanos" : 0, //Duration of synchronization pauses due to traffic throttling"total_paused_times" : 0, //Number of synchronization pauses due to traffic throttling"current" : {"files_count" : 0, //Number of files that are being synchronized"finished_files_count" : 0, //Number of files that have been synchronized"bytes" : 0, //Size of files that are being synchronized"finished_bytes" : 0 //Size of files that have been synchronized}}]}}}}
По умолчанию в архитектуре разделения чтения/записи система определяет необходимость синхронизации metadata на основе количества документов в индексах ведущего кластера. Если ведущий кластер только обновляет существующие документы, но количество документов остаётся неизменным, эти обновления не будут синхронизированы в кластер‑подписчик.
Для принудительной синхронизации метаданных индекса из лидирующего кластера в кластер‑подписчик в каждом цикле синхронизации (даже если количество документов остаётся прежним) выполните следующую команду:
PUT _cluster/settings{"persistent": {"remote_sync.force_synchronize": true}}
Вы можете выполнять запросы и удалять существующие задачи синхронизации индексов по шаблону.
GET auto_sync/pattern
GET auto_sync/pattern/{pattern_name}
Пример ответа:
{"patterns" : [{"name" : "pattern1","pattern" : {"remote_cluster" : "leader","remote_index_patterns" : ["log*"],"local_index_pattern" : "{{remote_index}}-sync","settings" : { }}}]}
Удаление задачи синхронизации индексов по шаблону только предотвращает создание новых задач синхронизации для совпадающих индексов. Это не останавливает уже созданные задачи синхронизации. Чтобы остановить эти задачи, выполните вручную Stopping Index Synchronization.
DELETE auto_sync/pattern/{pattern_name}
GET auto_sync/pattern
Интервал синхронизации индекса между лидирующим и кластером‑подписчиком по умолчанию составляет 30 секунд. Чтобы изменить его для указанного индекса, выполните следующую команду:
PUT {index_name}/_settings{"index.remote_sync.sync_interval": "2s"}
Параметр | Тип | Значение по умолчанию | Описание |
|---|---|---|---|
index_name | String | N/A | Указывает один или несколько индексов.
|
index.remote_sync.sync_interval | String | 30s (recommended) | Интервал синхронизации индекса. Формат значения: число + единица измерения
Минимальное значение: 1s Вы можете уменьшить этот интервал, если приоритетом является своевременность данных, но это увеличит нагрузку на CPU кластера. |
Вы можете изменить скорость синхронизации данных между лидирующим и ведомым кластерами, настроив некоторые параметры уровня кластера.
Ниже приведён пример:
PUT _cluster/settings{"persistent": {"remote_sync.chunk_size": "2MB","remote_sync.max_concurrent_file_chunks": 20,"remote_sync.max_bytes_per_sec": "100MB"}}
Parameter | Type | Default Value | Description |
|---|---|---|---|
remote_sync.chunk_size | String | 1MB | Размер отдельного фрагмента для синхронизации индекса. Формат значения: число + единица измерения
Минимальное значение: 1 MB (значение ниже этого снижает эффективность) |
remote_sync.max_concurrent_file_chunks | Integer | 10 | Максимальное количество фрагментов документов, синхронизируемых одновременно на одном узле. Диапазон значений: от 1 до 100. Установите этот параметр, исходя из доступной пропускной способности узла и ресурсов CPU. |
remote_sync.max_bytes_per_sec | String | 40MB | Максимальный объём данных, передаваемых в секунду на одном узле во время синхронизации. Вы можете установить этот параметр, чтобы предотвратить исчерпание сетевой пропускной способности задачами синхронизации данных. Формат значения: число + единица измерения
Значение 0 указывает отсутствие ограничения. Когда нагрузка запросов вашего кластера низка, вы можете увеличить значение, но это может увеличить сетевую нагрузку. |
Выполните следующую команду в follower cluster, чтобы немедленно остановить задачу синхронизации отдельного индекса:
PUT {index_name}/stop_remote_sync
После выполнения этой команды:
Остановить Index synchronization нельзя, пока для индекса создаётся snapshot. Чтобы остановить синхронизацию, необходимо дождаться завершения создания snapshot.
Когда leader cluster выходит из строя, вы можете выполнить leader/follower switchover, чтобы follower cluster взял на себя обслуживание и обеспечить непрерывность сервиса. Чтобы это происходило плавно и гарантировать согласованность данных, используйте одинаковые имена индексов в leader и follower кластерах при настройке Index synchronization.
Выполните следующую команду в follower cluster, чтобы проверить задачи синхронизации индексов, соответствующие шаблону:
DELETE auto_sync/pattern/{pattern_name}
Выполните следующую команду в кластере follower, чтобы остановить задачи синхронизации отдельных индексов для указанных индексов:
PUT */stop_remote_sync