手记

由 Canal 组件分析集成中间件架构的一般过程

数据同步背景

为什么要做数据同步?因为数据很多,还要共享或做它用。举个栗子,你从移动硬盘拷贝一份小小电影到你的 Macbook 上赏析,也叫 数据同步。但系统不比你的单纯,它使用的场景千奇百怪。数据同步,不管爱与不爱,你总会遇见,它会在某个时间等你,不离不弃,不见不散

哎,不就是 A 到 B 么,一个管道,罩得住。

Canal 简介

 

要在有限的时间里漂亮的完成工作,有时候你关注的并不一定是问题中心,深挖学习了 binlog的同步方式,并不会对你的工作进度有任何改善。将它加入到研究列表中,空闲的时间去学习更佳,没必要非要把头闷在水里憋气去体验窒息的味道。好了,问题的中心数据同步,已经由阿里的工程师替你完成了,就叫 Canal,解决的是最常用的 MySQL数据库同步到别处的问题。今天我们谈一下 Canal 集成,但不谈 Canal 细节实现。周边建设别人不舍得告诉你,小姐姐和你聊。

Canal是将自己伪装成一个 MySQL从库从其他 真正的MySQL库上拉取信息,说白了就是实现了 MySQL的一套协议,数据拿过来之后,想怎么把玩就怎么玩喽。东西是好东西,但 github上的 wiki文档让人看的昏昏欲睡,既然是谈架构,那我们就聊一下如何才能让工程师放心的使用 你的Canal


数据格式

简单说下 Canal的数据格式,根据 github的官方文档就能够简单的 RUN 起来。 Canal能够同步大多数 DCL、 DML、 DDL,我们通常也就关心 INSERT、 UPDATE、 DELETE引起的变化。那 Canal解释的数据是什么样子呢,我们可以用一张图来说明

可以看到 UPDATE同时包括 变更前和 变更后的值,需要的信息就都有了。有了这些数据,上天入地,无所不能。

一个通用的架构模式就是只考虑输入和输出。使用者大多数并不关心你的系统是怎么实现的,大家都很忙,而且并不一定都有兴趣。他只需要你告诉他最终的使用方式和输出格式即可。

整体高可用

那么开发使用中有哪些元素需要参与呢?我们同样上一张图 (仅考虑集群主从模式,单机和 M/M不谈)

很 Easy 是不是? ZK控制着 HA,同时记录消费的消费进度,怎么看都和 Kafka之流一个套路。但这里有几点要说明:

1) 为了保证 binlog正常拉取,Canal 服务器同时只有一台工作,其他都是影子 lol
2) 为了保证消费能正常进行,Client 端同时只有一台能够工作,其他都是影子 lol
3) binlog推荐使用 ROW模式,但有可能一个 update语句挤爆你的内存、打碎你的蛋蛋 
4) Canal 本身没有持久化能力,非常耗内存

我们接下来按照顺序模拟它们的死亡。考虑下面一张图。

红色的区块都是可能死亡的点,ZK 会死(当然它坚挺的很),MySQL 会死,至于 Canal,也肯定不能免俗,我们要让它的死轻如鸿毛。

 

小姐姐,提醒,架构要考虑到每一个交互场景和极端情况。准备的越细,觉睡的越香。除了让挑战你的无聊者碰一鼻子灰(对,就是那些整天将 高可用挂在嘴上的货),也能节省更多时间研究些更有意义的事情。

ZK 当机

ZooKeeper那么健壮,为什么还要模拟其当机呢?因为不排除 机房断电的可能。为什么我们首先谈到 ZK?从图中可以看到 Zk 死亡对系统的影响是巨大的。当然这仅仅是概率而已,最终会推断出 SLA服务质量,满足需求即可。

当然不排除有某些强迫症的外部因素影响你去做它的高可用。除了分机房,你 也可以在代码中进行集成,比如 ZK死亡,我们去直连 Canal。你要考虑开发成本和达到的效益是否合适。

有些公司在屁都没做出来之前,就特别洁癖的关注低概率事件,问题本身倒成了次要的了。这种公司是有问题的,尽量去说服吧。

所以如果 ZK 当机问题占用你的工作量,主要是其他人的认知问题。

Canal 当机

Canal集群模式已经通过 ZK 做了 HA,你要做的,就是模拟一遍。包括:
1) 当机一台,是否有其他实例顶上来 
2) 全部当机,上线一台后是否能正常运行
3) 长时间下线后,突然上线是否有其他问题?
4) 内存问题。canal 非常耗内存,可以配置参数使其不溢出,但会产生阻塞。

Client 当机

Client 的当机其实是无所谓的。但由于实现的方式千奇百怪,也会产生千奇百怪的事情。本部分主要是使用方式问题,可以备注在注意事项里。我们通过代码来说明

1) 代码有两层 while循环,如果只有一层的话,会出问题的 (想一想问什么)
2) 代码有 ACK确认机制,代码显示的进行了确认和回滚。但如果你的处理是放在多线程里,那就有可能漏掉消息
3) 消息有 batch,所以不可避免会出现重复消费的情况,你的业务支持幂等么?

MySQL 当机

1) MySQL 重新上线后 Canal 是否能够正常拉取 binlog?
2) 主从切换后,是否需要修改 Canal? 怎么补数据?

外围扩展



要将 Canal 用起来的话,它本身只能算是一个 半成品。只有给它加上翅膀,它才能够自由飞翔。

MQ

考虑到 Canal 的堆积能力并不强。堆积数据到 10W+时,速度会变慢,并会出现假死现象。另外一个场景,就是 canal 突然上线,这时候已经延后 binlog 很多了,重新连接后会一次性获取所有数据,卡到死为止~。

对于第一个场景,一个 MQ 介入是非常有必要的。Kafka 等消息队列的堆积能力已经家喻户晓,我们要做的就是将 Canal 的数据进行一次转发。以后的客户端,打交道的就只有 MQ 了。MQ 介入后,有以下好处:

1) 获得非常好的堆积能力,可以延后消费
2) 能够方便的得到积压数据,进行监控报警
3) 不比引入 Canal 客户端,客户端开发只与 MQ 打交道即可
4) MQ 支持顺序消息,对于无时序数据而言,非顺序消息能增加处理能力

监控报警

每个节点都会出问题,所以每个节点都需要监控。监控系统也是每个公司的工具链,你可能需要写一些 zabbix或者 telegraf脚本进行数据收集(监控系统我们后续文章介绍)。

进程监控

监控各组件是否存活,java 程序发生内存溢出死亡的概率还是很大的。如果想要进程死亡后自动重启,可以考虑采用 supervisor组件。

 

BTW:如果你找不到进程的死亡原因,执行 dmesg命令,大概率会看到死亡原因。

业务监控

1) MySQL binlog 位置监控( show master status;)。
2) Canal 到 MQ 的 Sink 消费位点监控。
3) 业务消费端对于 MQ 的消费延迟监控 (delay)。

自动部署

一个好的持续集成工具能够大量减少上线时间和故障响应时间。此部分与各公司的工具链有关。比如可以使用 ansible 等命令行工具,也可以使用 jenkins 等。

这部分的工作量还是比较大的,尤其是当组件增多。有几个容易忽略的点需要考虑:
1) MySQL 主从切换时,Canal 的配置是否需要变动
2) 当单 MySQL 实例库表过多时,Canal 是否需要分开部署,维护其拓扑结构
3) 各组件启动顺序问题,是否代码做了兼容能够支持
4) 数据同步需求是否线性增长,对应 Topic 的粒度支持

迭代思路

一个使用了第三方组件的数据同步中间件产品的建设过程,大体是分为以下 6 个阶段的。很多人还停留在搭起来就 OK 的阶段。除了搭建验证读源码或者是自己造轮子,还有很多额外的事情要做,这才是架构师应该关注的事情。

基础搭建使用

可以根据文档完成一个 quickstart,并能初步应用到业务中。此时的服务基本上是裸跑,有比较多的风险。

API 封装易用

根据自己的使用场景剔除或者增加部分功能,根据自己公司的编码和代码风格,编写定制易用的 API。这可能是一个适配器,也可能是一个 spring-starter 等。还有一些坑需要进行屏蔽等,比如开源版本的 Canal 没有 GTID 等,呵呵。这个时候适当读下源码是非常有必要的。

整体高可用和应急方案

对于一个重量级的中间产品,此部分的重要度是不言而喻的。数据交互节点,每一个都应该是不信任的。仔细 CHECK 数据交互中的每一个节点,找出突发情况的应急方案。有条件的,需要线上反复演练,确保系统整体达到高可用。

报警运维机制

完成责任划分和应急处理人员,确保每一条报警信息都能快速响应,将故障影响面降低到最低。此部分涉及流程机制问题,作为架构师是有责任推进其完成的。

内部文档与系统集成

为了达到快速响应的目的,同时让产品更加平滑的加入到公司技术栈中,需要将其集成到公司内部系统中。比如定制的监控系统、持续集成系统等。同时,为了减少其他伙伴的学习使用成本,一个浅显易懂的文档也是必要的(不是 doc 哦)。对于使用中容易造成故障的点,也要指出,并不是每个人都和你一样聪明能干。

宣传应用检验阶段

如果对你的系统有信心,最大规模的使用去检验其鲁棒性是极好的。一些宣传和支持是必要的,相信到了此阶段,有大量的使用案例,不断的培养用户,对你系统的怀疑会不攻自破。

总结

架构只是做技术么?这是狭义上的理解,技术是个敲门砖。广义上的架构包括技术、流程和人。转变这个观念,愿你的事业更上一层楼。


0人推荐
随时随地看视频
慕课网APP