As business expands, and data volumes and access requests grow exponentially, a monolithic architecture where a single cluster handles both write and query requests faces typical challenges like resource contention and overload. To address these challenges, CSS introduces read/write splitting between Elasticsearch clusters.
Elasticsearch read/write splitting works by having leader and follower clusters collaborate together. The feature delivers the following benefits:
Figure 1 Read/write splitting

How read/write splitting between Elasticsearch clusters works:
The leader synchronizes data changes to the follower through a REST API. Two synchronization methods are supported:
Figure 2 illustrates how read/write splitting works.
Figure 2 How read/write splitting works

Two Elasticsearch clusters of the same version have been created. One functions as the leader, and the other the follower. The follower cluster must be able to access the REST API (default port: 9200) of the leader cluster.
Log in to Kibana and go to the command execution page. Elasticsearch clusters support multiple access methods. This topic uses Kibana as an example to describe the operation procedures.
The left part of the console is the command input box, and the triangle icon in its upper-right corner is the execution button. The right part shows the execution result.
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": "*****"}}}}}
Parameter | Mandatory | Type | Description |
|---|---|---|---|
leader_name | Yes | String | Custom name of the leader cluster configuration task, used to identify the leader cluster connection in subsequent index synchronization configuration. Only letters (both uppercase and lowercase), digits, underscores (_), and hyphens (-) are allowed. Spaces and special characters (such as . # @) are not allowed. |
seeds | Yes | String | List of addresses for accessing the leader cluster.
|
username | Yes | String | Username of the leader cluster. This parameter is required only when security mode is enabled for the leader cluster. |
password | Yes | String | Password of the leader cluster. This parameter is required only when security mode is enabled for the leader cluster. |
Example response:
{"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
Example response:
{"leader1" : {"connected" : true //The two clusters are connected.}}
Synchronization Mode | Synchronizing a specified index | Synchronizing matched indexes |
|---|---|---|
Synchronization Logic | Manually specify an index that you wish to synchronize from the leader cluster to the follower. | Specify an index matching pattern. For each index (including any new indexes created in the future) that matches this pattern in the leader cluster, the system automatically creates a task that will synchronize it to the follower cluster. |
Scenario | When you want to precisely control the index synchronization scope (for example, to synchronize mission-critical indexes only) | When you want to synchronize many dynamically created indexes (for example, indexes automatically named by timestamp or predefined rules). |
Synchronization Policy Modification | A synchronization task can be re-delivered for the same index. That is when you can modify the synchronization policy. | After a synchronization task is started, the synchronization policy can no longer be modified. You can only create a new pattern-matching index synchronization task to replace an existing one. Procedure: Delete an existing task > Stopping Index Synchronization > Create a new task. |
The following describes how to configure a task of each type:
Run the following command in the follower cluster to create a single-index synchronization task.
Parameter | Mandatory | Type | Default Value | Description |
|---|---|---|---|---|
remote_cluster | Yes | String | N/A | The name of the leader cluster configuration task. The value must be consistent with the value of leader_name set in Connecting the Leader and Follower Clusters, for example, leader1. |
remote_index | Yes | String | N/A | The name of the index to be synchronized in the leader cluster. Enter the name of an existing index in the leader cluster, for example, data_leader. |
local_index | Yes | String | N/A | The name of the index in the follower cluster after synchronization from the leader, for example, data_follower. You can keep it the same as remote_index, but doing so is not recommended. This is because using identical names for indexes in the leader and follower clusters can lead to confusion during index management. |
settings | No | Map | N/A | Index settings to be modified and their target values after synchronization to the follower cluster. This parameter allows you to flexibly configure index settings (such as the number of replicas and refresh interval) to match the hardware resources or service requirements in the follower cluster. If not configured, the index settings of the leader cluster will be used by default. Key and value:
The following settings cannot be modified: number_of_shards, version.created, uuid, creation_date, and soft_deletes.enabled. |
settings_sync_enable | No | Boolean | false | Whether to periodically synchronize index settings from the leader cluster. The value can be:
|
settings_sync_patterns | No | String | * (matches all settings) | Leader-cluster index settings to be synchronized to the follower cluster. Specify the names of the settings to be synchronized.
Constraints:
|
settings_sync_exclude_patterns | No | String | Null (excludes none) | Leader-cluster index settings not to be synchronized to the follower cluster. Specify the names of the settings not to be synchronized.
Constraints:
|
alias_sync_enable | No | Boolean | false | Whether to periodically synchronize index aliases from the leader cluster. The value can be:
|
state_sync_enable | No | Boolean | false | Whether to periodically synchronize index status from the leader cluster. The value can be:
|
Run the following command in the follower cluster to create a pattern-matching index synchronization task:
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}
Parameter | Mandatory | Type | Default Value | Description |
|---|---|---|---|---|
pattern_name | Yes | String | N/A | The name of the index name matching pattern. |
remote_cluster | Yes | String | N/A | The name of the leader cluster configuration task. The value must be consistent with the value of leader_name set in Connecting the Leader and Follower Clusters, for example, leader1. |
remote_index_patterns | Yes | String | N/A | The leader-cluster index matching pattern.
|
local_index_pattern | Yes | String | N/A | Index naming pattern in the follower cluster after synchronization from the leader cluster. Template replacement is supported. For example, if this parameter is set to {{remote_index}}-sync, the index name log1 changes to log1-sync after synchronization. CAUTION: If leader/follower switchover is likely to happen, set this parameter to {{remote_index}} to ensure that the leader and follower clusters use identical index names. |
apply_exist_index | Yes | Boolean | true | Whether to synchronize existing indexes from the leader cluster. The value can be:
|
settings | No | Map | N/A | Index settings to be modified and their target values after synchronization to the follower cluster. This parameter allows you to flexibly configure index settings (such as the number of replicas and refresh interval) to match the hardware resources or service requirements in the follower cluster. If not configured, the index settings of the leader cluster will be used by default. Key and value:
The following settings cannot be modified: number_of_shards, version.created, uuid, creation_date, and soft_deletes.enabled. |
settings_sync_enable | No | Boolean | false | Whether to periodically synchronize index settings from the leader cluster. The value can be:
|
settings_sync_patterns | No | String | * (matches all settings) | Leader-cluster index settings to be synchronized to the follower cluster. Specify the names of the settings to be synchronized.
Constraints:
|
settings_sync_exclude_patterns | No | String | Null (excludes none) | Leader-cluster index settings not to be synchronized to the follower cluster. Specify the names of the settings not to be synchronized.
Constraints:
|
alias_sync_enable | No | Boolean | false | Whether to periodically synchronize index aliases from the leader cluster. The value can be:
|
state_sync_enable | No | Boolean | false | Whether to periodically synchronize index status from the leader cluster. The value can be:
|
After synchronization is enabled, the index in the follower cluster becomes read-only. Synchronization is performed periodically to ensure data consistency. The default synchronization interval is 30 seconds. For how to change it, see Changing the Index Synchronization Interval.
Run the following command in the follower cluster to obtain the synchronization status of a specified index:
GET {index_name}/sync_stats
An example output is as follows:
{"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}}]}}}}
By default, in a read/write splitting architecture, the system determines whether to synchronize metadata based on the number of documents in indexes in the leader cluster. If the leader cluster only updates existing documents and yet the number of documents remains unchanged, these updates will not be synchronized to the follower cluster.
To forcibly synchronize index metadata from the leader cluster to the follower cluster in each synchronization cycle (even if the number of documents remains the same), run the following command:
PUT _cluster/settings{"persistent": {"remote_sync.force_synchronize": true}}
You can query and delete existing pattern-matching index synchronization tasks.
GET auto_sync/pattern
GET auto_sync/pattern/{pattern_name}
Example response:
{"patterns" : [{"name" : "pattern1","pattern" : {"remote_cluster" : "leader","remote_index_patterns" : ["log*"],"local_index_pattern" : "{{remote_index}}-sync","settings" : { }}}]}
Deleting a pattern-matching index synchronization task only prevents new synchronization tasks from being created for matched indexes. It does not stop synchronization tasks that have already been created. To stop these tasks, manually perform Stopping Index Synchronization.
DELETE auto_sync/pattern/{pattern_name}
GET auto_sync/pattern
The default index synchronization interval between the leader and follower clusters is 30 seconds. To change it for a specified index, run the following command:
PUT {index_name}/_settings{"index.remote_sync.sync_interval": "2s"}
Parameter | Type | Default Value | Description |
|---|---|---|---|
index_name | String | N/A | Specifies one or more indexes.
|
index.remote_sync.sync_interval | String | 30s (recommended) | The index synchronization interval. Value format: number + unit
Minimum value: 1s You may reduce this interval if the timeliness of data is prioritized, but doing so will increase the cluster's CPU load. |
You can change the data synchronization speed between the leader and follower clusters by configuring some cluster-level settings.
The following is an example:
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 | The size of a single chunk for index synchronization. Value format: number + unit
Minimum value: 1 MB (a value lower than this impacts efficiency) |
remote_sync.max_concurrent_file_chunks | Integer | 10 | Maximum number of document chunks synchronized concurrently on a single node. Value range: 1 to 100. Set this parameter based on the node bandwidth and CPU resources available. |
remote_sync.max_bytes_per_sec | String | 40MB | Maximum size of data transmitted per second on a single node during synchronization. You can set this parameter to prevent data synchronization tasks from exhausting the network bandwidth. Value format: number + unit
The value 0 indicates no limit. When your cluster's query traffic is low, you can increase the value, but doing so may increase the network load. |
Run the following command in the follower cluster to stop a single-index synchronization task immediately:
PUT {index_name}/stop_remote_sync
After this command is executed:
Index synchronization cannot be stopped when a snapshot is being created for the index. To stop synchronization, you must wait until snapshot creation is complete.
When the leader cluster becomes faulty, you can perform a leader/follower switchover to have the follower cluster take over to ensure service continuity. To allow this to happen seamlessly and ensure data consistency, use identical index names between the leader and follower clusters when configuring index synchronization.
Run the following command in the follower cluster to check for pattern-matching index synchronization tasks:
DELETE auto_sync/pattern/{pattern_name}
Run the following command in the follower cluster to stop single-index synchronization tasks for specified indexes:
PUT */stop_remote_sync