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