背景
这篇文章主要介绍我正在开发的一个开源项目,是我差不多两年前最想做的事情,最近国庆正好有时间可以把想法写下来帮助我理清思路和帮助读者们了解这个项目。项目地址:github.com/elliotchenz…,感兴趣可以点点小星星。
在我刚刚加入现在这家公司的时候,老板分配到的任务是构建一个CDC平台。具体是做什么呢,容我一一道来。我们的是广告系统研发部门,我所在的小组只要负责B端系统的研发,在广告主创建广告之后需要把数据传给投放系统让他们把广告投放出去。那么这个数据是怎么传递过去的呢?一般来说现在比较通用的方案都是通过CDC(Change Data Capture)来解决异构数据系统之间的复制问题。 一般而言这种架构是长这样子的:
- Datasource, 比如MySQL,PGSQL之类的
- CDC/enrichment. 就举例MySQL来说,MySQL提供binlog可以让你同步数据库中发生的任何变更。很多时候你会需要做一些定制化的逻辑。这部分逻辑就是enrichment。
- 然后CDC平台处理之后的数据会被数据的接收方收到,一般是通过消息流传递这些消息。
相信你已经猜到了,我做的就是CDC/enrichment这一部份。开发这个系统的时候其实遇到了一些困难,或者说很多重复劳动堆积到一起,不过当时为了完成任务,拿到结果,时间上容不得我去做一些优化措施。这些年来其实间歇性的有思考如何优化之前遇到的问题,并且有拿出一套行之有效的方案去帮助到更多的人不必再面对我曾经遇到的问题。我遇到的问题是什么呢?
- 环境差异,我们用的是MySQL做数据存储,而MySQL的binlog格式设置需要是ROW才能为CDC服务所接受,因为别的数据格式CDC服务根本无法获取数据。而线上环境和本地环境之间的差异造成了参与这个项目的人每个人都需要有一套相关的MySQL环境。当时团队内部十几个人,导致这个服务并不是每个人都能在本地运行起来,另外本地上手这个服务可能需要折腾一两个小时的本地配置。
- 测试经验无法通用,我们的数据库表有十几二十个字段,有一些字段还是 JSON 类型,JSON字段内部还会有很多字段。并且这些数据还要经过一次定制化逻辑enrichment的加工,一方面是很难构建测试数据,比如某一列数据的设定是不可为空,在构建数据的时候你就必须给这个数据加上值,否者数据都没办法写入到数据库。再比如没有办法可以无侵入的观察到数据经过处理后的结果是什么?即便构建了测试数据,这些数据可能只能通过我们本地导出成SQL让别人倒入到他的环境去。这种方法可能并不是很通用,最后你很难知道谁哪里的数据才是标准的测试数据集,本地环境时不时给你把数据清空掉或者全部魔改一下也是有可能的,因为别人也需要测试别的业务和需求。
基于这些问题,我觉得会有一种比较通用的方式去解决,沉淀一套经验下来,后面刚上手CDC相关项目的人不再为这些而感到烦恼。这就是这篇文章的主旨。也就是我的想法,cdc-observer,可以帮助你以一种及其简单的方式构建本地数据库以及变更数据库中的数据,并且可以帮助你将CDC系统的结果打印到你标准输出流中。我的想法是什么呢?我想怎么做呢?且看我娓娓道来。
CDC-observer
其实想法很简单,环境的差异可以通过docker解决,只要大家电脑上运行的是一个镜像就可以解决环境的差异,这样可以节省所有人配置数据库相关环境的时间。至于测试经验的问题,可以将测试数据也一起打包到镜像中,这样你需要什么数据就跑对应版本的镜像即可。除此之外他应该还具有以下的功能去帮助到别人快速上手CDC系统:
-
快速构建数据库环境,当然这些修改都是对docker起来的数据库生效,并且相关的修改可以通过相应的API保存新的镜像
- 可以通过API快速搭建他想要的数据库环境
- 也可以通过简单的命令行工具去搭建数据库环境。
- 也可以直接sync一个数据库的schema
-
快速触发CDC事件,并且相关的修改可以通过相应的API保存新的镜像
-
可以通过API快速触发对应数据增删改的CDC事件,比如
- 更新 某数据库 某表,某字段
-
也可以通过简单的命令行工作去触发对应数据增删改的CDC事件
-
-
可以快速对接用户的定制化逻辑,输出经过该逻辑之后的数据结果
-
输出结果到标准输出流
架构
其实实现起来不难
- 使用docker提供的goland API镜像容器相关的操作,比如拉取镜像,构建容器,删除容器等等。
- 开发命令行工作帮助用户操作数据库和输出对应结果到标准输出流。
参考资料
- what is CDC: www.thoughtworks.com/en-au/insig…