配置OpenSearch集群读写分离
随着业务规模扩大,数据量和访问量呈指数级增长,单一集群同时处理数据写入和查询请求的“读写一体”架构逐渐暴露出资源争抢、集群负载过载等问题。为了解决这些问题,CSS服务提供了OpenSearch读写分离功能。
OpenSearch读写分离架构通过主集群和从集群的协作实现。具备如下特点与优势:
- 解耦读写压力:主集群专注写入,提升写入效率;从集群专注查询。支持高并发查询扩展。消除资源争抢,降低峰值负载。
- 弹性扩展能力:独立横向扩展,读/写集群可单独扩容。支持跨地域部署能力。
- 数据一致性保障:低时延的实时同步机制。支持仅同步增量数据。
功能介绍
OpenSearch读写分离的核心业务流程:
- 业务数据写入。用户请求写入数据,主集群处理写入操作。
- 数据同步。
- 查询处理。用户输入查询请求,从集群处理查询,返回结果。
如图2所示,介绍了读写分离特性的应用场景。
- 日常读写分离(图左):主集群承担写入任务,从集群承担查询任务,分离读写压力。
- 故障主从切换(图右):主集群故障时,从集群升级为新的主集群,提供写入和查询服务,避免业务中断。操作流程请参见案例:主从切换。
介绍视频
约束限制
- OpenSearch集群仅2.19.0版本支持读写分离功能。
- 主集群和从集群的版本必须保持一致,否则可能导致服务异常。
前提条件
已创建两个版本一致的OpenSearch集群,一个作为主集群,另一个作为从集群。从集群必须能访问主集群的REST接口(默认端口为9200)。
登录OpenSearch Dashboards
登录OpenSearch Dashboards进入命令执行页面。OpenSearch集群支持多种客户端访问,本文仅以CSS服务集成的OpenSearch Dashboards为例介绍配置指导。
- 登录云搜索服务管理控制台。
- 在左侧导航栏,选择“集群管理 > OpenSearch”。
- 在集群列表,选择目标集群,单击操作列的“Dashboards”,登录OpenSearch Dashboards。
- 在OpenSearch Dashboards左侧导航栏选择“Dev Tools”,进入操作页面。
控制台左侧是命令输入框,其右侧的三角形图标为执行按钮,右侧区域则显示执行结果。
连接主集群和从集群
- 执行如下命令,在从集群中配置主集群的连接信息,以便从集群能够从主集群同步数据。
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": "*****" } } } } }表1 连接主从集群的参数说明 参数
是否必选
类型
说明
leader_name
是
String
主集群配置任务的自定义名称,用于后续索引同步配置中标识主集群连接信息。
允许大小写字母、数字、下划线(_)、连字符(-)。不能包含特殊字符(如空格、.、#、@)。
seeds
是
String
主集群的访问地址列表。
- 非安全模式的集群或安全模式+HTTP协议的集群格式:http://xx.xx.xx.xx:9200
- 安全模式+HTTPS协议的集群格式:https://xx.xx.xx.xx:9200
username
是
String
主集群的用户名,仅主集群是安全模式的集群时才需要配置。
password
是
String
主集群的密码,仅主集群是安全模式的集群时才需要配置。
返回示例:
{ "acknowledged" : true, // 是否成功 "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 //表示连接正常 } }
配置索引同步
- 创建索引同步任务。有指定索引同步和匹配索引同步2种方式。
表2 同步方式对比 同步方式
指定索引同步
匹配索引同步
同步逻辑
手动指定具体索引名称,从主集群同步到从集群。仅同步明确列出的索引。
创建基于匹配模式的索引同步任务,当主集群中存在符合匹配模式的索引(包括后续新建的索引)时,系统会自动为每个匹配的索引生成一个指定索引同步任务,从主集群同步到从集群。
适用场景
需精确控制索引同步范围(如仅同步关键业务索引)的场景。
索引动态创建(如按时间、业务规则命名)、需批量同步大量索引的场景。
同步策略修改
启动同步任务后,支持对同一索引再次下发同步任务,以修改同步策略。
启动同步任务后,不支持修改同步策略,只能新建匹配索引同步任务替换历史匹配索引同步任务。操作流程:删除已创建的匹配索引同步任务 > 停止索引同步 > 创建新的匹配索引同步任务。
两种方式的配置指导如下:
- 指定索引同步
在从集群执行如下命令,创建指定索引同步任务。
PUT start_remote_sync { "remote_cluster": "{leader_name}", "remote_index": "{index_name_leader}", "local_index": "{index_name_follower}", "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 }表3 指定索引同步的参数说明 参数
是否必选
类型
默认值
说明
remote_cluster
是
String
无
主集群配置任务的名称。
与连接主集群和从集群时设置的“leader_name”保持一致,如“leader1”。
remote_index
是
String
无
主集群待同步的索引名称。
指定主集群已有的索引名称,如“data_leader”。
local_index
是
String
无
主集群索引同步到从集群后的索引名称。如“data_follower”。
支持和“remote_index”保持一致,但不推荐,因为主从集群索引名称重复可能导致索引管理混乱。
settings
否
Map
无
主集群索引同步到从集群时需要修改的索引settings配置及其目标值。
通过此参数,用户可灵活调整从集群索引的配置(如副本数、刷新间隔等),以适配从集群的硬件资源或业务需求。如果未配置此参数,系统将默认从集群的索引settings配置和主集群一致。
键值对说明:
- key:settings配置项名称(如number_of_replicas)。
- value:修改后的配置值(如4)。
以下settings配置不支持修改:number_of_shards、version.created、uuid、creation_date、soft_deletes.enabled。
settings_sync_enable
否
Boolean
false
是否周期性同步主集群索引的settings配置。
取值范围:
- true:开启同步。当主集群索引的settings配置更新时,从集群同步更新。
- false:关闭同步。当主集群索引的settings配置更新时,从集群不会同步更新,维持首次同步的配置。
settings_sync_patterns
否
String
*(匹配所有配置)
待同步的主集群索引的settings配置。
指定要同步的settings配置名称:
- 单个配置:直接输入settings配置名称(如“index.max_regex_length”)。
- 多个配置:用英文逗号分隔多个settings配置名称(如“index.max_regex_length,index.max_refresh_listeners”)。
- 通配符:支持通配符 *(匹配任意字符),如“index*”表示匹配所有以index开头的settings配置。
约束限制:
- 仅当“settings_sync_enable”为“true”时,本参数配置才生效。
- 当同一个配置项同时在“settings”和“settings_sync_patterns”中配置时,“settings_sync_patterns”的配置将优先生效,即从集群会直接同步主集群的当前配置项。
- 以下settings配置不支持同步到从集群:index.number_of_shards、index.version.created、index.uuid、index.creation_date、index.history.uuid、index.number_of_replicas、index.auto_expand_replicas、index.version.upgraded
settings_sync_exclude_patterns
否
String
无(不排除任何设置)
不需要同步的主集群索引的settings配置。
指定不同步的settings配置名称:
- 单个配置:直接输入settings配置名称(如“index.max_regex_length”)。
- 多个配置:用英文逗号分隔多个settings配置名称(如“index.max_regex_length,index.max_refresh_listeners”)。
- 通配符:支持通配符 *(匹配任意字符),如“index*”表示匹配所有以index开头的settings配置。
约束限制:
- 仅当“settings_sync_enable”为“true”时,本参数配置才生效。
- 如果同时配置了“settings_sync_patterns”和“settings_sync_exclude_patterns”,则两者差集的settings配置才会被同步到从集群。
- 冷索引同步时需要从集群包含冷数据节点,以确保冷索引能够成功同步。当从集群无冷数据节点,且目标同步索引含冷索引时,会导致同步失败。需通过以下配置将冷索引同步至从集群的数据节点(此时从集群的该索引不再是冷索引),以确保同步成功。
"settings_sync_exclude_patterns": ["index.routing.allocation.require.box_type"]
alias_sync_enable
否
Boolean
false
是否周期性同步主集群的索引别名。
取值范围:
- true:从集群周期性同步主集群的索引别名。
- false:从集群不同步主集群的索引别名。
state_sync_enable
否
Boolean
false
是否周期性同步主集群的索引状态。
取值范围:
- true:从集群周期性同步主集群的索引状态。
- 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 }表4 匹配索引同步的参数说明 参数
是否必选
类型
默认值
说明
pattern_name
是
String
无
匹配索引同步任务的名字,用于区分匹配模式。
remote_cluster
是
String
无
主集群配置任务的名称。
与连接主集群和从集群时设置的“leader_name”保持一致,如“leader1”。
remote_index_patterns
是
String
无
主集群待同步的索引名称的匹配模式。
- 单个索引:直接输入索引名称(如“my_index”)。
- 多个索引:用英文逗号分隔多个索引(如“my_index1,my_index2”)。
- 通配符:支持通配符 *(匹配任意字符),如“myindex*”表示匹配所有以myindex开头的索引。
local_index_pattern
是
String
无
主集群索引同步到从集群的索引名称。
支持模板替换。如取值为“{{remote_index}}-sync”时,待同步索引名称为“log1”,同步过来的索引名称为“log1-sync”。
注意:当业务场景涉及主从集群切换时,本参数值请配置为“{{remote_index}}”,以确保主从集群使用相同的索引名称。
apply_exist_index
是
Boolean
true
是否同步主集群的历史索引。
取值范围:
- true:系统会同步满足匹配模式的历史索引(主集群已存在的索引)和新建索引(主集群后续创建的索引)。
- false:系统仅同步满足匹配模式的新建索引(主集群后续创建的索引),不包含已存在的历史索引。历史索引可能因未同步导致数据不一致,需结合业务场景谨慎配置。
settings
否
Map
无
主集群索引同步到从集群时需要修改的索引settings配置及其目标值。
通过此参数,用户可灵活调整从集群索引的配置(如副本数、刷新间隔等),以适配从集群的硬件资源或业务需求。如果未配置此参数,系统将默认从集群的索引settings配置和主集群一致。
键值对说明:
- key:settings配置项名称(如number_of_replicas)。
- value:修改后的配置值(如4)。
以下settings配置不支持修改:number_of_shards、version.created、uuid、creation_date、soft_deletes.enabled。
settings_sync_enable
否
Boolean
false
是否周期性同步主集群索引的settings配置。
取值范围:
- true:开启同步。当主集群索引的settings配置更新时,从集群同步更新。
- false:关闭同步。当主集群索引的settings配置更新时,从集群不会同步更新,维持首次同步的配置。
settings_sync_patterns
否
String
*(匹配所有配置)
待同步的主集群索引的settings配置。
指定要同步的settings配置名称:
- 单个配置:直接输入settings配置名称(如“index.max_regex_length”)。
- 多个配置:用英文逗号分隔多个settings配置名称(如“index.max_regex_length,index.max_refresh_listeners”)。
- 通配符:支持通配符 *(匹配任意字符),如“index*”表示匹配所有以index开头的settings配置。
约束限制:
- 仅当“settings_sync_enable”为“true”时,本参数配置才生效。
- 当同一个配置项同时在“settings”和“settings_sync_patterns”中配置时,“settings_sync_patterns”的配置将优先生效,即从集群会直接同步主集群的当前配置项。
- 以下settings配置不支持同步到从集群:index.number_of_shards、index.version.created、index.uuid、index.creation_date、index.history.uuid、index.number_of_replicas、index.auto_expand_replicas、index.version.upgraded
settings_sync_exclude_patterns
否
String
无(不排除任何设置)
不需要同步的主集群索引的settings配置。
指定不同步的settings配置名称:
- 单个配置:直接输入settings配置名称(如“index.max_regex_length”)。
- 多个配置:用英文逗号分隔多个settings配置名称(如“index.max_regex_length,index.max_refresh_listeners”)。
- 通配符:支持通配符 *(匹配任意字符),如“index*”表示匹配所有以index开头的settings配置。
约束限制:
- 仅当“settings_sync_enable”为“true”时,本参数配置才生效。
- 如果同时配置了“settings_sync_patterns”和“settings_sync_exclude_patterns”,则两者差集的settings配置才会被同步到从集群。
- 冷索引同步时需要从集群包含冷数据节点,以确保冷索引能够成功同步。当从集群无冷数据节点,且目标同步索引含冷索引时,会导致同步失败。需通过以下配置将冷索引同步至从集群的数据节点(此时从集群的该索引不再是冷索引),以确保同步成功。
"settings_sync_exclude_patterns": ["index.routing.allocation.require.box_type"]
alias_sync_enable
否
Boolean
false
是否周期性同步主集群的索引别名。
取值范围:
- true:从集群周期性同步主集群的索引别名。
- false:从集群不同步主集群的索引别名。
state_sync_enable
否
Boolean
false
是否周期性同步主集群的索引状态。
取值范围:
- true:从集群周期性同步主集群的索引状态。
- false:从集群不同步主集群的索引状态。
- 指定索引同步
- 查看同步状态,确认索引同步配置成功。
开启索引同步后,从集群的索引会变为只读状态,并且定时与主集群索引同步,以确保数据的一致性和可靠性。同步周期默认30秒,如果需要修改请参见修改索引同步周期。
在从集群执行如下命令,获取指定索引的同步状态。
GET {index_name}/sync_stats返回示例如下:
{ "indices" : { "data1_follower" : { "shards" : { "0" : [ { "primary" : false, // 是否是主分片 "total_synced_times" : 27, // 同步次数总和 "total_empty_times" : 25, // 无需同步文件的同步次数总和,即主集群分片和从集群分片数据一致,无需同步的次数 "total_synced_files" : 4, // 已同步文件数 "total_synced_bytes" : 3580, // 已同步文件总大小 "total_paused_nanos" : 0, // 因限流导致的暂停同步的时长 "total_paused_times" : 0, // 因限流导致的暂停同步的次数 "current" : { "files_count" : 0, // 当前正在同步的文件个数 "finished_files_count" : 0, // 当前正在同步的已完成文件个数 "bytes" : 0, // 当前正在同步的文件大小 "finished_bytes" : 0 // 当前正在同步的已完成文件个数 } }, { "primary" : true, // 是否是主分片 "total_synced_times" : 28, // 同步次数总和 "total_empty_times" : 26, // 无需同步文件的同步次数总和,即主集群分片和从集群分片数据一致,无需同步的次数 "total_synced_files" : 20, // 已同步文件数 "total_synced_bytes" : 17547, // 已同步文件总大小 "total_paused_nanos" : 0, // 因限流导致的暂停同步的时长 "total_paused_times" : 0, // 因限流导致的暂停同步的次数 "current" : { "files_count" : 0, // 当前正在同步的文件个数 "finished_files_count" : 0, // 当前正在同步的已完成文件个数 "bytes" : 0, // 当前正在同步的文件大小 "finished_bytes" : 0 // 当前正在同步的已完成文件个数 } } ] } } } } - 开启强制索引同步。
读写分离架构默认根据主集群索引的文档数是否发生变化来决定是否同步元数据。当主集群仅对文档进行更新且文档数不变时,更改不会同步到从集群。
如果需要在每个同步周期强制从集群同步主集群的索引元数据(即使文档数未变化),可以执行以下命令:
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" : { } } } ] } - 在从集群执行如下命令,查询匹配索引同步任务列表。
- 删除已创建的匹配索引同步任务。
删除匹配索引同步任务只会停止同步后续新建的符合匹配模式的索引,已建立的索引同步任务不会因匹配索引同步任务的删除而自动终止,如需停止这些任务,需手动执行停止索引同步。
- 在从集群执行如下命令,删除指定匹配索引同步任务。
DELETE auto_sync/pattern/{pattern_name} - 执行如下命令,查询匹配索引同步任务列表,确认任务已被成功删除。
GET auto_sync/pattern
- 在从集群执行如下命令,删除指定匹配索引同步任务。
修改索引同步周期
主从集群的索引同步周期默认为30秒,如需修改指定索引的同步周期,可以执行以下命令:
PUT {index_name}/_settings
{
"index.remote_sync.sync_interval": "2s"
}
|
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
index_name |
String |
无 |
指定索引名称。
|
|
index.remote_sync.sync_interval |
String |
30s(建议保持默认值) |
指定索引的同步周期。 取值格式:数字+单位
最小值: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"
}
}
|
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
remote_sync.chunk_size |
String |
1MB |
指定同步时单个索引的数据块大小。 取值格式:数字+单位
最小值:1MB(低于此值可能导致效率下降) |
|
remote_sync.max_concurrent_file_chunks |
Integer |
10 |
指定同步时单个节点允许的最大并发数据块数量。 取值范围:1~100 建议根据节点带宽和CPU资源调整。 |
|
remote_sync.max_bytes_per_sec |
String |
40MB |
指定同步时单个节点的每秒最大传输速率。避免同步任务占满网络带宽。 取值格式:数字+单位
0表示无带宽限制。 当集群查询流量较低时,可适当调高数值,但可能增加网络负载。 |
停止索引同步
在从集群执行如下命令停止指定索引的同步任务(该命令执行后,同步任务将立即停止):
PUT {index_name}/stop_remote_sync
命令执行成功后:
- 主集群上对该索引的后续修改将不会被同步到从集群。
- 从集群上该索引的只读状态将被解除,允许在从集群写入新数据。
案例:主从切换
当主集群出现故障时,支持通过主从切换机制保障业务连续性。如果业务场景涉及主从集群切换,建议在配置索引同步时保持主从集群的索引名称一致,以确保切换过程的平滑性和数据一致性。
