Elasticsearch - 跨集群复制(CCR) Elasticsearch 数据同步高级方案
摘要 Elasticsearch跨集群复制(CCR)是一种企业级数据同步方案,支持近实时、自动化的索引数据复制,适用于灾备、地理就近访问和读写分离等场景。本文深入解析CCR原理、配置步骤及Java客户端实现,对比Logstash等同步方案的优劣,并通过Docker搭建双集群演示完整流程。 核心要点 功能特性:基于事务日志的增量同步,秒级延迟,Follower集群只读 典型场景:异地容灾、全球多活、

👋 大家好,欢迎来到我的技术博客!
💻 作为一名热爱 Java 与软件开发的程序员,我始终相信:清晰的逻辑 + 持续的积累 = 稳健的成长。
📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。
🎯 本文将围绕ElasticSearch这个话题展开,希望能为你带来一些启发或实用的参考。
🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获!
文章目录
- Elasticsearch - 跨集群复制(CCR):Elasticsearch 数据同步高级方案 🌐🔁
-
- 什么是跨集群复制(CCR)?核心概念解析 🧩
- CCR vs 其他数据同步方案:为何选择 CCR?⚖️
- CCR 工作原理:数据如何从 Leader 流向 Follower?📡
- 环境准备:搭建两个 Elasticsearch 集群 🏗️
- 配置跨集群复制:四步走 🚶♂️
- Java 客户端管理 CCR:自动化运维示例 ☕
- 高级配置:调优 CCR 性能与可靠性 ⚙️
- 监控与故障排查:确保 CCR 健康运行 👁️
- 架构实战:构建多活读写分离系统 🌍
- CCR 与索引生命周期管理(ILM)集成 🔄
- 安全与权限控制:生产环境必备 🔐
- 替代方案思考:何时不使用 CCR?🤔
- 总结:构建弹性、智能的数据同步体系 🧠
Elasticsearch - 跨集群复制(CCR):Elasticsearch 数据同步高级方案 🌐🔁
在现代分布式系统中,数据的高可用性、灾难恢复能力与低延迟访问已成为核心需求。当你的 Elasticsearch 集群承载着关键业务日志、实时交易数据或用户行为分析时,单点故障或区域性中断可能带来不可估量的损失。
如何确保数据在多个地理位置之间安全、高效、一致地同步?如何实现跨数据中心的读写分离?如何在不影响主集群性能的前提下完成异地灾备?
跨集群复制(Cross-Cluster Replication, CCR)正是 Elasticsearch 为此类场景提供的企业级解决方案。作为 Elastic Stack 的高级功能之一,CCR 允许你将一个索引(Leader)的数据近乎实时地自动复制到另一个远程集群(Follower),构建出灵活、可靠、可扩展的数据同步架构。
本文将深入剖析 Elasticsearch CCR 的原理、配置、使用场景与最佳实践。我们将:
- 详解 CCR 的工作机制与数据流;
- 演示如何通过 Kibana 和 REST API 配置跨集群复制;
- 提供完整的 Java 客户端代码示例,实现自动化管理;
- 对比 CCR 与其他同步方案(如 Logstash、Snapshot)的优劣;
- 分析网络、安全、性能等生产环境关键考量;
- 构建一个真实的多活读写分离架构案例。
无论你是 SRE、DevOps 工程师、后端开发者,还是正在规划全球部署的数据平台架构师,本文都将为你提供一套可落地、可运维、可监控的 CCR 实战指南。让我们一起揭开 Elasticsearch 高级数据同步的神秘面纱!🔐🚀
什么是跨集群复制(CCR)?核心概念解析 🧩
跨集群复制(CCR)是 Elasticsearch 自 6.5 版本引入、并在 7.x/8.x 中持续增强的一项功能。它允许你将一个索引(称为 Leader Index)中的数据自动、增量、近实时地复制到另一个集群中的索引(称为 Follower Index)。
关键特性 ✅
| 特性 | 说明 |
|---|---|
| 自动同步 | Follower 索引自动拉取 Leader 的新操作(增删改),无需手动干预 |
| 近实时 | 延迟通常在秒级(取决于网络和负载) |
| 只读 Follower | Follower 索引为只读,防止数据不一致 |
| 版本兼容 | Follower 集群版本必须 ≥ Leader 集群版本 |
| 基于操作日志 | 利用 Elasticsearch 内部的 translog(事务日志)进行增量同步 |
| 支持索引模板 | 可配合 ILM(索引生命周期管理)实现滚动索引的自动复制 |
典型应用场景 🎯
-
灾难恢复(DR)
主集群(如北京)发生故障时,切换到灾备集群(如上海)继续服务。 -
地理就近访问(Geo-locality)
将数据复制到不同区域的集群,用户访问本地集群,降低延迟。 -
读写分离
写入集中在 Leader 集群,查询分散到多个 Follower 集群,提升读吞吐。 -
数据聚合与分析
将多个业务集群的数据复制到中央分析集群,统一进行 BI 或机器学习。 -
蓝绿部署 / A/B 测试
在 Follower 集群上测试新版本查询逻辑,不影响生产写入。
CCR vs 其他数据同步方案:为何选择 CCR?⚖️
在 CCR 出现之前,用户常通过以下方式实现数据同步:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Logstash + JDBC/Beats | 灵活,支持异构源 | 延迟高(分钟级),需维护管道,无事务保证 | 批量 ETL |
| Snapshot & Restore | 完整备份,节省存储 | 全量/增量快照,恢复慢,非实时 | 灾备、归档 |
| 双写应用层 | 控制精细 | 应用复杂,一致性难保证,失败处理困难 | 简单场景 |
| Kafka 中转 | 解耦,缓冲 | 架构复杂,需维护 Kafka 集群 | 高吞吐流处理 |
| ✅ CCR | 近实时、自动、轻量、事务安全 | 仅限 ES → ES,Follower 只读 | 高可用、低延迟同步 |
💡 结论:如果你的需求是 Elasticsearch 集群之间的近实时、可靠、自动化数据复制,CCR 是最佳选择。
CCR 工作原理:数据如何从 Leader 流向 Follower?📡
理解 CCR 的内部机制,有助于排查问题和优化性能。
核心组件
- Leader Cluster:源集群,包含可被复制的索引(需启用
index.soft_delete.enabled=true,8.x 默认开启)。 - Follower Cluster:目标集群,主动向 Leader 拉取数据。
- Remote Cluster Connection:Follower 集群通过此连接发现并连接 Leader 集群。
- CCR Background Tasks:Follower 集群上的后台任务,负责拉取和重放操作。
数据同步流程
关键技术点
- 基于 Sequence Number:每个操作都有全局递增序号,确保顺序一致;
- Soft Deletes:8.x 默认启用,保留删除记录用于同步;
- Pull-based:Follower 主动拉取,避免 Leader 被压垮;
- 断点续传:网络中断后,从上次成功位置继续。
环境准备:搭建两个 Elasticsearch 集群 🏗️
为演示 CCR,我们需要两个独立的 Elasticsearch 集群。这里使用 Docker Compose 快速部署。
leader/docker-compose.yml
version: '3.8'
services:
es-leader:
image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0
container_name: es-leader
environment:
- cluster.name=leader-cluster
- discovery.type=single-node
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms1g -Xmx1g"
ports:
- "9200:9200"
networks:
- ccr-net
networks:
ccr-net:
driver: bridge
follower/docker-compose.yml
version: '3.8'
services:
es-follower:
image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0
container_name: es-follower
environment:
- cluster.name=follower-cluster
- discovery.type=single-node
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms1g -Xmx1g"
ports:
- "9201:9200" # 避免端口冲突
networks:
- ccr-net
networks:
ccr-net:
driver: bridge
启动集群
# 终端1
cd leader && docker-compose up -d
# 终端2
cd follower && docker-compose up -d
等待 1–2 分钟,确认两个集群均可访问:
- Leader: http://localhost:9200
- Follower: http://localhost:9201
配置跨集群复制:四步走 🚶♂️
步骤 1:在 Follower 集群配置 Remote Cluster
Follower 需要知道如何连接 Leader。
通过 Kibana(推荐)
- 访问 Follower 的 Kibana(假设已部署,或使用 Dev Tools)
- 进入 Stack Management > Remote Clusters
- 点击 Add remote cluster
- Name:
leader-cluster - Seeds:
es-leader:9300(注意:是 transport 端口 9300,不是 HTTP 9200)
- Name:
- 点击 Save
🔒 若启用安全认证,需配置 TLS 和用户凭证。
通过 REST API
curl -X PUT "http://localhost:9201/_cluster/settings" \
-H "Content-Type: application/json" \
-d '{
"persistent": {
"cluster": {
"remote": {
"leader-cluster": {
"seeds": ["es-leader:9300"]
}
}
}
}
}'
验证连接:
curl http://localhost:9201/_remote/info
# 应返回 leader-cluster 的状态为 "connected"
📚 官方文档:Configure Remote Clusters
步骤 2:在 Leader 集群创建可复制的索引
Leader 索引必须满足:
- 启用 soft deletes(8.x 默认开启);
- 不能是
.kibana等系统索引(除非特殊配置)。
# 在 Leader 集群创建索引
curl -X PUT "http://localhost:9200/orders" \
-H "Content-Type: application/json" \
-d '{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"order_id": { "type": "keyword" },
"customer": { "type": "text" },
"amount": { "type": "float" },
"timestamp": { "type": "date" }
}
}
}'
步骤 3:在 Follower 集群启动复制
使用 _ccr/follow API 创建 Follower 索引并开始同步。
curl -X PUT "http://localhost:9201/orders_follower" \
-H "Content-Type: application/json" \
-d '{
"remote_cluster": "leader-cluster",
"leader_index": "orders"
}'
✅ 成功响应:
{"follow_index_created": true}
此时,Follower 集群会自动创建 orders_follower 索引,并开始拉取数据。
步骤 4:验证数据同步
- 向 Leader 写入数据:
curl -X POST "http://localhost:9200/orders/_doc" \
-H "Content-Type: application/json" \
-d '{
"order_id": "ORD-1001",
"customer": "Alice",
"amount": 299.99,
"timestamp": "2025-04-05T10:00:00Z"
}'
- 查询 Follower:
curl "http://localhost:9201/orders_follower/_search?pretty"
你应该能在结果中看到刚写入的文档!
Java 客户端管理 CCR:自动化运维示例 ☕
在生产环境中,你可能需要通过程序动态管理 CCR(如创建/暂停/恢复复制)。Elasticsearch Java API Client 提供了完整支持。
Maven 依赖
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.12.0</version>
</dependency>
初始化两个客户端
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
// Leader 客户端
RestClient leaderRestClient = RestClient.builder(
new HttpHost("localhost", 9200)
).build();
ElasticsearchClient leaderClient = new ElasticsearchClient(
new RestClientTransport(leaderRestClient, new JacksonJsonpMapper())
);
// Follower 客户端
RestClient followerRestClient = RestClient.builder(
new HttpHost("localhost", 9201)
).build();
ElasticsearchClient followerClient = new ElasticsearchClient(
new RestClientTransport(followerRestClient, new JacksonJsonpMapper())
);
创建 Leader 索引(Java)
import co.elastic.clients.elasticsearch.indices.CreateIndexRequest;
CreateIndexRequest createRequest = new CreateIndexRequest.Builder()
.index("products")
.settings(s -> s
.numberOfShards("1")
.numberOfReplicas("0")
)
.mappings(m -> m
.properties("name", p -> p.text(t -> t))
.properties("price", p -> p.float_(f -> f))
)
.build();
leaderClient.indices().create(createRequest);
System.out.println("Leader index 'products' created.");
启动 CCR 复制(Java)
import co.elastic.clients.elasticsearch.ccr.PutFollowRequest;
PutFollowRequest followRequest = new PutFollowRequest.Builder()
.index("products_follower") // Follower 索引名
.remoteCluster("leader-cluster")
.leaderIndex("products")
.build();
followerClient.ccr().putFollow(followRequest);
System.out.println("CCR replication started.");
暂停与恢复复制
// 暂停
followerClient.ccr().pauseFollow(p -> p.index("products_follower"));
// 恢复
followerClient.ccr().resumeFollow(r -> r.index("products_follower"));
获取复制状态
import co.elastic.clients.elasticsearch.ccr.StatsResponse;
StatsResponse stats = followerClient.ccr().stats();
System.out.println("Active follow tasks: " + stats.followStats().numberOfSuccessfulFollowIndices());
🔗 Java API 文档:CCR Java Client
高级配置:调优 CCR 性能与可靠性 ⚙️
1. 调整拉取频率
Follower 默认每秒检查一次新操作。可通过以下参数优化:
PUT /_cluster/settings
{
"persistent": {
"xpack.ccr.follow_read_poll_timeout": "5s" // 拉取间隔
}
}
- 值越小,延迟越低,但请求更频繁;
- 值越大,节省资源,但延迟增加。
2. 控制批量大小
PUT /products_follower/_ccr/follow
{
"max_read_request_operation_count": 512, // 每次拉取最多操作数
"max_outstanding_read_requests": 12, // 并发读请求数
"max_write_buffer_size": "512mb", // 写缓冲区大小
"max_write_buffer_count": 2147483647
}
📊 建议:高吞吐场景可增大
max_read_request_operation_count。
3. 网络与安全
- 网络带宽:确保 Leader 与 Follower 之间有足够带宽;
- TLS 加密:生产环境必须启用 TLS;
- 专用用户:为 CCR 创建最小权限用户(需
read+monitor权限)。
// 在 Leader 集群创建角色
POST /_security/role/ccr_reader
{
"cluster": ["monitor"],
"indices": [
{
"names": ["*"],
"privileges": ["read", "view_index_metadata"]
}
]
}
监控与故障排查:确保 CCR 健康运行 👁️
关键监控指标
| 指标 | 说明 | 告警阈值 |
|---|---|---|
ccr.follow_pending_tasks |
待处理任务数 | > 0 持续增长 |
ccr.read_exceptions |
读取异常次数 | > 0 |
ccr.write_exceptions |
写入异常次数 | > 0 |
follower_lag_in_bytes |
数据滞后字节数 | > 1GB |
follower_lag_in_ops |
滞后操作数 | > 10000 |
查看复制状态
# 查看所有 follow 任务
GET /_ccr/stats
# 查看特定索引状态
GET /products_follower/_ccr/stats
响应示例:
{
"follow_stats": {
"total_read_remote_exec_time_millis": 1200,
"total_read_time_millis": 800,
"total_write_time_millis": 400,
"last_requested_seq_no": 1500,
"last_seen_seq_no": 1500,
"outstanding_read_requests": 0,
"outstanding_write_requests": 0
}
}
last_requested_seq_no == last_seen_seq_no表示无滞后。
常见问题
Q1: Follower 索引无法创建?
- 检查 Remote Cluster 是否 connected;
- 确认 Leader 索引存在且可读;
- 查看 Follower 日志:
docker logs es-follower
Q2: 复制延迟高?
- 检查网络延迟(
ping,traceroute); - 增大
max_read_request_operation_count; - 降低 Leader 写入压力。
Q3: 如何停止复制?
POST /products_follower/_ccr/unfollow
⚠️ 注意:
unfollow会关闭复制,但保留 Follower 索引数据。
架构实战:构建多活读写分离系统 🌍
假设我们有一个全球电商系统,希望:
- 所有订单写入 美国东部(Leader)集群;
- 用户在 欧洲 和 亚太 通过本地 Follower 集群查询订单。
架构图
flowchart LR
A[Web App - US] -->|Write| B[Elasticsearch\nUS-East\n(Leader)]
C[Web App - EU] -->|Read| D[Elasticsearch\nEU-West\n(Follower)]
E[Web App - APAC] -->|Read| F[Elasticsearch\nAPAC-SG\n(Follower)]
B -->|CCR| D
B -->|CCR| F
style B fill:#ffe4b5,stroke:#333
style D fill:#98fb98,stroke:#333
style F fill:#98fb98,stroke:#333
实施步骤
- 部署三个集群:
us-east,eu-west,apac-sg; - 在
eu-west和apac-sg配置 Remote Cluster 指向us-east; - 在两个 Follower 集群上对
orders索引执行follow; - 应用层根据用户地理位置路由查询请求。
优势
- 写入集中,保证一致性;
- 查询本地化,延迟 < 50ms;
- 单区域故障不影响其他区域读取。
CCR 与索引生命周期管理(ILM)集成 🔄
实际生产中,日志或指标数据通常按天滚动(如 logs-2025-04-05)。CCR 支持自动复制新创建的索引。
步骤
- 在 Leader 集群创建索引模板 + ILM 策略;
- 在 Follower 集群创建 自动跟随模式(Auto-follow pattern)。
Leader:设置 ILM
PUT _ilm/policy/daily-logs-policy
{
"policy": {
"phases": {
"hot": { "actions": { "rollover": { "max_age": "1d" } } }
}
}
}
PUT _index_template/logs-template
{
"index_patterns": ["logs-*"],
"template": {
"settings": {
"index.lifecycle.name": "daily-logs-policy",
"index.lifecycle.rollover_alias": "logs-write"
}
}
}
Follower:设置 Auto-follow
PUT _ccr/auto_follow/logs-auto-follow
{
"remote_cluster": "leader-cluster",
"leader_index_patterns": ["logs-*"],
"follow_index_pattern": "{{leader_index}}-follower"
}
现在,每当 Leader 创建 logs-2025-04-05,Follower 会自动创建 logs-2025-04-05-follower 并开始复制!
🔗 官方指南:Auto-follow Patterns
安全与权限控制:生产环境必备 🔐
CCR 涉及跨集群通信,安全至关重要。
最小权限原则
在 Leader 集群创建专用角色:
POST /_security/role/ccr_replicator
{
"cluster": ["monitor", "manage_ccr"],
"indices": [
{
"names": ["logs-*", "orders"],
"privileges": ["read", "view_index_metadata"]
}
]
}
在 Follower 集群创建用户并分配角色:
POST /_security/user/ccr_user
{
"password": "secure_password",
"roles": ["ccr_replicator"]
}
然后在 Remote Cluster 配置中指定用户凭证(需 TLS)。
📚 安全文档:CCR Security
替代方案思考:何时不使用 CCR?🤔
尽管 CCR 强大,但并非万能:
- 异构数据源:若源不是 Elasticsearch,需用 Logstash 或 Kafka;
- 双向同步:CCR 是单向的,双向需应用层协调;
- 极低延迟要求(< 100ms):考虑同集群副本或应用缓存;
- 成本敏感:Follower 集群需同等存储资源。
总结:构建弹性、智能的数据同步体系 🧠
通过本文,我们全面掌握了 Elasticsearch 跨集群复制(CCR)的核心能力:
- 理解了 CCR 的工作原理与适用场景;
- 学会了从零配置 Leader/Follower 集群;
- 掌握了 Java 客户端自动化管理 CCR;
- 实践了多活读写分离与 ILM 集成;
- 了解了安全、监控、调优等生产要素。
CCR 不仅是一项技术功能,更是一种架构思维——通过数据的流动与冗余,换取系统的韧性与用户体验的提升。
当你在全球部署 Elasticsearch 集群时,CCR 就是你手中的“数据高速公路”,让信息无缝穿梭于各个角落,支撑起真正全球化、高可用的智能应用。
现在,就去你的环境中试试 CCR 吧!用几行 API,构建属于你的弹性数据同步网络。🌐✨
附录:权威资源链接
- 📘 Elasticsearch CCR 官方文档
- 🛠️ CCR REST API 参考
- 📊 Monitoring CCR with Kibana
- 🎥 Elastic 官方 CCR 教程视频
- 🧪 CCR 性能基准测试报告
Happy Replicating! 🚀
🙌 感谢你读到这里!
🔍 技术之路没有捷径,但每一次阅读、思考和实践,都在悄悄拉近你与目标的距离。
💡 如果本文对你有帮助,不妨 👍 点赞、📌 收藏、📤 分享 给更多需要的朋友!
💬 欢迎在评论区留下你的想法、疑问或建议,我会一一回复,我们一起交流、共同成长 🌿
🔔 关注我,不错过下一篇干货!我们下期再见!✨
更多推荐


所有评论(0)