当前位置: 首页>数据库>正文

双活系统 数据库postgresql mysql数据库双活

简述

异地多活是一项系统性工作,包含 web 层、应用服务层、数据层的流量分配和同步。

数据层的双向同步是整个方案基础,CloudCanal 在 MySQL <-> MySQL 链路有效支持了这个能力,本文简要介绍如何使用 CloudCanal 配置这样的双向同步链路。

技术点

数据冲突

双向同步中, 暂时无法完全通过数据层解决的是数据冲突问题,如一个订单同时在两地被修改价格,到底哪个为准,这个具有外部依赖性。

针对这个问题,最有效的解决方案是通过业务流量分配(比如user_id),将同一条数据(或相关数据)写入放在其中一边,更加简单暴力的方式是将具备冲突条件的数据写入完全放在一地。

另外同步工具层面可添加数据冲突策略,比如版本号对比、设定数据优先级等,甚至人工介入解决。

同步回环

回环问题,即防止数据在双向链路中写回产生日志的实例,导致老数据覆盖新数据。

业界常用解决方案包括以下几种:

  • 修改数据库引擎,将同步过来的日志写入打上特殊标记(如 MySQL relay_log apply),对向链路识别该标记并决定是否同步
  • 同步数据写到对端时, 同一个事务带上一个特定操作,对向链路识别这个操作,决定整个事务是否同步
  • 依赖数据库自身提供的防回环机制(比如 MySQL GTID),同步工具做相应动作

CloudCanal 目前在 MySQL 到 MySQL 链路采用了 GTID 方案,一是 MySQL 自带这个防重能力,二是尽量避免做更多操作。

举个 “栗子”

准备 CloudCanal

本次案例使用 docker 社区版, 安装参考 。

添加数据源

  • 本案例 MySQL 数据库放在上海杭州, CloudCanal社区版运行于上海 ECS
  • 登录 CloudCanal 平台
  • 数据源管理 -> 添加数据源
  • 选择 自建 MySQL ,阿里云 RDS 账号权限不支持链接上设置 GTID_NEXT

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_数据同步,第1张

  • 自建 MySQL 开 binlog 和 GTID
server-id       = 2
log-bin         = mysql-bin
gtid_mode = on
enforce_gtid_consistency = on
  • 确认 MySQL GTID 已经生效(请写几条测试数据)

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_CloudCanal_02,第2张

  • 建议对数据源进行描述修改,防止配置正反链路时,识别错数据库

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_数据迁移_03,第3张

创建正向同步任务

  • 任务管理->新建任务
  • 双向同步中,正向任务一般指源端有数据,目标端无数据的链路,涉及对端数据初始化
  • 源端和目标端选择数据源, 并分别点击 测试连接 按钮以测试数据库连通性和获取 schema 级别元信息
  • 选择源端和目标端 schema
  • 点击下一步

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_数据迁移_04,第4张

  • 选择 数据同步,并且勾选 全量数据初始化
  • 规格可以根据任务重要度以及部署机器的内存容量合理选择,一般 2GB 内存规格即可
  • 勾选 DDL 同步
  • 点击 下一步

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_CloudCanal_05,第5张

  • 表、列映射裁剪…此处省略
  • 对任务内容进行确认 ,置灰 自动启动任务 按钮以便调参数
  • 点击确认创建

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_canal_06,第6张

  • 任务详情 -> 参数设置
  • 设置目标数据源配置 deCycle , enableTransaction , 源端数据源配置 gtidMode 参数为 true

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_canal_07,第7张

  • 生效配置并启动

创建反向同步任务

  • 任务管理->新建任务
  • 源端和目标端选择数据源(请和正向任务所选数据源对调), 并分别点击 测试连接 按钮以测试数据库连通性和获取 schema 级别元信息
  • 选择源端和目标端 schema
  • 点击下一步

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_数据迁移_08,第8张

  • 选择 数据同步,并去除 全量数据初始化
  • 勾选 DDL 同步
  • 点击 下一步

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_canal_09,第9张

  • 表、列映射裁剪…此处省略
  • 对任务内容进行确认 ,置灰 自动启动任务 按钮以便调参数
  • 点击确认创建

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_双活系统 数据库postgresql_10,第10张

  • 任务详情 -> 参数设置
  • 设置目标数据源配置 deCycle , enableTransaction , 源端数据源配置 gtidMode 参数为 true
  • 生效配置并启动

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_canal_11,第11张

任务同步

  • 正向任务和反向任务正常同步,进行源和目标数据校验一致

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_双活系统 数据库postgresql_12,第12张

测试

  • 为了防止数据冲突,我们分别给两个数据库的不同表造一些混合负载,表级别隔离下冲突数据的可能。看最后数据是否一致。
  • 给源端数据库中 kbs_question 表和 目标数据库 kbs_article 表造 IUD 负载 。

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_双活系统 数据库postgresql_13,第13张

  • 停止测试负载
  • 正向和反向任务状况

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_数据同步_14,第14张

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_双活系统 数据库postgresql_15,第15张

  • 重跑校验任务,数据一致

    双活系统 数据库postgresql mysql数据库双活,双活系统 数据库postgresql mysql数据库双活_双活系统 数据库postgresql_16,第16张

FAQ

为什么不用 MySQL 原生的双 Master 复制

如果对数据不做映射、裁剪、转换、冲突策略(比如略过冲突数据)等动作,使用 MySQL 双 Master 复制是一个选择。

另外对于长距离双向同步,还需做一些防网络中断等工作。

综合这两方面,第三方有商业支持或开源软件可能会表现出更好的应变性。毕竟改 MySQL 代码不容易。

为什么不用 Paxos 或 Raft 支持的数据库异地 3 副本或 5 副本

一部分原因和上面是一致的,毕竟是数据库内部机制,很难做一些定制。对于 3 副本或者 5 副本,一般做法是多数派副本在同城(不同机架、机房),少数副本在异地,异地副本靠异步同步数据。

对于单 Leader 写入机制,连业务层面设计不冲突写入策略的机会可能都没有。Multi-Master 涉及更加复杂的算法。

综合来看,没有孰好孰坏,按业务对数据的实际要求和所能提供的硬件条件进行选择。

双向同步还支持哪些链路?

目前 CloudCanal 方案只实现了 MySQL->MySQL ,并且方案上依赖 GTID ,对于 ORACLE ,PG ,SQLSERVER 等关系型数据库,可能需要实现通用方案(主要是事务方案), 将他们同构或者异构链接起来。


https://www.xamrdz.com/database/6wc1938671.html

相关文章: