ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

TongSearch跨集群复制(CCR)原理与实战:从同步机制到容灾设计

TongSearch跨集群复制(CCR)原理与实战:从同步机制到容灾设计 1. 为什么需要跨集群复制单集群的边界与同步的刚需先说个我在实际项目里常被问到的场景业务上线前明明只规划了一个 TongSearch 集群结果运行半年后业务部门突然提出北京机房的数据上海机房也要能实时查到。再或者合规审计要求数据必须保留多副本生产集群要容灾主集群挂了另外一套集群要能立刻顶上。这时候你会发现单集群不是不够用而是它的能力边界天然决定了——它只能保证本集群内的数据一致性和查询可用性解决不了跨机房跨网络跨组织的数据流动问题。TongSearch 的跨集群复制Cross-Cluster ReplicationCCR就是专门干这个的。我把它理解成数据库领域的主从同步只不过它是在搜索引擎这个维度上重新实现了同一件事。核心思路不复杂一个集群作为数据源Leader另一个或多个集群作为数据接收方FollowerLeader 上的索引变更会被持续捕获、传输、重放最终让 Follower 集群上的索引内容和 Leader 保持一致。这玩意儿解决的实际痛点我梳理下来基本是四类容灾与高可用主集群所在机房出现网络故障、断电甚至硬件损坏时Follower 集群可以快速切换对外服务业务不中断。就近读取用户在多个地域访问时直接读本地机房集群查询延迟大幅下降不需要每次请求都跨地域走公网。数据归集多个边缘集群的数据统一同步到中心集群供数据分析、BI 报表使用。集群迁移与升级先把数据同步到新版本集群验证稳定后再切流量降低升级风险。我最早接触跨集群复制是在一个金融客户的灾备项目里。客户的业务场景是主中心同城灾备两边各一套 TongSearch主中心负责日常读写灾备中心平时只承担只读查询如果主中心出现极端故障灾备要在 30 分钟内拉起完整的写入能力。当时最让我头疼的不是 TongSearch 本身而是怎么保证两边数据不丢、不重、不乱序。这个三不原则就是跨集群复制设计里的灵魂。换一个更直白的说法如果你把 TongSearch 集群想象成一个巨大的图书馆索引就是书架上的书文档就是书里的每一页。单集群是只有一个馆区的图书馆读者只能跑来这里看书跨集群复制等于在另一个城市开分馆总馆每进来一批新书、或者修改一本书的内容分馆都要同步更新。麻烦的是总馆和分馆之间不是用卡车运书而是通过一条网络管道不断传递变更记录怎么保证传递过程不掉页、不重复、不乱序就成了整个同步流程最核心的工程问题。这也解释了为什么跨集群复制不能简单粗暴地用把全量索引文件拷贝过去来实现。文件拷贝只能解决某一时刻的快照问题之后源源不断的增量写入怎么办所以 CCR 的架构从设计第一天起就是围绕增量日志捕获 可靠传输 有序重放这三个环节展开的。2. 前置条件与集群规划网络、版本、内存和索引设计缺一不可很多人在 TongSearch 上配 CCR 失败不是同步逻辑出了问题而是前置条件没满足。这一节我把容易踩的坑按顺序讲清楚。2.1 网络连通性与安全认证跨集群复制说到底是一条持续不断的数据管道管道两头必须能稳定互通。这里要注意的不仅是能 ping 通还有两个细节。第一端口要放通。TongSearch 节点之间的传输端口、HTTP 端口都要双向可达。如果中间有防火墙或安全组记得把集群节点的 IP 加白名单。我在一个项目里排查了整整一个下午的同步延迟问题最后发现是防火墙对长连接做了空闲超时连接被静默断开后TongSearch 没有立刻重连导致同步出现积压。后来调了防火墙的空闲超时时间问题立刻消失。第二认证方式要提前对齐。如果集群开启了安全认证Follower 集群连接 Leader 集群时使用的账号必须具备读取索引的权限。很多刚上手的人只配了连通性忘了配权限日志里报 403 却一头雾水。检查项说明常见问题网络连通性节点端口双向可达防火墙拦截长连接安全认证同步账号有读取源索引权限403 权限错误版本兼容Leader 与 Follower 版本匹配版本不一致导致协议异常集群时间建议保持一致日志排查困难索引状态源索引不能处于 close 状态同步任务创建失败2.2 版本兼容与内存分配跨集群复制对版本匹配有比较严格的要求。我的经验是Follower 集群的版本不要低于 Leader 集群最好完全一致。版本差太多会出现协议层不兼容同步任务能创建但数据一直不同步日志还没有明显报错。内存方面很多人忽略了一个点CCR 同步任务在 Follower 集群上会常驻一些线程和缓冲区。如果 Follower 集群本身内存就很紧张同步任务会把内存压力进一步放大严重时直接触发 OOM。所以规划时我一般建议在原有堆内存基础上预留 10% 到 15% 的余量给复制任务。2.3 索引设计对同步成功率的影响这是最有意思的一块。跨集群复制是对索引这一层做同步不是对文档做同步。这就意味着原索引是什么分片规划、什么 mapping、什么分词器Follower 集群上都会照着建。因此在源集群创建索引时有几件事必须提前想清楚主分片数不能事后随意更改。分片数是索引创建时就定死的CCR 同步时会保持和源一致。mapping 必须稳定。如果源索引的 mapping 频繁变更同步任务可能需要重建索引导致长时间不同步。别名和索引模板提前规划好。Follower 集群上建议使用与源不同的别名方便切换。我见过一个很有意思的实际案例业务团队在源集群上删掉了一个字段结果 Follower 集群上的同步任务直接报错。查了半天才发现Follower 集群上的索引还是旧的 mapping新数据里少了这个字段解析阶段就开始报错复制任务只能暂停。这类问题没有太好的自动化手段解决核心还是靠源端的变更规范和同步任务的状态监控。3. 同步流程的完整链路从索引快照到增量日志重放接下来是最核心的部分——数据同步到底是怎么跑起来的。我会按顺序把整条链路拆开讲这样你在排查问题时能准确判断目前卡在了哪一步。3.1 阶段一创建索引快照与数据初始化第一次建立复制任务时Follower 集群上通常没有目标索引或者有同名索引但数据落后很多。CCR 的第一步不是直接拉增量日志而是先做一次全量初始化也就是常说的把基线数据先对齐。这个阶段做的事情我形容为先拍一张照片再把照片传到另一个房间挂起来。具体流程是复制任务读取源索引的元数据信息mapping、分片数、setting。基于这套元数据在 Follower 集群创建同名索引。将源索引的主分片数据进行快照式拉取写入 Follower 集群的新索引。快照完成前产生的增量数据会被记录下来快照完成后继续从增量日志处补拉。这里有个关键问题快照过程中增量数据不能丢。CCR 的实现方式是在创建快照的同时开启日志记录快照创建完成后把日志里积压的增量变更再次应用到 Follower。这样就能做到全量增量拼接后数据一致。3.2 阶段二增量日志捕获——读懂 Translog快照做完之后后面的日常同步就完全依赖增量日志了。在 TongSearch 的底层设计里每个分片在写入数据时除了写 Lucene 索引文件还会写一份 translog 日志用来保证异常情况下的数据恢复。CCR 正是借助这份 translog 来感知源端数据变化的。我把这个过程类比成流水账Lucene 索引文件是整理好的财务报表translog 是每天发生的每一笔记账。CCR 做的事情就是不断读取新账目然后一条条同步到另一个地方重新记账。从实现层面看Follower 集群的复制任务会定期轮询源端分片拉取自上次同步位置之后新增的 translog 操作记录。每一次拉取都会记录一个同步位置类似游标这样即使同步中断下次也能从断点继续不会重复也不会遗漏。3.3 阶段三数据重放与冲突处理增量日志拉到 Follower 集群后就要真正写到本地了。这个阶段有几个细节值得注意。顺序一致性每个分片的变更会按照源端写入顺序依次重放确保同一个分片上的文档操作不乱序。冲突策略如果 Follower 集群上的目标文档被本地修改过复制引擎会以源端数据为准进行覆盖。我建议 Follower 集群上的索引严格只读任何本地写入都会增加冲突风险。批量性能复制任务不是一条条写而是按批写入提升吞吐。说到这里我想强调一个反直觉的点Follower 集群上的数据并不能保证在任意时刻都和 Leader 完全一致。它是有同步延迟的这个延迟可能是几十毫秒也可能在高峰期拉到几秒甚至更久。如果你做的是强一致的跨机房读写场景CCR 不适合它解决的是最终一致性需求。这一点必须在项目设计阶段就跟业务方对齐不然后面会出现一堆数据怎么还没同步过来的投诉。3.4 阶段四状态监控与断点续传同步链路跑起来后不是就一劳永逸了。CCR 提供了比较完善的状态查询能力你可以通过 API 查看每个复制任务的位置、健康状况、最近同步时间等信息。我一般会建一套监控巡检脚本重点盯几个指标指标正常范围异常表现同步延迟秒级以内持续分钟级以上复制任务状态activefailed / paused未同步操作数趋近于 0持续增长网络重试次数偶尔出现频繁重试断点续传是 CCR 最让人放心的能力之一。只要 translog 没有被源端清理掉复制任务在中断恢复后都能从上次记录的位置继续同步。这里有一个隐藏的坑如果 Follower 集群停摆时间过长源端 translog 因为保留策略被清理那断点就没法续了只能重建复制任务走一次全量初始化。所以源端 translog 的保留策略需要根据最大允许停摆时间来设计。4. 创建复制任务的实操步骤与参数解析理论链路讲完下面进入动手环节。我以实际配置为例把创建跨集群复制任务的完整过程走一遍。4.1 在 Follower 集群注册远端集群所有 CCR 任务都是在 Follower 端发起主动去 Leader 端拉数据所以第一步是在 Follower 集群上配置远端集群信息告诉它你的数据源头在哪。PUT /_cluster/settings { persistent: { cluster.remote.leader_cluster.seeds: [10.0.1.10:9300, 10.0.1.11:9300] } }这里的leader_cluster是给远端集群起的别名后面的地址是 Leader 集群节点的 transport 端口。我习惯在 seeds 里至少配两个节点避免单个节点不可达导致远端集群信息无法解析。配置完成后可以用下面的命令验证连通性GET /_remote/info如果配置正确返回结果里能看到 leader_cluster 的集群信息如果返回报错优先检查网络、端口、认证。4.2 创建跨集群复制任务远端集群注册好后就可以创建复制任务了。TongSearch 的 CCR API 通常长这样PUT /_ccr/leader_cluster:source_index/_sync { remote: { host: 10.0.1.10, port: 9200 }, target_index: target_index, enabled: true, sync_strategy: full_copy, schedule: every 5s }参数含义逐个解释一下remote.host和remote.portLeader 集群的 HTTP 访问地址。target_index同步到本地后创建的索引名可以不同于源索引名。sync_strategyfull_copy表示先做全量拷贝再持续增量同步。如果目标索引已经存在且数据完整也可以选择只做增量。schedule增量拉取的执行间隔设定同步任务检查源端变更的频率。创建成功后复制任务会自动执行初始化流程。你可以用下面命令查看任务状态GET /_ccr/target_index/_status返回信息里要重点看两处sync_status是否正常和sync_progress同步进度。如果是刚创建的任务initialization_in_progress会短暂为 true等全量初始化完成后会进入持续增量同步状态。4.3 参数调优从默认值到适合业务的配置每个人都有自己的一套参数心法我这里分享几个我实际调过觉得影响比较大的。同步频率。默认的增量拉取频率在数据量不大时够用但如果业务写入 QPS 很高建议把 schedule 缩短到 1 到 2 秒否则同步延迟会肉眼可见地增长。当然频率越高Follower 集群的轮询开销也越高需要平衡。批量大小。部分版本支持配置批量拉取的大小。我之前压测过一个数据量较大的索引默认配置下同步吞吐一直上不去调整了批量拉取文档数之后吞吐提升了将近一倍。这个参数和网络带宽、目标集群写入能力都有关系建议通过压测确定不要照搬别人的配置。translog 保留策略。就如 3.4 节提到的translog 保留时长的设置决定了断点续传的安全窗口。PUT /leader_cluster:source_index/_settings { index.translog.retention.size: 512mb, index.translog.retention.age: 12h }如果你的业务允许 Follower 集群最多停摆半天那保留 12 小时是一个比较稳妥的值。设置太大有磁盘占用问题设置太小有断点失效风险。4.4 复制任务的启停与切换在实际运维中我经常需要临时暂停某个复制任务比如 Leader 集群要升级、Follower 集群要扩容。操作其实很简单但很容易在暂停后忘了恢复这个环节翻车。暂停任务POST /_ccr/target_index/_pause恢复任务POST /_ccr/target_index/_resume还有一个容易忽略的点暂停期间产生的增量数据会继续留在源端 translog 里恢复后会自动补拉不需要手动处理。但这依赖于源端 translog 没有被清理所以暂停时间不宜超过 translog 保留时限。5. 实测中常见的坑与排查路径从我的经验看跨集群复制在落地过程中遇到的大多数问题都可以从四个方面去排查网络、权限、translog、目标索引状态。这一节我把遇到过的典型坑按排查路径写出来希望能帮你省去一些弯路。5.1 复制任务一直处于初始化状态有一次客户反馈复制任务创建后半天都没有完成初始化。我查任务状态发现initialization_in_progress一直为 true但同步进度没有任何变化。排查链路如下先看 Follower 集群日志关键词搜 ccr 或 replication。日志里发现一直提示无法连接 Leader 集群的某个节点。核对网络后发现该节点的 transport 端口在安全组里没有放通。放通端口后任务立刻完成初始化进入增量同步。这个案例的教训是注册远端集群时可能只配了部分节点的 seeds但实际复制任务会连接所有参与的分片所在节点任何一个节点不通都可能导致初始化挂起。5.2 同步延迟持续增长但任务状态是 active还有一种更隐蔽的情况任务状态显示 normal同步延迟却从几秒涨到几分钟而且没有回落的趋势。遇到这种问题我的排查顺序是先看源端写入速率。如果源端 QPS 本来就很高延迟增长可能是数据生产速度超过了消费速度。再看 Follower 集群的写入能力。Follower 节点磁盘 I/O 是否打满堆内存是否频繁 GC。最后看网络带宽。如果带宽被打满数据拉取自然会变慢。多数情况下这种延迟增长是消费端能力不足导致的处理方式是扩容 Follower 集群或者调大批量参数。5.3 目标索引 mapping 冲突导致复制报错这个坑在前面提过但在实际排查中特别容易绕弯子。现象是复制任务突然变成 failed日志里报字段类型冲突。我当时的排查步骤查看任务状态发现失败原因是mapper_parsing_exception。对比源索引和目标索引的 mapping发现目标索引的某个字段是 long 类型但源端已经改成了 keyword。这个字段在源端已经写入了一段时间Follower 集群的索引却还保留旧 mapping导致新数据写入时报错。解决办法没有捷径删除目标索引重建复制任务或者手工更新目标索引 mapping。这也说明跨集群复制里的mapping 漂移问题必须靠变更管理流程去约束而不是每次出问题再救火。5.4 同步停止但没有任何报错最让人头疼的问题是没有报错但数据不更新。我在一个项目里遇到过复制任务显示正常源端有写入目标端数据就是不变。排查链路确认任务状态、同步位置是否有推进。发现同步位置停在一个固定的序号上不再前进。打开源端 translog 统计发现该分片的 translog 增长极小。最后定位到问题根源业务写入的是另一个索引搞错了同步目标。其实很多时候数据不同步不是 CCR 本身的问题而是业务写入的索引和你配置复制任务的索引根本不是同一个。这种问题检查配置就能发现但一定要先有查同步位置是否推进的习惯而不是在配置和日志里漫无目的地翻。5.5 关于监控与告警的几条建议跨集群复制是后台持续运行的工作你不可能每时每刻盯着控制台。我建议至少做以下几层监控任务状态监控复制任务出现 failed 或 paused 时必须告警。同步延迟监控延迟超过业务容忍阈值的要告警。磁盘空间监控translog 保留策略设置过大或业务停摆导致 translog 暴增都会撑爆磁盘。告警方案不必做得非常复杂初期先用脚本定时调 API 拉状态把结果推到企业微信或钉钉消息里就够用。等体系成熟后再考虑接入统一的监控平台。6. 从同步到容灾一个完整的设计思路最后这部分我不讲具体的 API 操作而是把视角拉高一点聊聊怎么基于 CCR 设计一套真正能用的容灾方案。毕竟很多团队配好了同步任务以为数据在复制了就万事大吉结果做容灾演练时发现根本切换不了。6.1 明确 RPO 和 RTO 目标设计容灾方案前先回答两个问题RPO恢复点目标灾难发生时最多允许丢多少数据RTO恢复时间目标灾难发生后多久必须恢复服务跨集群复制决定了 RPO 的下限。如果同步延迟是 5 秒那最多可能丢 5 秒的数据。如果你跟业务方承诺 RPO 为 0零丢失CCR 模式满足不了需要额外的双写或其他方案。RTO 则取决于你的切换流程。Follower 集群的索引默认是只读的要把流量切过去可能需要执行索引只读开关、别名切换、甚至 DNS 切换这些操作时间要提前演练不能等到灾难发生时才想。6.2 读流量切分与写流量切换我在实际方案里通常会把容灾切换分成两步第一步是读流量切换。平时 Follower 集群承担只读查询如果 Leader 集群出现慢查询、热点等问题可以把读流量切到 Follower。第二步是写流量切换。Leader 集群彻底不可用时执行真正的故障切换。这时需要把 Follower 集群的索引从只读状态解开允许写入同时将业务系统的写入地址切换到 Follower 集群。这里有个容易被忽略的设计点切换前要确保 Follower 集群此时的数据已经追平到故障前的最后状态这需要你在切换动作中增加等待同步延迟归零的判断而不是直接切。6.3 回切方案要提前设计很多团队做容灾只做了切过去没做切回来。等 Leader 集群恢复后想要重新切回原集群发现数据流已经断开了需要重建复制任务或者花很长时间重新同步。我的建议是在容灾演练时把回切也作为必选动作演练并且提前规划好回切时的数据一致性校验方案。比如随机抽几个重点索引的文档数做对比或者用时间戳字段判断最大同步位置是否一致。这些动作有了成熟流程后真到用的时候才不会手忙脚乱。根据我个人的经验CCR 在 TongSearch 里是比较成熟的能力但同步功能能用和容灾方案可靠是两码事。前者只需要配置正确后者还依赖监控告警、切换流程、演练机制这些周边体系的建设。如果你正准备在生产环境上线 CCR我建议你先从非核心业务索引开始试点跑通之后再逐步扩大范围。至少我自己经历过的几个比较顺的项目都是这么一步步过来的。
返回列表