神州优车数据交换平台的构架、建设与疼点难点解读
优采云 发布时间: 2020-08-11 21:51讲师介绍
卢彪
神州优车集团架构部技术专家
百度百科:
数据交换平台,是指将分散建设的若干应用信息系统进行整合,通过计算机网路建立的信息交换平台,它让若干个应用子系统进行信息/数据的传输及共享,提高信息资源的利用率,成为进行信息化建设的基本目标,保证分布异构系统之间互联互通,建立中心数据库,完成数据的抽取、集中、加载、展现,构造统一的数据处理和交换。
笔者觉得,数据交换平台是建立分布式系统的三驾马车之一。这三驾马车分别是基于RPC的服务调用、基于MQ的风波驱动以及基于Data Sync的数据共享。
而驱动数据交换平台出现和发展的根本动力是:用空间换时间。
一、交换平台浅谈
1、服务场景
概括来讲,数据交换平台可以服务的场景可以分为三大类,分别是:基础构架、容灾备份和异构重塑。
基础构架
场景举例一:EDA
通过数据交换平台,把数据库Log风波(如MySQL的Binlog)发送到MQ,然后由不同的消费者进行消费,驱动不同的业务流程(如:刷新缓存、构造搜索引擎、下单以后发短信、支付以后通知发货等),基于这样的构架,免去了业务方自己定义领域风波和发送风波的工作,大大节约了工作量。
更重要的是,基于数据库自己的Log机制,数据一致性更有保证,其它例如容错处理、HA等机制也只靠数据交换平台去保证即可。
当然,如果风波定义比较复杂,普通的业务表对应的LogEvent未能抒发的话,还须要自行设计领域风波,此时我们可以定义一张通用的风波表用于保存自定义风波;而发送风波的操作对应风波表的插入操作而且随业务操作放在一个事务中,待事务递交后,交换平台拉取风波表的日志,然后提取风波内容发送到MQ即可。
通过消费数据库的Log,可做的文章非常多,我们团队内部正在研制一个风波平台,也是基于消费MySQL-Binlog来实现的,大体构架如下所示:
事件平台提供了风波订阅,事件配置(如:是实时触发下一操作还是倒计时定时触发下一操作,下一操作是插口反弹还是形成一个新的风波等),事件编排和实时监控等基础支撑,使用方只需提供配置规则和开发反弹插口即可,免去了各研制团队各自为政、重复建设的各类问题。
另外,该平台最大的一个特色就是引入了风波驱动的定时器机制,没有这样一个机制之前,涉及到时间要素相关的判定时(如:下单后多长时间未结算订单手动转为无效,租车时长超过一定时间后,结算类型手动由短租产品转为长租产品等),业务研制团队须要写大量的定时任务扫描数据库来估算时间区间,不仅开发成本巨大而且常常也存在较大的性能问题。
有了定时器机制,业务方只需配置时间规则即可,并且风波平台是分布式的,可以提供更高的性能支撑。
场景举例二:CQRS(Command Query Responsibility Segregation)
这里套用DDD领域中的一个概念CQRS,具体介绍可参考链接:
CQRS的思想本质上就是为同一份数据构建两套模型(或叫视图):
CQRS架构模式的一个开源实现是Axon-Framework,基于Axon可以建立自己的领域模型、领域风波、事件库房、查询视图等,其提供了聚合根定义、事件重放、事件消费、数据镜像等基础支撑,套用一下它的构架图如下:
理想是丰腴的现实却是肉感的,DDD提出早已很多年了,却因难于实践,绝大部分公司还是逗留在靠数据库表进行建模的阶段,但CQRS的思想是挺好的。
那么我们抛掉DDD,基于表模型来理解CQRS:数据表模型也是领域模型,只不过不是面向对象的领域模型,数据库的Log也是风波,只不过抒发能力不象DDD中的领域风波这么丰富。
基于此,靠数据库管理模型和风波,加上一个数据交换平台进行风波转发和消费,便可以建立一个广义上的CQRS构架,如下所示:
场景举例三:数据采集和回流
很多公司正在建设或则早已建设了自己的大数据平台,其中数据采集和回流是必不可少的一个环节,一般小一些的公司在数据采集这一层做的比较零散,各种开源产品堆积在一起完成采集相关的工作,而大一些的公司会考虑平台化,把数据采集放到整个数据交换平台的规划中,以便于提高效率和减少成本。
下图是我们团队的数据交换平台和大数据平台的关系*敏*感*词*:
容灾备份
场景举例一:多机房
多中心、多备份、异地双活、异地多活等是好多大公司正在实践或则早已实践过的技术困局,这中间的核心便是一整套完整的数据同步方案。
场景举例二:数据镜像
通过数据交换平台,可以创建各类类型的DB镜像,满足不同场景下的使用须要。
场景举例三:数据归档
通过增量交换,在同步过程中忽视删掉风波,可以实现实时归档。
异构构建
场景举例一:DB升级换代,迁库、拆库、合库
对DB进行升级换代,日常的迁库、拆库和合库等运维操作,就要涉及到数据迁移,如果有平台,迁移工作都会显得很简单。
场景举例二:资产复用
越大的公司,包袱也越重,很多公司拥有各类类型的数据库和储存产品,为了复用那些资产,就涉及到各类场景下的数据同步,统一的数据交换平台会使这种场景各异的同步显得容易好多。
2、建设思路
一千个读者就有一千个哈姆雷特,一千个架构师就有一千种构架思想,数据交换平台的建设也没有哪些手炮可言。不同团队面对的场景各异,进化下来的构架也就不尽相同。此处结合自己的经验和心得,谈一谈数据交换平台建设过程的一些方法论和注意事项。
架构选型
数据同步流程是生产者-消费者模式的典型彰显,生产者负责从不同的数据源拉取数据,消费者负责把数据讲到不同的数据源,生产者和消费者之间可以是1对1的关系,也可以是1对多的关系。
那么,数据交换平台就是把生产者和消费者串联上去的中枢,并且可以在串联的过程中控制流程,概括来讲就是进行数据集成。
数据集成是数据交换平台最基本的工作,架构的选型和设计应当仅仅围绕这个基本点展开,只有以便快速集成的构架能够支撑不断变化的数据同步需求。
在进行构架设计时,需要考虑的点,大致总结如下:
很多公司都在基于消息中间件建立自己的数据交换平台(有的称之为数据总线),生产者把数据发送到MQ,消费者从MQ上消费数据,并且数据可以自描述,此模式的一个典型开源实现就是Kafka-Connect,其构架图如下所示:
优点:
缺点:
不论怎样,该构架模式是太优秀的,能满足百分之六七十的应用场景。但我们团队并没有直接套用该构架,而是针对其缺点,并受Kafka-Connect思路的启发,实现了一套基于消息中间件和直连同步的混和构架,如下所示(即DataLink的构架):
在Kafka-Connect的构架中,因为要以Kafka做数据中转站,所以运行的Task要么是SourceTask、要么是SinkTask,而DataLink中的Task可以对Reader和Writer进行任意组合(理论上)。
基于这样的特点,要建立基于消息中间件的同步,组合Mq-Writer和Mq-Reader即可;要建立直连式的同步,绕过Mq直接组合源端Reader和目标Writer即可。根据不同场景选择不同模式,更加灵活。
消息中间件的方案也好,混合方案也好,针对的大部分场景都是实时增量同步(虽然也支持部份场景下的全量同步,但其实不是其主业),针对离线全量同步场景,目前你们用的最多的方案是阿里开源的DataX,有兴趣的可以研究一下。
简单总结,没有最好的构架只有最合适的构架,基于消息中间件建立数据交换平台是目前比较流行的构架模式,但它也有自身的缺点,组合各类技术,扬长避短,针对自己的问题和疼点找到适宜自己的方案才是最合理的方案。
方式方式
如果说构架选型是制订战略,那方法技巧就是具体战术。从同步行为上来换分,可以分为实时增量同步和离线全量同步。
前者的可行战术主要有触发器、日志解析和基于时间戳的数据抽取(当然,不同DB都会有自己的一些特殊方案,如Oracle的物化视图机制,SQL Server的CDC等),后者的可行战术主要有文件Dump和API抽取。
实时增量同步
先说实时增量同步。基于触发器的形式获取数据比较传统,并且由于运维冗长和性能较差等缘由,用的也越来越少。
但在个别特定场景下还是有适用空间的,有一个开源的产品代号为SymmetricDS,可以自动化管理触发器并提供统一的数据抓取和消费机制,如果想基于触发器做数据同步的话可以参考该产品。
基于日志解析的方法去做同步目前最受偏爱,像MySQL、HBase等都提供了日志重放机制,并且合同开源.
该方法的主要优点有:对业务表零侵入、异步解析日志没有性能问题、实时性比较高等。
日志解析太美好,但并不是所有DB都提供了这样的机制(如SQL Server),当触发器和日志解析都搞不定时,通过时间戳数组(如:modify_time)定时扫表,拿到变更数据并进行同步,也是常用的一种手段.
该方法有几个显著的缺点:实时性比较低、需要业务方保证时间戳数组不能出现漏更新,定时扫表查询也可能会带来一些性能问题等。
离线全量同步
再说离线全量同步。文件Dump的形式通常用在同构数据源之间的同步场景,并且须要靠DB自己的导出导入机制进行支持,可以服务的场景比较单一。API抽取的方法更通用和灵活一些,同构异构都可以编码进行实现,做的好的话,还可通过灵活的参数控制提供各类中级功能特点,如开源产品DataX。
难点问题
把数据从一个地方迁往另一个地方,怎样保证在同步过程中数据不出问题(不丢、不重、不乱)或者出现问题后能快速恢复,要考虑的点十分多也十分杂,这里结合自己的经验聊聊主要的难点以及常用的解决方案。
其一:种类繁杂的API
看上去其实也没有哪些难的,不就是调用API进行数据操作吗?其实不然,市面上的储存产品有上百种,常用的也有几十种,其产品特点是千差万别的。
为了建立一个高效可靠的平台,对这种产品的API及其内部机制进行透彻的研究是必须要做的 (如:是否支持事务?事务细度是表级别还是记录级别?是支持随机读写还是只能支持Append?操作API时有没有客户端缓存?HA是如何实现的?性能困局点在哪些地方?调优参数都有什么?自带的Replication机制是如何实现的?等等),否则平台也就仅仅逗留在能用的阶段。
拿我们自己的经历举个反例:在建设大数据平台时,需要数据交换平台把MySQL和HBase的数据实时同步到HDFS中,基于DataLink我们开发了HDFS Writer插件,在实践过程中没少趟坑。
解决这个难点问题,没有捷径,只能靠降低自身硬实力来进行突破。
其二:同步关系*敏*感*词*
对于服务框架来说,随着服务数目不断降低,我们须要服务*敏*感*词*;对于数据交换平台来说,随着同步关系的不断降低,同样须要对同步关系进行*敏*感*词*。
需要*敏*感*词*的点主要有:
避免回环同步通常加入DAG检查机制即可。
保证Schema的一致性通常有两个思路:一个是在同步过程中获取到源端的ddl句子手动同步到目标端,另一个是平台提供同步关系检查机制供外部系统使用,前者在异构数据源比较多的时侯实现上去困难比较大(脚本转换、性能问题、幂等判定等),并且不是所有的方案都能领到ddl句子,而后者更具有通用性和可行性。
目前我们内部的方案是,SQL脚本上线时,由数据交换平台进行SQL解析,然后返回同步关系树给DBA团队的DBMS系统,然后由DBMS系统根据同步关系的提示逐库执行脚本即可。
同步关系树的一个*敏*感*词*如下所示:
其三:数据质量
保证数据质量是数据交换平台的核心使命,同步过程中做到不丢、不重、不乱,通过数据巡检能迅速发觉问题;发现问题后能快速修补。
如果能把事前、事中、事后这三个阶段都控制好,那平台已然达到优秀的级别了。
事前阶段靠建立的设计和测试,事中阶段靠立体化的监控报案,事后阶段靠功能丰富的修补工具,但每位阶段实践上去都不容易,原因在于场景的灵活性和复杂性,如:
目前我们团队也还在不断探求的路上,没有绝对完美的方案,针对自己的场景和对数据一致性要求的程度,找到最合适的方案才是正解。下面借用一张图来展示数据质量的设计要点:
其四:扩展性
技术的发展是快速的,业务的演化也是千变万化的,为了应对这种变化,平台肯定也要跟随变,但如何用最小的变化带来最大的利润,是判定一个平台、一个产品成熟与否的关键指标。
笔者笃信一句谚语:架构是进化下来的,而不是设计下来的;但同时也笃信另一句谚语:好的设计是成功的一半。二者并不矛盾,主要在于如何去折中。
做平台和做工具的一个重要区别在于,前者要重点考虑具象、建模和参数化,以提供灵活的扩展性。
那么扩展性应当考虑到哪些程度呢?一句话来概括:我们在平台的建设过程中应当不断归纳、不断纠错、不断具象、不断迭代、不断推演,把已知的事情做到模型化,把未知的事情做到可预见,不做过度设计,但也要充分设计。
开源数据同步中间件中,扩展性做的比较好的:阿里的DataX不错,KafKa-Connect不错,基于触发器的SymmetricDS也不错,下文要介绍的我们近来开源的DataLink也在这方面做了好多考虑。
3、开源产品
在这里列举一下数据同步相关的开源产品,供参考学习:
二、实战项目介绍
1、DataLink项目介绍
名称: DataLink['deit lik]
译意: 数据链路,数据(自动)传输器
语言: 纯Java开发(JDK1.8+)
定位: 满足各类异构数据源之间的实时增量同步,一个分布式、可扩充的数据同步系统
开源地址:
此次开源为消除内部依赖后的版本(开源的是增量同步子系统),在集团内部DataLink和阿里的DataX还进行了深度集成,增量(DataLink)+全量(DataX)共同组成统一的数据交换平台(如果去做类比的话,DataLink可以看做增量版的DataX),平台构架如下所示:
2、项目背景
随着神州优车集团业务的高速发展,各种各样的数据同步场景应运而生,原有的系统构架未能支撑复杂多变的业务需求。所以,从2016年底开始,团队内部开始酝酿DataLink这个产品。
着眼于未来,我们的目标是构建一个新平台,满足各类异构数据源之间的实时增量同步,支撑公司业务的快速发展。在充分督查的基础之上,我们发觉,没有任何一款开源产品能轻易的满足我们的目标,每个产品都有其显著的弱项和局限性,所以最终的选项只有“自行设计”。
但自行设计并不是陡然设计,现有的数据交换平台、已有的经验、大大小小的开源产品都是我们的设计根基,与其说是自行设计,倒不如说是站在巨人的右臂上做了一次飞越。由此诞生了DataLink这样一个产品,其产品特点主要如下:
3、应用现况
DataLink从2016年12月开始立项,第一版于2017年5月份上线,在神州优车集团内部服役到如今,基本上满足了公司所有业务线的同步需求,目前内部的同步规模大体如下:
4、架构模型
基础构架
DataLink是典型的Master-Slave构架,Manager(管理节点)+Worker(工作节点),下面对基础构架的重点模块做概要介绍:
Manager
Manager是整个DataLink集群的脑部,有三个核心功能:
Group
Worker
Task
(Re-)Balance
(Re-)Balance的定义:通过一定的负载均衡策略,使Task在Worker节点上均衡的分布。(Re-)Balance的单位是Group,一个分组发生(Re-)Balance不会影响其它分组的正常运行。
发生(Re-)Balance的时机有:
Plugin
插件模型最大的意义在于前馈和复用,只须要提供一套基础框架,开发一系列同步插件,通过配置组合便可以支持“无限多”的同步场景。
插件界定为两种:Reader插件和Writer插件,插件之间通过Task串联上去。Task运行时,每个插件都有自己独立的Classloader,保证插件之间的JAR包隔离。
MySQL
DataLink的运行须要依赖各类配置信息,这些配置信息统一保存到MySQL中。DataLink在运行过程中会动态形成监控和统计数据,这些数据也统一保存到MySQL中。
存储的配置信息主要有:同步任务信息、工作节点信息、分组信息、数据源配置信息、映射规则信息、监控信息、角色权限信息等。
ZooKeeper
Manager的高可用须要依赖于ZooKeeper,通过占领和*敏*感*词*“/datalink/managers/active”节点,实现秒级Switch。
注:Worker的高可用并不依赖ZooKeeper,只要Manager才能保证高可用,Worker就是高可用的。
Task会将运行时信息注册到ZooKeeper,注册信息主要有两类:
具体介绍可参见wiki:
总体构架
概念模型
一句话概括概念模型:高度可扩充的、可对接任意存储之间数据同步的松散模型。架构选型章节对该模型已有介绍,此处不再赘言。
领域模型
Contract
契约即规范,是对不同领域内数据类型的高层具象,其在Datalink中的主要表现形式为Record,如针对关系型数据库有RdbEventRecord、针对Hbase有HRecord。
在整个产品规划中,契约处于最顶楼,无论采用何种基础设施、何种业务模型、何种开发语言,契约都是一套独立的规范。契约是联接Reader和Writer的纽带,Reader和Writer互不感知,它们通过辨识共同的契约实现数据交换。
Business Model
Business Model是对数据交换业务场景的高层具象,将不同场景的共性需求进行了归纳和总结,抽象出了一套统一的模型定义。
当然,它不是万能的,不能收录所有的需求点,并且是随着场景的增多不断演变的。但它是必须的,统一的模型具象可以支撑80%场景下的功能复用。
主要模型定义如下:
具体介绍可参见wiki:
深入领域
插件模型
插件体系:一般由两部份组成,Framework+Plugin。DataLink中的Framework主要指【TaskRuntime】,Plugin对应的是各类类型的【TaskReader&TaskWriter】。
TaskRuntime:提供了Task的高层具象、Task的运行时环境和Task的插件规范。
TaskReader&TaskWriter:一个个具体的数据同步插件,遵从Task插件规范,功能自治,和TaskRuntime完全前馈,理论上插件数目可无限扩展。
Task:DataLink中数据同步的基本单位是Task,一个Worker进程中可以运行一批Task,一个运行中的Task由一个TaskReader和起码一个TaskWriter组成,即有:
具体介绍可参见wiki:
深入插件
5、项目未来
DataLink项目借鉴了好多开源产品的思想,这里要重点谢谢的产品有:Canal、Otter、DataX、Yugong、Databus、Kafka-Connect、Ersatz。
站在巨人的右臂上,我们进行了开源,一方面回馈社区,一方面抛砖引玉。展望未来,我们希望这个项目就能活跃上去,为社区作出更大的贡献,内部的各类新特点也会尽早同步到开源版本,同时也希望有更多的人参与进来。
目前内部正在规划中的功能有:双机房(中心)同步、通用审计功能、各种同步工具和插件、实时数据库房、整个更多已有开源产品的功能特点和各类大数据构架进行深度融合等。
直播回放