Elasticsearch双向跨集群复制实现灾备恢复教程
elasticsearch 项目地址: https://gitcode.com/gh_mirrors/elas/elasticsearch
概述
在现代分布式系统中,确保数据的高可用性和灾难恢复能力至关重要。Elasticsearch提供的跨集群复制(CCR)功能是实现这一目标的有效手段。本文将详细介绍如何基于双向CCR在两个Elasticsearch集群之间建立灾难恢复机制,确保在一个集群发生故障时,系统能够自动切换到另一个集群,并在故障恢复后实现数据同步。
核心概念理解
在开始配置前,我们需要明确几个关键概念:
- 跨集群复制(CCR):允许将一个集群中的索引自动复制到另一个集群的功能
- 数据流(Data Stream):Elasticsearch中用于管理时序数据的高级抽象
- 领导者-追随者模式:在CCR中,原始数据的集群称为领导者(leader),接收复制的集群称为追随者(follower)
- 双向复制:两个集群互为领导者和追随者,实现数据的双向同步
环境准备
本教程假设您已经拥有两个Elasticsearch集群,分别命名为clusterA和clusterB。两个集群应该位于不同的地理位置或可用区,以实现真正的灾难恢复能力。
详细配置步骤
第一步:配置远程集群连接
在两个集群上分别设置远程集群连接信息:
// 在clusterA上执行
PUT _cluster/settings
{
"persistent": {
"cluster": {
"remote": {
"clusterB": {
"mode": "proxy",
"skip_unavailable": true,
"server_name": "clusterb.es.region-b.gcp.elastic-cloud.com",
"proxy_socket_connections": 18,
"proxy_address": "clusterb.es.region-b.gcp.elastic-cloud.com:9400"
}
}
}
}
}
// 在clusterB上执行
PUT _cluster/settings
{
"persistent": {
"cluster": {
"remote": {
"clusterA": {
"mode": "proxy",
"skip_unavailable": true,
"server_name": "clustera.es.region-a.gcp.elastic-cloud.com",
"proxy_socket_connections": 18,
"proxy_address": "clustera.es.region-a.gcp.elastic-cloud.com:9400"
}
}
}
}
}
关键参数说明:
skip_unavailable
: 设置为true允许在远程集群不可用时继续操作proxy_socket_connections
: 控制与远程集群的连接数,根据网络状况调整proxy_address
: 远程集群的代理地址
第二步:建立双向自动跟随模式
为了避免递归复制,必须设置排除模式:
// 在clusterA上执行
PUT /_ccr/auto_follow/logs-generic-default
{
"remote_cluster": "clusterB",
"leader_index_patterns": [
".ds-logs-generic-default-20*"
],
"leader_index_exclusion_patterns":"*-replicated_from_clustera",
"follow_index_pattern": "{{leader_index}}-replicated_from_clusterb"
}
// 在clusterB上执行
PUT /_ccr/auto_follow/logs-generic-default
{
"remote_cluster": "clusterA",
"leader_index_patterns": [
".ds-logs-generic-default-20*"
],
"leader_index_exclusion_patterns":"*-replicated_from_clusterb",
"follow_index_pattern": "{{leader_index}}-replicated_from_clustera"
}
重要注意事项:
- 自动跟随模式仅对新创建的索引生效,已有数据不会被自动复制
- 排除模式(
leader_index_exclusion_patterns
)是防止递归复制的关键 - 跟随索引模式(
follow_index_pattern
)只能包含小写字母
第三步:配置Logstash实现负载均衡
使用Logstash的负载均衡功能实现自动故障转移:
input {
generator{
message => 'Hello World'
count => 100
}
}
output {
elasticsearch {
hosts => [
"https://clustera.es.region-a.gcp.elastic-cloud.com:9243",
"https://clusterb.es.region-b.gcp.elastic-cloud.com:9243"
]
user => "logstash-user"
password => "same_password_for_both_clusters"
}
}
实现原理:
- 当两个集群都正常时,Logstash会自动将请求负载均衡到两个集群
- 当其中一个集群不可用时,所有请求会自动路由到另一个可用集群
- 集群恢复后,请求会自动重新平衡
最佳实践:
- 在两个集群上为Logstash使用相同的用户名和密码
- 考虑使用TLS加密连接确保安全性
- 根据实际业务需求调整input配置
故障转移与恢复流程
正常状态下的数据分布
当两个集群都正常运行时:
- 每个集群的原始数据流(
logs-generic-default
)包含约50%的文档 - 每个集群的复制数据流(
*-replicated_from_*
)包含来自另一个集群的50%文档 - 查询
logs*
将返回所有100个文档
模拟clusterA故障
- 停止clusterA服务
- 观察Logstash将所有流量自动重定向到clusterB
- 数据分布变化:
- clusterB的原始数据流文档数增加到150
- clusterA的数据保持不变(因为已停止)
操作建议:
- 将所有查询请求也重定向到clusterB
- 监控clusterB的性能指标,确保能够处理额外负载
恢复clusterA服务
- 重新启动clusterA
- 观察系统自动将clusterB新增的数据复制回clusterA
- Logstash自动恢复负载均衡到两个集群
- 最终数据分布:
- clusterA: 50原始文档 + 150复制文档
- clusterB: 150原始文档 + 50复制文档
数据更新与删除操作
在双向复制环境中,更新和删除操作需要特别注意:
-
定位文档位置:首先确定文档所在的原始索引
GET logs-generic-default*/_search?filter_path=hits.hits._index { "query": { "match": { "event.sequence": "97" } } }
-
在正确的集群上执行操作:
- 如果文档在
*-replicated_from_clustera
中,在clusterA上操作 - 如果文档在
*-replicated_from_clusterb
中,在clusterB上操作 - 如果文档在原始索引中,在当前集群上操作
- 如果文档在
-
执行更新操作示例:
POST logs-generic-default/_update_by_query { "query": { "match": { "event.sequence": "97" } }, "script": { "source": "ctx._source.event.original = params.new_event", "lang": "painless", "params": { "new_event": "FOOBAR" } } }
重要警告:如果软删除在复制前被合并,可能会导致复制失败。确保适当配置index.soft_deletes.retention_lease.period
参数。
总结与最佳实践
- 监控与告警:建立完善的监控系统,及时发现集群故障
- 定期测试:定期模拟故障场景,验证灾备方案有效性
- 容量规划:确保备用集群有足够资源处理全部负载
- 文档策略:制定清晰的文档更新操作流程,避免数据不一致
- 性能优化:根据网络状况调整
proxy_socket_connections
参数
通过本文介绍的配置,您可以建立一个健壮的双向灾备系统,确保在单个集群故障时业务连续性,并在故障恢复后自动同步数据。这种方案特别适合对数据可用性要求高的生产环境。
elasticsearch 项目地址: https://gitcode.com/gh_mirrors/elas/elasticsearch
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考