共计 5588 个字符,预计需要花费 14 分钟才能阅读完成。
互联网利用随着业务的倒退,局部单表数据体量越来越大,应答服务性能与稳固的思考,有做分库分表、数据迁徙的须要,本文介绍了 vivo 帐号应答以上需要的实际。
一、前言
Canal 是阿里巴巴开源我的项目,对于什么是 Canal?又能做什么?我会在后文为大家一一介绍。
在本文您将能够理解到 vivo 帐号应用 Canal 解决了什么样的业务痛点,基于此心愿对您所在业务能有一些启发。
二、Canal 介绍
1. 简介
Canal [kə’næl],译意为水道 / 管道 / 沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和生产。
晚期阿里巴巴因为杭州和美国双机房部署,存在跨机房同步的业务需要,实现形式次要是基于业务 trigger 获取增量变更。从 2010 年开始,业务逐渐尝试数据库日志解析获取增量变更进行同步,由此衍生出了大量的数据库增量订阅和生产业务。
2. 工作原理
2.1 MySQL 主备复制原理
Canal 最外围的运行机制就是依赖于 MySQL 的主备复制,咱们优先简要阐明下 MySQL 主备复制原理。
MySQL master 将数据变更写入二进制日志 (binary log, 其中记录叫做二进制日志事件 binary log events,能够通过 show binlog events 进行查看)。
MySQL slave 将 master 的 binary log events 拷贝到它的中继日志 (relay log)。
MySQL slave 重放 relay log 中事件,将数据变更反映它本人的数据。
2.2 MySQL Binary Log 介绍
MySQL-Binlog 是 MySQL 数据库的二进制日志,用于记录用户对数据库操作的 SQL 语句(除了数据查问语句)信息。
如果后续咱们须要配置主从数据库,如果咱们须要从数据库同步主数据库的内容,咱们就能够通过 Binlog 来进行同步。
2.3 Canal 工作原理
Canal 模仿 MySQL slave 的交互协定,假装本人为 MySQL slave,向 MySQL master 发送 dump 协定。
MySQL master 收到 dump 申请,开始推送 binary log 给 slave(也就是 Canal)。
Canal 解析 binary log 对象 (原始为 byte 流)。
Canal 把解析后的 binary log 以特定格局的进行推送,供上游生产。
2.4 Canal 整体架构
阐明:
- server 代表一个 canal 运行实例,对应于一个 jvm
- instance 对应于一个数据队列(1 个 server 对应 1..n 个 instance)
instance 模块:
- EventParser(数据源接入,模仿 slave 协定和 master 进行交互,协定解析)
与数据库交互模仿从库,发送 dump binlog 申请,接管 binlog 进行协定解析并做数据封装,并将数据传递至上层 EventSink 进行存储,记录 binlog 同步地位。 - EventSink(Parser 和 Store 链接器,进行数据过滤,加工,散发的工作)
数据过滤、数据归并、数据加工、数据路由存储。 - EventStore(数据存储)
治理数据对象存储,包含新 binlog 对象的写入治理、对象订阅的地位治理、对象生产胜利的回执地位治理。 - MetaManager(增量订阅 & 生产信息管理器)
负责 binlog 对象整体的公布订阅管理器,相似于 MQ。
2.5 Canal 数据格式
上面咱们来一起看下 Canal 外部封装的 Binlog 对象格局,更好的了解 Canal。
Canal 可能同步 DCL、DML、DDL。
业务通常关怀 INSERT、UPDATE、DELETE 引起的数据变更。
EntryProtocol.proto
Entry
Header
logfileName [binlog 文件名]
logfileOffset [binlog position]
executeTime [binlog 里记录变更产生的工夫戳]
schemaName [数据库实例]
tableName [表名]
eventType [insert/update/delete 类型]
entryType [事务头 BEGIN/ 事务尾 END/ 数据 ROWDATA]
storeValue [byte 数据, 可开展,对应的类型为 RowChange]
RowChange
isDdl [是否是 ddl 变更操作,比方 create table/drop table]
sql [具体的 ddl sql]
rowDatas [具体 insert/update/delete 的变更数据,可为多条,1 个 binlog event 事件可对应多条变更,比方批处理]
beforeColumns [Column 类型的数组]
afterColumns [Column 类型的数组]
Column
index [column 序号]
sqlType [jdbc type]
name [column name]
isKey [是否为主键]
updated [是否产生过变更]
isNull [值是否为 null]
value [具体的内容,留神为文本]
2.6 Canal 示例 demo
上面咱们通过理论代码逻辑的判断,查看 Binlog 解析成 Canal 对象的数据模型,加深了解
- insert 语句
- delete 语句
- update 语句
2.7 Canal HA 机制
线上服务的稳定性极为重要,Canal 是反对 HA 的,其实现机制也是依赖 Zookeeper 来实现的,与 HDFS 的 HA 相似。
Canal 的 HA 分为两局部,Canal server 和 Canal client 别离有对应的 HA 实现。
- Canal Server: 为了缩小对 mysql dump 的申请,不同 server 上的 instance 要求同一时间只能有一个处于 running,其余的处于 standby 状态。
- Canal Client: 为了保障有序性,一份 instance 同一时间只能由一个 canal client 进行 get/ack/rollback 操作,否则客户端接管无奈保障有序。
依赖 Zookeeper 的个性(本文不着重解说 zookeeper 个性,请在网络上查找对应材料):
- Watcher 机制
- EPHEMERAL 节点 (和 session 生命周期绑定)
大抵步骤:
Canal server 要启动某个 canal instance 时都先向 zookeeper 进行一次尝试启动判断 (实现:创立 EPHEMERAL 节点,谁创立胜利就容许谁启动)。
创立 ZooKeeper 节点胜利后,对应的 Canal server 就启动对应的 Canal instance,没有创立胜利的 Canal instance 就会处于 standby 状态。
一旦 ZooKeeper 发现 Canal server A 创立的节点隐没后,立刻告诉其余的 Canal server 再次进行步骤 1 的操作,从新选出一个 Canal server 启动 instance。
Canal client 每次进行 connect 时,会首先向 ZooKeeper 询问以后是谁启动了 Canal instance,而后和其建设链接,一旦链接不可用,会从新尝试 connect。
2.8 Canal 应用场景
下面介绍了 Canal 的原理与运行机制,上面咱们从理论场景来看,Canal 可能为咱们业务场景解决什么样的问题。
2.8.1 不停服迁徙
业务在倒退初期,为了疾速撑持业务倒退,很多数据存储设计较为粗放,比方用户表、订单表可能都会设计为单表,此时惯例伎俩会采纳分库分表来解决容量和性能问题。
但数据迁徙会面临最大的问题:线上业务须要失常运行,如果数据在迁徙过程中有变更,如何保证数据一致性是最大的挑战。
基于 Canal,通过订阅数据库的 Binlog,能够很好地解决这一问题。
可详见下方 vivo 帐号的不停机迁徙实际。
2.8.2 缓存刷新
互联网业务数据源不仅仅为数据库,比方 Redis 在互联网业务较为罕用,在数据变更时须要刷新缓存,惯例伎俩是在业务逻辑代码中手动刷新。
基于 Canal,通过订阅指定表数据的 Binlog,能够异步解耦刷新缓存。
2.8.3 工作下发
另一种常见利用场景是“下发工作”,当数据变更时须要告诉其余依赖零碎。
其原理是工作零碎监听数据库变更,而后将变更的数据写入 MQ/Kafka 进行工作下发。
比方帐号登记时上游业务方须要订单此告诉,为用户删除业务数据,或者做数据归档等。
基于 Canal 能够保证数据下发的精确性,同时业务零碎中不会散落着各种下发 MQ 的代码,从而实现了下发归集,如下图所示:
2.8.4 数据异构
在大型网站架构中,数据库都会采纳分库分表来解决容量和性能问题,但分库分表之后带来的新问题。
比方不同维度的查问或者聚合查问,此时就会十分辣手。个别咱们会通过数据异构机制来解决此问题。
所谓的数据异构,那就是将须要 join 查问的多表依照某一个维度又聚合在一个 DB 中。
基于 Canal 能够实现数据异构,如下图示意:
3、Canal 的装置及应用
Canal 的具体装置、配置与应用,请查阅官网文档 >\> 链接
三、帐号实际
1、实际一:分库分表
1.1 需要
- 难点:
表数据量大,单表 3 亿多。
常规定时工作迁徙全量数据,工夫长且对业务有损。
- 外围诉求:
不停机迁徙,最大化保障业务不受影响
“给在公路上跑着的车换轮胎”
1.2 迁徙计划
1.3 迁徙过程
整体过程大抵如下:
- 剖析帐号现有痛点
单表数据量过大:帐号单表 3 亿 +
用户惟一标识过多
业务划分不合理
- 确定分库分表计划
- 存量数据迁徙计划
应用传统的定时工作迁徙,时长过长,且迁徙过程中为了保证数据一致性,须要停机保护,对用户影响较大。
确定应用 canal 进行迁徙,对 canal 做充沛调研与评估,与中间件及 DBA 独特确定,可反对全量、以及增量同步。
- 迁徙过程通过开关进行管制,单表模式 → 双写模式 → 分表模式。
- 数据迁徙周期长,迁徙过程中遇到局部未能预估到的问题,进行了屡次迁徙。
- 迁徙实现后,正式切换至双写模式,即单表及分表同样写入数据,此时数据读取依然在单表模式下读取数据,Canal 依然订阅原有单表,进行数据变更。
- 运行两周后线上未产生新问题,正式切至分表模式,此时原有单表不再写入数据,即单表不会再有新的 Binlog 产生,切换后线上呈现了局部问题,即时跟进解决,“有惊无险”。
2、实际二:跨国数据迁徙
2.1 需要
在 vivo 海内业务发展初期,海内局部国家的数据存储在中立国新加坡机房,但随着海内国家法律合规要求越来越严格,特地是欧盟地区的 GDPR 合规要求,vivo 帐号应答合规要求,做了比拟多的合规革新工作。
局部非欧盟地区的国家合规要求随之变动,举例澳洲当地要求满足 GDPR 合规要求,原有存储在新加坡机房的澳洲用户数据须要迁徙至欧盟机房,整体迁徙复杂度减少,其中波及到的难点有:
- 不停机迁徙,已出货的手机用户须要能失常拜访帐号服务。
- 数据一致性,用户变更数据一致性须要保障。
- 业务方影响,不能影响现网业务方失常应用帐号服务。
2.2 迁徙计划
2.3 迁徙过程
- 在新加坡机房搭建备库,主从同步 Binlog。
- 搭建 Canal 的 server 及 client 端,同步订阅生产Binlog。
- client 端基于订阅的Binlog 进行解析,将数据加密传输至欧盟 GDPR 机房。
- 欧盟利用数据解析传输的数据,落地存储。
- 数据同步实现后运维共事帮助将下层域名的 DNS 解析转发至欧盟机房,实现数据切换。
- 察看新加坡机房 Canal 服务运行状况,没有异样后进行 Canal 服务。
- 通过业务方,帐号侧实现切换。
- 待业务方同步切换实现后,将新加坡机房的数据革除。
3、经验总结
3.1 数据序列化
Canal 底层应用 protobuf 作为数据数据列化的形式,Canal-client 在订阅到变更数据时,为 null 的数据会主动转换为空字符串,在 ORM 侧数据更新时,因判断逻辑不统一,导致最终表中数据更新为空字符串。
3.2 数据一致性
帐号本次线上 Canal-client 只有单节点,但在数据迁徙过程中,因业务个性,导致数据呈现了不统一的景象,示例大抵如下:
- 用户换绑手机号 A。
- Canal 此时在还未订阅到此 Binlog position。
- 用户又换绑手机号 B。
- 在对应时刻,Canal 生产到更新手机号 A 的 Binlog,导致用户新换绑的手机号做了笼罩。
3.3 数据库主从延时
出于数据一致性地思考(联合帐号业务数据未达到须要分库的必要性),帐号分表在同一数据库进行,即迁徙过程中分表数据一直地进行写入,加大数据库负载的同时造成了从库读取延时。
解决方案:减少速率管制,基于业务的理论状况,配置不同的策略,例如白天业务量大,能够适当升高写入速度,夜间业务量小,能够适当晋升写入速度。
3.4 监控告警
在整体数据迁徙过程中,vivo 帐号在 client 端减少了实时同步数据的繁难监控伎俩,即基于业务表基于内存做计数。
整体监控粒度较粗,包含以上数据不一致性,在数据同步实现后,未能发现异常,导致切换至分表模式下呈现了业务问题,好在逻辑数据能够通过弥补等其余伎俩补救,且对线上数据影响较小。
四、拓展思考
1、现有问题剖析
以上是基于 Canal 现有架构画出的繁难图,尽管基于 HA 整体高可用,但细究后还是会发现一些隐患,其中标记红色 X 的节点,能够视为可能呈现的故障点。
2、通用组件复用
基于以上可能呈现的问题点,咱们能够尝试做上图中的优化。
3、延展利用 - 多数据中心同步
在互联网行业,大家对“异地多活”曾经耳熟能详,而数据同步是异地多活的根底,所有具备数据存储能力的组件如:数据库、缓存、MQ 等,数据都能够进行同步,造成一个宏大而简单的数据同步拓扑,互相备份对方的数据,能力做到真正意义上 ” 异地多活”。
本逻辑不在本次探讨范畴内,大家能够参阅以下文章内容,笔者集体认为解说较为具体:http://www.tianshouzhi.com/api/tutorials/canal/404
五、参考资料
- https://github.com/alibaba/canal
- https://github.com/alibaba/otter
作者:vivo 产品平台开发团队