首页/数据/数据工程与 ETL 速查/Canal HA:ZooKeeper 主备
CDC 与同步53 条

Canal HA:ZooKeeper 主备

Canal 高可用依赖 ZooKeeper:多个 Canal Server 向 ZK 注册同一 destination,同一时刻只有一个 Active 提供服务,故障时 Standby 接管并从持久化位点继续。客户端通过 ZK 感知当前 Active 地址,切换期间要处理连接重建与位点确认。

Canal HA 是什么

Canal 的高可用依赖 ZooKeeper:多个 Canal Server 向 ZK 注册同一个 destination,同一时刻只有一个实例处于 Active 状态提供服务,其余为 Standby。Active 故障后,Standby 通过 ZK 的选主机制接管,并从持久化的位点继续解析,客户端再从 ZK 查询当前可用的 server 地址重新连接。需要记住的是:这套机制保证的是服务可用性,不保证消息不丢不重——切换期间未被客户端确认的批次会被重投,消费侧仍然必须幂等。

基本信息

协调组件ZooKeeper 集群(节点数按团队高可用规范部署)
角色Active 提供服务,Standby 待命
位点持久化服务端与客户端各自的位点按配置持久化,位置是切换续读的关键
切换行为Standby 接管,从持久化位点继续解析
客户端要求从 ZK 或配置中心获取当前可用地址,并具备重连逻辑

典型使用场景

  • 生产库同步不允许中断:单实例故障时自动切换,尽量减少停更时间
  • 定期演练故障切换,验证客户端重连与位点续读是否正常
  • 扩容或迁移机器:新实例加入后由 ZK 参与选主
  • 多业务共用一套同步链路时,按 destination 隔离并在需要时各自做主备
  • 排查切换后数据重复:确认未确认批次被重投的范围

HA 拓扑示意

HA 拓扑示意
canal-server-A  --active---+                (注册同一 destination)
                            +--> ZooKeeper(注册与选主)
canal-server-B  --standby--+

客户端:从 ZK 查询当前可用 server 地址后连接,断连需重试
位点:服务端持久化 + 客户端 ack 共同决定续读起点

# 演练要点:主动停掉 Active,确认 Standby 接管时间与数据是否连续
# 观察项:接管耗时、未确认批次的重投范围、客户端重连是否自动完成

切换期间的行为

环节切换时的表现要求
选主ZK 中重新选出 ActiveZK 集群本身要冗余部署
位点从持久化位点继续解析位点存储要可靠,不能只放本地
客户端连接断开后重连新地址需要重试与重连逻辑
消息语义未确认批次会被重投消费侧必须幂等
HA 保证的是服务可用性,不保证不丢不重:ZK 自身也要按集群部署并做切换演练,否则单点故障时整条同步链路一起停。
只部署一台 Canal 却配置了 HA 参数是常见的假高可用:故障时没有可接管的节点,配置看起来完整但毫无作用。
位点存储的位置决定切换后能否续读:位点只保存在容器本地时,实例重建或换机后可能从很早的位点重放,造成大量重复数据。

易错点

  • 只部署一台 Canal 却配置了 HA 参数,故障时没有可接管节点,属于假高可用
  • 客户端缓存了旧 Active 地址且不重试,切换完成后消费长时间中断
  • 位点只持久化在容器本地,实例重建后从旧位点重放,下游产生大量重复数据
  • 切换后未确认批次被重投,而消费侧不幂等,指标被重复累加

数据来源与参考

  • Canal 官方文档(HA 配置与使用)
  • Apache ZooKeeper 官方文档
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌