作者:天羽
我一直深信,“不是因为有了机会才争取,而是因为争取了才有机会;不是因为会了才去做,而是因为做了才能会;不是因为拥有了才付出,而是因为付出了才拥有!”
DRC是什么?
DRC(Data Replication Center)是阿里技术保障-数据库技术团队自主研发的数据流产品,支持异构数据库实时同步,数据记录变更订阅服务。为跨域实时同步、实时增量分发、异地双活、分布式数据库等场景提供产品级的解决方案。DRC在阿里服务了数万个实时通道,在刚刚过去的2015双11,DRC峰值每秒解析一千万条记录,三单元同步平均延时500毫秒。
DRC今天已经是阿里巴巴的基础设施,支持电商异地多活、大数据实时抽取、搜索实时数据、蚂蚁商户账单,甚至双11的“酷毙了”的媒体大屏等。在云上已经有上百个外部用户通过阿里云数据传输产品DTS调用DRC建立自己的容灾体系。我认为DRC是阿里数据生产到数据消费的底层基础设施,就像网络一样无处不在。
DRC是怎么做起来的?
很肯定的说,DRC是以解决数据库的痛点为出发点的,是在一次次刚需驱动下做起来的。
大家知道MySQL数据库Master到Slave的同步,一直是单线程apply。在2011年,淘宝的评价库作为一个写入大的应用,最早出现了主备延时,Slave单线程apply很容易出现主备延时,因为主库的业务写入一直是并发的,再加上我们当时都是SAS硬盘(写入性能不足)。一般这种情况只能拆库,把库拆小一点,单实例写入就少一点。
另外就是淘宝一直在做单元化项目,最早叫做“走出杭州”,我们要在北方站点A建设一个单元来跑读流量,该项目2009年是冷备,2011年开始试验流量,2012年才有正式切读流量,2013年实现淘宝最小单元化环境,2014实现近距离异地双活,到今年双11实现远距离的异地多活,大家可能都听说过了。
2011年站点A大概部署了几十台服务器,混跑全站MySQL,远距离的单线程复制就更加不可保障延时了。技术上此时有两种解法,在MySQL内部做并发apply,或者做个第3方工具模拟Slave拉数据再像应用一样并发写入Slave。我们相信在内核里解一定是未来,但因为当时对MySQL内核把控没有足够把握,就先在外面做。
DRC第一任开发者董开,在MySQL内核专家希羽的指导下,经历近半年的迭代,于2011年9月完成了第一个版本DRC 1.0。一个进程负责实时拉取MySQL日志,并且并发写入Slave,单进程干完所有的活。然后很快就发布了了DRC v1.1,解决了过多线程重复拉Slave日志以及表过滤规则正则匹配。当时的架构大概是这样的[2011年10月]。
尽管理论上解决了问题,但这个版本配置复杂,易用性和稳定性很差,加上投入不足,DBA一度质疑DRC的作用(当时我是DBA,也是这么看的)。后来数据库内核专家丁奇了解了这个需求,用MySQL框架快速实现了一个transfer,作为一个独立的MySQL进程,模拟从库拉日志,然后并发写备库。使用上相当于一个定制化的Slave,跟MySQL Slave长得几乎一样,只有部署的DBA本人才知道那是一个transfer。
当时DRC和transfer都在用,DBA在实际工作中基本是遇到延时了就临时启一个,不延时就去掉,因此只有个别DBA会用到这两个工具。站点A单元本身O记延时就大,主要是应用和搜索测试。但是因为站点A没有部署完整链路,业务都是读,没有写逻辑,无法自己失效Tair,跨域远程失效代价太大,因此需要依赖数据库日志来失效本地Tair。DRC-Tair版本7月份发布,站点A2011年8月就已经用DRC来失效Tair。
交易主库2011年12月底去O后,站点A读流量终于不依赖O记延时,开始规划2012年站点A正式跑生产流量,店铺、商品详情页等应用要支持30%的读流量,我们开始批量使用DRC用于杭州到站点A的复制。当时我们意识到这条链路是非常重要的生产依赖,开始找人才加大投入。
去IOE后大量使用MySQL,DBA开始感到不幸福了。除了运维自动化程度不够之外,还因为拆库拆表非常频繁,每次都要去通知下游,漏通知一个就会故障。而此时数据库,除了DRC同步站点A链路外,还有非常多的账号来拉取数据,搜索每天晚上全量拉数据,数仓也是按表拉全量,业务也开始使用精卫来拉数据做业务逻辑,而部分数仓实时业务也想把增量的O记版的dbsync改成MySQL版。这就意味着核心库除了前台业务外,还会有至少5个下游账号,预期还会增加。而一个业务方内部也会有很多子团队,因此拆一个库要通知十几个团队是很正常的,靠接口人发邮件,然后晚上拆库时一起熬夜改配置。上下游都很痛苦,一个漏通知就故障了。另外,数据库性能瓶颈和账号安全性也是很大问题,因为一般拉数据都是公共账号,内部多团队共用。
因此,我一直希望DRC把单进程的抓取和写入分开成两个进程,通过进程间通信做到一次抓取,多次分发,至少以后新接入不要再建账号拉数据了。这时,一个契机来了,搜索刚好也在做技术迭代、做实时搜索。DBA和搜索团队达成全改增的一致目标,2012年1月份基本确认需求。
当时DRC已经有站点A数据同步和失效Tair链路的业务,是一个选择,而另一个阿里内部的数据分发工具精卫正在同步给前台业务逻辑,数仓dbsync在同步离线抽取,但这些工具里面没有一个可以马上服务于搜索,都要经过改造。
此时DRC已经在考虑统一同步链路的设计,2012年1月的插件化设计文档,只解决各种数据库间技术差异的问题,不解决DRC数据服务问题。
刚才提到的数据库拆库要通知下游,2012年站点A的实时需求,多个账号的同时存在,都是我们必须去解决掉的。因此我们必须建设一个增量同步中心,而当时可以说没有任何工具能够同时解决这些问题,除了DRC。
因为DRC从第一天设计开始,就选择了一条最难的路,保障数据库的事务一致性,包括DDL(表结构变更)也可以进行同步或过滤。而这是其他数据同步产品第一天就想避开的,因为那样简单高效。而DBA天生就在这个坑里,绝对不能让主备不一致、或事务不完整,哪怕只是一条数据。而且DBA迫切希望以后不用通知下游了,让DRC自动适配主备切换或拆库。
后面的路该怎么走其实很清晰,但是我们首先要服务好搜索这个业务。杰睿、二败、赤天三个主力开发,玉龙负责测试,本空作为架构师,开始考虑抓取和写入对不同的数据源插件化,引入zookeeper,调研Server?Framework做集群管理和路由。中间经历好几个版本,把各模块原型都开发完了,大概5月份,整体架构已经基本完成。此时主要考虑的需求有4个:
1. 机房容灾(站点A异地实时读)
2. 搜索的增量数据同步
3. 阿里云RDS数据库版本升级的数据迁移
4. MySQL数据导入到OceanBase(集团业务上OB迁移)
DRC团队提出了三大技术前提:1).强一致性; 2).实时性(<1S) 3).强鲁棒性。全力以赴,守护这几点。
原架构:通过插件支持多种源和目的,单机版工作,需要较多运维配套。
定下搜索增量服务的目标后,当时还有很多其他的需求需要经常沟通和核对,感谢玉龙记下这些珍贵的资料。
这段时间,我很少关注DRC,但我知道在角落里,有两个人天天干到深夜。二败和杰睿为了兑现给客户的承诺,为了心中的梦想,不眠不休。这段时间,我在做DBFree运维平台,对DRC的希望是,站点A不要延时太大。另外生产上我让吉远做了个工具,可以在MySQL原生复制和DRC之间一键切换,我们靠这个应对了2012年双11的主备延时。
在开启高大上新篇章之前,我特别想说一下参与的同学。DRC在2011年作为一个工具存在,还有很多问题很难解,董开压力巨大,走了。赤天前后脚进来,一直做失效Tair链路,直到12年7月离开DRC。杰睿和二败在12年初进来,有了玉龙和本空协助,面临巨大的机遇和挑战。我经常说DRC干挂了两批人,活下来真心不容易,但有了阿里这个舞台,有了梦想的坚持,一切皆有可能。
2012年7月,DRC内部版本,实现ClusterManager原型,主要是路由功能和容灾守护,引入zookeeper,已经和现在的架构非常接近,当时杰睿有个DRC免运维的梦想。2012年11月,增量平台v1.0正式发布,支持自动主备切换,支持DDL,支持库、表、列过滤。而搜索选择DRC的最主要原因是,DRC提供了心跳信息,搜索一般只订阅几个表,如果这几个表没有新的业务写入,位点就会停止,搜索不知道是任务异常了还是没有数据。而DRC在整个库有任何写入都会推进心跳位点,搜索可以基于心跳位点做合并时间。这成为搜索选型时确定使用DRC的最核心因素。
此时DRC服务于站点AMySQL同步、Tair失效、搜索和广告增量。虽然有集群管理,但依然是单进程服务架构,三个场景的进程版本不一样,使用插件式,已经支持数据库主备切换自动联动,DBA不需要再通知上下游。
但是问题又来了,一方面,数据库已经有那么多账号各拉一份自己的数据,DBA提出DRC一个账号只能来拉一次。另一方面,搜索业务已经成功上线,我们要合并版本,为马上要来的2013淘宝最小单元化环境准备。当时的DBA负责人后羿在交给我时,就已经提出了增量中心的目标,让数据库的账号安全和稳定性有保障。
我们做了两个重要业务决定,1、做好小淘宝单元化是首要目标 2、做增量中心,收敛账号,降低实时链路维护成本(非搜索场景DBA的人工通知还在持续)。
2012年底二败预研LevelDB做数据持久化,此时一个重要人物,来自华为的时勤博士加入,接手二败已经预发的版本,做DRC Queue。2013年4月年完成开发测试,DRC具备数据持久化能力。3月份我正式带DRC了,5月延瑛加入。我们在技术上做出两个重要技术决定,1、抓取和写入作为两个进程分离,一次抓取,多次订阅,reader继续插件化不变以支持多种数据源,合并DRC版本。2、引入embedded MySQL,所有的DDL都会内部执行一遍,为单元化架构准备,保障延时情况可复原数据格式,不丢一条,不错一条。
2013年7月,DRC单元化版本发布,同步和增量版本统一。
* Feature 持久化队列引擎
* Feature支持避免增量循环复制功能
* Feature 增量数据一对多分发
* Feature 数据事务并发复制
* Feature 增量任务自动容灾
* Feature 增量任务自动主备切换
问题来了,为什么是DRC?
我深信只有足够艰苦的付出才能获得丰厚的回报。DRC从第一天就选择了一条最难的路,做的是最底层,因此才能统一链路。从一开始,DRC就是为了解决MySQL内核缺陷,DRC团队找的人,全部都是数据库内核研发背景的。最最核心的是,DRC是被DBA骂起来的,也是DBA在单元化过程中反复使用推动了迭代,没有一直在边上骂的DBA,DRC可能会取巧走偏,不会硬着头皮,把看似不可能变成可能。DRC技术上最重要的3点,也是其他数据同步产品都不具备的能力。
* 保障事务的高效并发同步,DRC申请了多项事务冲突并发算法专利。其他同步产品不保障事务,保障事务是关系数据库同步的底线。
* MetaBuilder,解决回拉历史而表结构变更的问题,保障强一致。今天给你一条binlog,你可以知道数据,但不知道格式,是bigint还是varchar。如果是实时的,可以回查DB得到表结构Meta,来获得格式并完成拼接,这就是取巧的做法,但如果不实时,回查DB时,DB已经发生过DDL,拉到的Meta不是这个日志当初产生的样子,就无解了。而DRC的内嵌MySQL会执行和同步每个DDL,因此自己实时构造着和日志相同步调的Meta信息。
* DRC的代码效率,不管是存储压缩、带宽压缩、实时性、吞吐性能,一直赶在单元化需求前面。虽然在单元化上摔过跤,但我们一直按数据库内核的质量要求保障着核心代码。
是什么成就了DRC?
如果觉得以上3点答案还不够,那么我想说我们最大的财富就是有一票DBA兄弟共同战斗。非常感谢最早天天梳理单元化逻辑到深夜的胜通,出故障时顶着压力的张瑞、云浩,做数据实时校验产品的千震、奚越。
当DRC团队在角落埋头苦干解决下面3个问题的时候,DBA就在DRC的坑里一起扛着。我一直非常认可张瑞的一句话:没有DBA,就没有DRC。
* 站点A容灾机房,2009年开始建。2011年初核心去O后MySQL出现延时, DBA经常重建Slave。
* 2011-2013,大量的MySQL,大量的下游公共账号,部分还非得拉主库,DBA主备切换或拆库,要通知10多个团队,N个邮件列表,大家一起熬夜变更,一旦出现漏通知故障就由DBA扛。
* 2013年,淘宝最小单元化环境,数据库之间双向同步,循环复制。
2013年除了淘宝最小单元化,搜索、数据仓库、阿里云RDS都已经使用DRC做同步或增量服务。我称之为DRC基础设施建设年。
2014年,异地双活,阿里云官网上云,精卫也已经接入DRC,我们提供了自动化接入能力。我称之为DRC基础设施落地年。
2015年,也就是现在,是DRC的云上服务年,通过DTS提供数据同步服务。
DRC作为数据库同步基础设施,功能更好,因为我们的对手是阿里数据生产到数据消费日益增长的需求和成本。DRC要通过规模化服务能力,做好数据质量、稳定性和成本,成为网络一样无处不在的基础设施。
当我们聚焦在单元化场景时,现有架构已经可以把分发需求的服务成本边际化掉。但今天DRC的集群规模已经很大,线上几十个集群,最大的集群有接近7000个实时任务通道,目前正在进行着新一代集群架构研发,面向未来3年,支撑单集群5万个任务的管理。
最后,我想感谢一下曾经为DRC战斗,如今已经离开战线的老战友们。