异地多活是一项系统性工作,包含 web 层、应用服务层、数据层的流量分配和同步。
数据层的双向同步是整个方案基础,CloudCanal 在 MySQL <-> MySQL 链路有效支持了这个能力,本文简要介绍如何使用 CloudCanal 配置这样的双向同步链路。
双向同步中, 暂时无法完全通过数据层解决的是数据冲突问题,如一个订单同时在两地被修改价格,到底哪个为准,这个具有外部依赖性。
针对这个问题,最有效的解决方案是通过业务流量分配(比如user_id),将同一条数据(或相关数据)写入放在其中一边,更加简单暴力的方式是将具备冲突条件的数据写入完全放在一地。
另外同步工具层面可添加数据冲突策略,比如版本号对比、设定数据优先级等,甚至人工介入解决。
回环问题,即防止数据在双向链路中写回产生日志的实例,导致老数据覆盖新数据。
业界常用解决方案包括以下几种:
CloudCanal 目前在 MySQL 到 MySQL 链路采用了 GTID 方案,一是 MySQL 自带这个防重能力,二是尽量避免做更多操作。
本次案例使用 docker 社区版 。
本案例 MySQL 数据库放在上海和杭州, CloudCanal社区版运行于上海 ECS
登录 CloudCanal 平台
数据源管理 -> 添加数据源
选择 自建 MySQL ,阿里云 RDS 账号权限不支持链接上设置 GTID_NEXT
自建 MySQL 开 binlog 和 GTID
server-id = 2 log-bin = mysql-bin gtid_mode = on enforce_gtid_consistency = on
确认 MySQL GTID 已经生效(请写几条测试数据)
建议对数据源进行描述修改,防止配置正反链路时,识别错数据库
如果对数据不做映射、裁剪、转换、冲突策略(比如略过冲突数据)等动作,使用 MySQL 双 Master 复制是一个选择。
另外对于长距离双向同步,还需做一些防网络中断等工作。
综合这两方面,第三方有商业支持或开源软件可能会表现出更好的应变性。毕竟改 MySQL 代码不容易。
一部分原因和上面是一致的,毕竟是数据库内部机制,很难做一些定制。对于 3 副本或者 5 副本,一般做法是多数派副本在同城(不同机架、机房),少数副本在异地,异地副本靠异步同步数据。
对于单 Leader 写入机制,连业务层面设计不冲突写入策略的机会可能都没有。Multi-Master 涉及更加复杂的算法。
综合来看,没有孰好孰坏,按业务对数据的实际要求和所能提供的硬件条件进行选择。
目前 CloudCanal 方案只实现了 MySQL->MySQL ,并且方案上依赖 GTID ,对于 ORACLE ,PG ,SQLSERVER 等关系型数据库,可能需要实现通用方案(主要是事务方案), 将他们同构或者异构链接起来。
本文简单介绍了如何使用 CloudCanal 构建 MySQL->MySQL 双向同步链路,如果各位有需求,可以尝试使用下我们的免费社区版体验。
最后,如果各位觉得这篇文章还不错,请点赞、评论加转发吧。