精华内容
下载资源
问答
  • MySQL数据库读写分离中间件Atlas

    千次阅读 2017-02-17 16:12:44
    作者:朱超,奇虎360公司资深研发工程师,2011年加入公司,先后负责数据库中间件、分布式消息队列、配置管理系统等软件基础设施的设计与开发,对高性能分布式系统架构有浓厚兴趣。 本文为《程序员》原创文章,未经...

    作者:朱超,奇虎360公司资深研发工程师,2011年加入公司,先后负责数据库中间件、分布式消息队列、配置管理系统等软件基础设施的设计与开发,对高性能分布式系统架构有浓厚兴趣。
    本文为《程序员》原创文章,未经允许不得转载,更多精彩文章请订阅2017年《程序员》

    Atlas是由奇虎360公发的基于MySQL协议的数据库中间件产品,它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改了若干Bug,并增加了很多功能特性。目前该产品在360内部得到了广泛应用,覆盖80%以上的MySQL业务,每天读写量达数十亿次,于GitHub开源后,业界几十家公司将其应用于生产环境。

    Atlas项目源代码托管地址https://github.com/qihoo360/atlas

    产品研发背景

    该项目最早在2012年提出,主要为了解决两个问题:

    一是业务程序员对数据库细节关注过多。在没有中间件的情况下,应用程序直接连接MySQL的主从库,需要在配置文件中指定主从库的IP和端口,并由业务程序员自行决定将写语句和读语句分别发往主库和从库,在数据量较大的情况下还需要自行管理分库分表等技术细节,使得业务程序员负担较重。

    二是DBA运维工作不方便。数据库宕机是家常便饭,在需要切换或上下线数据库时,DBA需要协调业务程序员修改配置,运维操作也会对业务造成一定干扰,影响DBA工作顺利进行。

    我们希望能将业务与DB进行一定程度的隔离,使业务程序员尽量少关心DB的细节,可以专注于编写业务逻辑;另一方面DBA的运维操作尽量做到对业务无影响。如此则需要将读写分离、分库分表、平滑上下线DB等逻辑提炼出来,以公共组件的方式提供给以上两类人群使用。从形式上看有两种,一种是独立的中间件服务,另一种集成于客户端的LIB。前者优点是升级更新较方便,而且与语言无关,缺点是网络增加一跳,数据需要转发,性能可能不如LIB形式,后者优缺点正相反。经过权衡我们选择了前者,除以上考虑外还有部分原因是我们团队与各条业务线是独立的部门,要推动业务工程师升级LIB有相当的困难。

    开始时调研了MySQL官方的MySQL-Proxy、阿里巴巴的Cobar、Amoeba、TDDL等产品,其中MySQL-Proxy更新缓慢,长期停留在Alpha版阶段,Cobar安装部署相对复杂,Amoeba不支持事务,TDDL未完整开源。最终我们选择了MySQL-Proxy进行二次开发。

    技术架构

    部署架构

    Atlas一般搭配LVS使用,客户端通过LVS访问Atlas,以避免单点故障,当然也可以使用Keepalived等。Atlas后面挂接MySQL的一主多从集群,需要注意的是主从同步需要DBA预先配置好,Atlas只涉及客户端与DB间的网络交互,DB与DB间的通讯与Atlas无关。

    图1  读写分离架构

    图1 读写分离架构

    Atlas会把客户端发来的SQL语句根据读写分别路由到主库和从库上,对于有多台从库的情况,还会根据加权负载均衡策略决定选择哪台从库来执行每条读语句。

    线程模型

    Atlas的线程模型与Memcached相似,都是由一个主线程和若干个工作线程组成。主线程负责监听客户端的新连接,工作线程在系统启动时即创建完成,并监听管道读端的读事件。当有客户端连接到来时,主线程将客户端的IP和端口等信息封装成一个CON结构,然后选择某个工作线程来处理该客户端的请求。选择的方法可以是Round-Robin方式,也可以根据各个线程的负载情况选择负载最轻的线程(可以粗略认为待处理队列最短即为负载最轻)。主线程选定工作线程后,将CON结构放入该线程对应的待处理队列,然后向相应管道的写端写入一个字节(字节内容无所谓),则工作线程会收到管道读端的读事件,并从队列中取出CON结构,进行下一步处理。当然也可改用Linux的新系统调用eventfd实现对工作线程的唤醒,性能比管道更高。

    图2  线程模型

    图2 线程模型

    两个经典技术问题

    字符集

    MySQL支持多种字符集,字符集状态与会话(连接)绑定,即各个连接上的字符集互不相干。而Atlas拥有连接池,要求实现连接复用,这就不可避免会导致字符集混乱。

    图3  访问架构

    图3 访问架构

    如图3所示,客户端发来SET NAMES UTF8语句,Atlas从连接池里取出一个空闲连接(连接1),在连接1上执行该语句后,将连接1放回连接池。客户端再发来一条SELECT语句,Atlas又从连接池里取出一个空闲连接(连接2),连接2大概率与连接1不是同一个连接,在连接2上执行SELECT语句,而连接2并未设置UTF-8字符集,因此造成乱码。

    图4  访问架构

    图4 访问架构

    解决方案:Atlas记录每个客户端和每个连接的当前字符集状态(以一个正整数表示即可)并进行相关修正。当客户端发来SQL语句时,Atlas会检查该语句是否要设置字符集(SET NAMES或SET CHARACTER_XXX)。如某个客户端发来SET NAMES UTF8,Atlas从连接池内取出连接1并执行该语句,执行成功后,将该客户端和连接1的当前字符集均置为UTF-8。之后该客户端发来SELECT语句(或其他非SET类语句),Atlas从连接池内取出连接2,然后比较客户端的当前字符集(上步已设置为UTF-8)和连接2的当前字符集(假定为GBK),若一致则直接执行,若不一致则在SELECT前插入一条SET NAMES UTF8,将两条语句一起发给MySQL,第一条语句起到将连接2的字符集修正为UTF-8的作用,然后再执行SELECT则不会乱码。当然也可以进一步优化,就是由Atlas直接返回SET类语句的结果(OK)给客户端,省去一次与MySQL的交互过程。

    自验证

    图5  连接认证

    图5 连接认证

    图5是MySQL的连接认证示意图。

    1. Connect阶段,客户端建立与MySQL的TCP连接;
    2. HandShake阶段,MySQL向客户端发送握手包,其中携带多项信息,如服务端的特性标志、字符集等,此处我们主要关心的是其包含的20个字节的随机串;
    3. Auth阶段,客户端将握手包内的随机串取出,与自身的密码一起执行以下运算SHA1( password) XOR SHA1( “20-bytes random data from server” SHA1( SHA1( password ) ) ),得到一个加密串,加上客户端的用户名、特性标志、字符集等附加信息,组成认证包发给MySQL。
    4. Auth-Result阶段,MySQL通过在mysql.user中保存的该用户名对应的密码,也执行同样的运算得到一个加密串,并与认证包中的加密串对比,若相同则认为密码正确,返回结果OK给客户端,否则返回ERR拒绝连接。

    返回OK后应用层连接即建立完毕,接下来客户端向MySQL发送SQL语句,并从MySQL接收语句的执行结果,然后再发送下条语句……直至有一方断开连接为止。

    图6  Atlas连接访问工作原理

    图6 Atlas连接访问工作原理

    图6是1.x版本的Atlas的工作过程。

    可以看到,在连接认证阶段,Atlas简单地透传客户端与MySQL双方的通讯包。初看似乎并没有问题,但考虑到Atlas后面挂接的是一主多从多台MySQL时,情况就变得比较复杂。

    客户端向Atlas建立连接时,Atlas需要选择转而向哪台MySQL建立连接。以最简单的一主一从为例:若Atlas向主库建连接,则从库上没有连接,无法实现读写分离;若向从库建连接,则问题更严重,因为主库上没有连接,所以写语句无法执行。那么能不能同时向两台MySQL建连接呢?问题在于两台MySQL都会发送握手包,而客户端遵循MySQL协议,它不可能一次接受两个握手包……

    在1.x中,我们使用了一个取巧的办法,即在主库上预留一定数量的连接,比如32个。客户端向Atlas建立连接时,首先检查主库上的连接数是否已经达到32个,若未达到则向主库建连接,若已达到则向从库建连接。这样既保证了写语句可以在主库上执行,又使得读语句可以在从库上执行,从而正确实现读写分离。这个办法有几个潜在的问题:1. 若有多于32个客户端同一瞬间发送写语句,则主库上连接数将不够用,当然也可以让某些客户端阻塞等待其他客户端让出连接来部分解决;2. 无法支持长连接;3. 在主库连接数达到32个之前,仍然无法读写分离。

    仔细分析以上情况,可以得知,其本质原因是Atlas需要依赖客户端的连接动作转而向MySQL建连接,因此能建立连接的数量最大不超过客户端的Connect次数,这就极大地制约了Atlas作为中间件的灵活性。为了摆脱这一束缚,就要求Atlas能自主决定何时、向哪台MySQL、建立多少个连接。实现该特性的前提是,Atlas必须知悉客户端的用户名和密码,因为从1.x的交互图上可知,Atlas透传客户端的认证包给MySQL,而认证包内只有加密串而没有密码明文,也不可能反解(否则我们就破解了MySQL的加密协议)。

    图7  Atlas 连接访问工作原理

    图7 Atlas 连接访问工作原理

    图7是2.x版本Atlas的工作过程。

    用户名和密码事先已经作为配置在Atlas启动时加载进来(当然也可以通过Atlas的管理接口进行动态的增删改查)。当客户端来连接Atlas时,Atlas自行产生一个握手包(包含20字节随机串)发给客户端,然后接收客户端发来的认证包,根据配置的用户名和密码进行加密计算并检查结果,根据结果正确与否返回OK或ERR给客户端,从而完成客户端的连接认证工作。客户端发来SQL语句时,Atlas检查连接池中是否有空闲连接,若有则直接使用,若没有则根据配置的用户名和密码自行向MySQL建立新连接,然后供该语句使用。

    此方案的优点:真正完全的读写分离,支持长连接,连接按需建立,连接数随并发度上升而增加,随并发度下降而减少(可以依靠MySQL的wait_timeout,也可以由Atlas监控连接的空闲时间)。

    小结

    从以上内容可以看出,MySQL中间件产品的设计与开发需要对相关协议有比较深入的了解,且因MySQL数据库软件自身的升级,协议还可能随之改变。限于篇幅,还有不少功能点不能一一细述,有兴趣者可查阅项目源码托管平台上的资源。

    SDCC 2017·上海站将于2017年3月17-19日登陆申城,三大技术峰会和24位嘉宾,汇聚国内知名的互联网公司CTO、架构师、技术总监,畅谈运维、数据库和架构的热门话题和技术热点,遇见精益运维发起人&优维科技CEO王津银、MongoDB大中华区首席架构师唐建法和华为软件API开放平台架构师李林锋等大牛。截止3月5日前门票八折优惠中,5人以上团购立减400元,详情点击注册参会

    展开全文
  • 数据库中间件

    千次阅读 2017-12-11 23:52:49
    这里主要介绍互联网行业内有关数据库的相关中间件数据库相关平台主要解决以下三个方面的问题: 为海量前台数据提供高性能、大容量、高可用性的访问为数据变更的消费提供准实时的保障高效的异地数据同步 应用层...

    这里主要介绍互联网行业内有关数据库的相关中间件。数据库相关平台主要解决以下三个方面的问题:

    • 为海量前台数据提供高性能、大容量、高可用性的访问
    • 为数据变更的消费提供准实时的保障
    • 高效的异地数据同步

    应用层通过分表分库中间件访问数据库,包括读操作(Select)和写操作(update, insert和delete等,DDL, DCL)。写操作会在数据库上产生变更记录,MySQL的变更记录叫binlog, Oracle的称之为redolog, 增量数据订阅与消费中间件解析这些变更,并以统一的格式保存起来,下层应用根据这些数据进行消费应用。当然,在数据库与数据库本身之间也会有数据库迁移的操作,这种操作可以不需要增量数据订阅与消费中间件的数据,而可以自行处理。

    数据库中间件有以下几种:

    • 分布式数据库分表分库
    • 数据增量订阅与消费
    • 数据库同步(全量、增量、跨机房、复制)
    • 跨数据库(数据源)迁移

    整个产品族图如下:

    • 最上层的是分布式数据库分表分库中间件,负责和上层应用打交道,对应用可表现为一个独立的数据库,而屏蔽底层复杂的系统细节。分布式数据库中间件除了基本的分表分库功能,还可以丰富一下,比如讲读写分离或者水平扩容功能集成在一起,或者比如读写分离本身也可以作为一个独立的中间件。(Cobar, MyCAT, TDDL, DRDS, DDB)
    • 增量数据订阅和消费,用户对数据库操作,比如DML, DCL, DDL等,这些操作会产生增量数据,下层应用可以通过监测这些增量数据进行相应的处理。典型代表Canal,根据MySQL的binlog实现。也有针对Oracle(redolog)的增量数据订阅与消费的中间件。(Canal, Erosa)
    • 数据库同步中间件涉及数据库之间的同步操作,可以实现跨(同)机房同步以及异地容灾备份、分流等功能。可以涉及多种数据库,处理之后的数据也可以以多种形式存储。(Otter, JingoBus, DRC)
    • 数据库与数据库之间会有数据迁移(同步)的动作,同款数据同步原理比较简单,比如MySQL主备同步,只要在数据库层进行相应的配置既可,但是跨数据库同步就比较复杂了,比如Oracle->MySQL. 数据迁移一般包括三个步骤:全量复制,将原数据库的数据全量迁移到新数据库,在这迁移的过程中也会有新的数据产生;增量同步,对新产生的数据进行同步,并持续一段时间以保证数据同步;原库停写,切换新库。将“跨数据库”这个含义扩大一下——“跨数据源”,比如HDFS, HBase, FTP等都可以相互同步。(yugong, DataX)

    分布式数据库

    随着互联网产品在体量和规模上日益膨胀,无论是Oracle还是MySQL,都会第一时间面临来自磁盘,CPU和内存等单机瓶颈,为此,产品方除了需要不断购买成本难以控制的高规格服务器,还要面临不断迭代的在线数据迁移。在这种情况下,无论是海量的结构化数据还是快速成长的业务规模,都迫切需要一种水平扩展的方法将存储成本分摊到成本可控的商用服务器上。同时,也希望通过线性扩容降低全量数据迁移对线上服务带来的影响,分库分表方案便应运而生。

    分表分库类的中间件主要有两种形式向应用提供服务:

    • 一种是以JDBC的jar包形式为Java应用提供直接依赖,Java应用通过提供的JDBC包实现透明访问分布式数据库集群中的各个分库分表,典型代表网易的DDB和阿里的TDDL.
    • 另一种是为应用部署独立的服务来满足应用分库分表的需求,在这种方式下通过标准JDBC访问Proxy,而Proxy则根据MySQL标准通信协议对客户端请求解析,还原应用SQL请求,然后通过本地访问数据库集群,最后再将得到的结果根据MySQL标准通信协议编码返回给客户端。典型代表阿里的Cobar, Cobar变种MyCAT, 阿里的DRDS,网易的DDB proxy模式以及DDB的私有云模式。

    Cobar

    Cobar 是提供关系型数据库(MySQL)分布式服务的中间件,它可以让传统的数据库得到良好的线性扩展,并看上去还是一个数据库,对应用保持透明。

    Cobar以Proxy的形式位于前台应用和实际数据库之间,对前台的开放的接口是MySQL通信协议。将前台SQL语句变更并按照数据分布规则发到合适的后台数据分库,再合并返回结果,模拟单库下的数据库行为。

    Cobar属于阿里B2B事业群,始于2008年,在阿里服役3年多,接管3000+个MySQL数据库的schema,集群日处理在线SQL请求50亿次以上。由于Cobar发起人的离职,Cobar停止维护。后续的类似中间件,比如MyCAT建立于Cobar之上,包括现在阿里服役的RDRS其中也复用了Cobar-Proxy的相关代码。

    Cobar结构

    • 与应用之间通过MySQL protocol进行交互,是一个proxy的结构,对外暴露jdbc:mysql://CobarIP:port/schema。对应用透明。
    • 无需引入新的jar包,从访问迁移到数据库访问Cobar可以复用原有的基于JDBC的DAO。
    • Cobar前后端都实现了MySQL协议,当接受到SQL请求时,会一次进行解释(SQL Parser)和路由(SQL Router)工作,然后使用SQL Executor去后端模块获取数据集(后端模块还负责心跳检查功能);如果数据集来自多个数据源,Cobar则需要把数据集进行组合(Result Merge),最后返回响应。
    • 数据库连接复用。Cobar使用连接词与后台真是数据库进行交互。(实际应用中,根据应用的不同,使用proxy结构后数据库连接数能够节约2-10倍不等。)
    • Cobar事务,Cobar在单库的情况下保持事务的强一致性,分库的情况下保持事务的弱一致性,分库事务采用2PC协议,包括执行阶段和提交阶段。

    Cobar的前端是NIO的,而后端跟MySQL交互是阻塞模式,其NIO代码只给出了框架,还没有来得及实现。 据称未开源版的Cobar实现了后端的NIO。
    Cobar会出现假死,假死以后Cobar会频繁进行主从切换(如果配置了的话),自动切换本身也存在隐患。
    可以计算:Cobar的TPS=5,000,000,000/(3000*24*60*60)=20。

    与Cobar相关的还有一共Cobar-Client.

    Cobar通过SQL语句转发的方式实现数据访问。用户发来的SQL语句,Cobar解析其内容,判断该语句所涉及的数据分布在哪个分库上,再将语句转发给此分库执行。当SQL语句中涉及的拆分字段有多值,如 IN, 或where条件中没有出现拆分字段时,该语句将会转发至后台所有分库执行,再将执行结果以MySQL协议包的形式送回应用端。

    通信模块,负责从连续的网络数据流中识别出一个个MySQL协议包,再解析协议包识别出SQL语句输出给Parser模块,同时,把Result Merge模块输入的执行结果,编码成MySQL的协议包。它以NIO方式实现,有很高的执行效率。之后进行优化,引入了一个ByteBuffer池,将NIO的Buffer统一管理起来,减少了NIO数据交互时的垃圾回收。

    Cobar前端使用的是优化后的NIO通信模块,为了让该模块在后端使用,Cobar去除了JDBC。与后端数据库交互,Cobar直接面向协议,目前实现了基于MySQL协议的后端交互。

    水平拆分后,后台有多个数据源,对他们的管理分为两个层次:DataNode和replica(HA Pool)。
    DataNode管理拆分,一个DataNode存放一个分片的数据,彼此无数据交集。每个分片的数据存多份以保证高可用,每一份叫做一个replica,由HA层管理。每一个replica表示一个具体的数据源,它是一个连接池,池内管理每一个具体的JDBC连接。路由运算只关注到DataNode层,之下的层次对其不可见。
    每一份replica之间的数据复制和同步由MySQL本身的replication协议完成,同一时刻只有一个replica提供服务(称为Master,其余replica称为Slave).Cobar会与之保持心跳,一旦发现它不可用,会切换至另一个replica,解决Oracle单点的第二个问题。

    为了节省数据库的机器数量,可以采用下图中的方式部署:

    HA

    在用户配置了MySQL心跳的情况下,Cobar可以自动向后端连接的MySQL发生心跳,判断MySQL运行状况,一旦运行出现异常,Cobar可以自动切换到备机工作,但需要强调的是:

    1. Cobar的主备切换有两种触发方式,一种是用户手动触发,一种是Cobar的心跳语句检测到异常后自动触发。那么,当心跳检测到主机异常,切换到备机,如果主机恢复了,需要用户手动切回主机工作,Cobar不会在主机恢复时自动切换回主机,除非备机的心跳也返回异常。
    2. Cobar只检查MySQL主备异常,不关心主备之间的数据同步,因此用户需要在使用Cobar之前在MySQL主备上配置双向同步,详情可以参阅MySQL参考手册。

    Cobar解决的问题

    分布式:Cobar的分布式主要是通过将表放入不同的库来实现。

    1. Cobar支持将一张表水平拆分成多份分别放入不同的库来实现表的水平拆分
    2. Cobar也支持将不同的表放入不同的库
    3. 多数情况下,用户将以上两种方式混合使用

    这里需要强调的是,Cobar不支持将一张表,例如test表拆分成test_1, test_2, test_3….放在同一个库中,必须拆分后的表分别放入不同的库来实现分布式。

    Cobar的约束

    1. 不支持跨库情况下的join、分页、排序、子查询操作
    2. SET语句执行会被忽略,事务和字符集设置除外
    3. 分库情况下,insert语句必须包括拆分字段列名
    4. 分库情况下,update语句不能更新拆分字段的值
    5. 不支持SAVEPOINT操作
    6. 暂时只支持MySQL数据节点
    7. 使用JDBC时,不支持rewriteBatchedStatements=true参数设置(默认为false)
    8. 使用JDBC时,不支持useServerPrepStmts=true参数设置(默认为false)
    9. 使用JDBC时,BLOB, BINARY, VARBINARY字段不能使用setBlob()或setBinaryStream()方法设置参数

    MyCAT

    从定义和分类看,它是一个开源的分布式数据库系统,是一个实现了MySQL协议的Server,前端用户可以把它看做是一个数据库代理,用MySQL客户端工具和命令行访问,而其后端可以用MySQL Native Protocol与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。

    MyCAT发展到目前的版本,已经不是一个单纯的MySQL代理了,它的后端可以支持MySQL, SQL Server, Oracle, DB2, PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储,未来还会支持更多类型的存储。

    MyCAT是一个强大的数据库中间件,不仅仅可以用作读写分离,以及分表分库、容灾管理,而且可以用于多租户应用开发、云平台基础设施,让你的架构具备很强的适应性和灵活性,借助于即将发布的MyCAT只能优化模块,系统的数据访问瓶颈和热点一目了然,根据这些统计分析数据,你可以自动或手工调整后端存储,将不同的表隐射到不同存储引擎上,而整个应用的代码一行也不用改变。

    MyCAT是在Cobar基础上发展的版本,两个显著提高:

    • 后端由BIO改为NIO,并发量有大幅提高;
    • 增加了对Order By, Group By, Limit等聚合功能(虽然Cobar也可以支持Order By, Group By, Limit语法,但是结果没有进行聚合,只是简单返回给前端,聚合功能还是需要业务系统自己完成)

    MyCAT架构

    • 事务是弱XA
    • MyCAT的原理中最重要的一个动词是“拦截”,它拦截了用户发来的SQL语句,首先对SQL语句做了一些特定的分析:如分片分析,路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
    • MyCAT对自身不支持的SQL语句提供了一种解决方案——在要执行的SQL语句前添加额外的一段由注解SQL组织的代码,这样SQL就能正确执行,这段代码称之为“注解”。注解的使用相当于对MyCAT不支持的SQL语句做了一层透明代理转发,直接交给目标的数据节点进行SQL语句执行。
    • MyCAT自身有类似其他数据库的管理监控方式,可以通过MySQL命令行,登录管理端口(9066)执行相应的SQL进行管理,也可以通过jdbc的方式进行远程连接管理。

    HA

    MyCAT作为一个代理层中间件,MyCAT系统的高可用设计到MyCAT本身的高可用以及后端MySQL的高可用. 在多数情况下,建议采用MySQL主从复制高可用性配置并交付给MyCAT来完成后端MySQL节点的主从自动切换。

    MySQL侧的HA

    • MySQL节点开启主从复制的配置方案,并将主节点配置为MyCAT的dataHost里的writeNode,从节点配置为readNode,同时MyCAT内部定期对一个dataHost里的所有writeHost与readHost节点发起心跳检测。
    • 正常情况下,MyCAT将第一个writeHost作为写节点,所有的DML SQL会发送此节点。
    • 若MyCAT开启了读写分离,则查询节点会根据读写分离的策略发往readHost(+writeHost)执行。
    • 如果第一个writeHost宕机,MyCAT会在默认的三次心跳检测失败后,自动切换到下一个可用的writeHost执行DML SQL语句
    • 当原来配置的MySQL写节点宕机恢复后,作为从节点,跟随新的主节点,重新配置主从同步。

    MyCAT自身的HA

    • 官方建议是采用基于硬件的负载聚亨或者软件方式的HAproxy等。
    • 如果还担心HAproxy的稳定性和但节点问题,则可以用keepalived的VIP的浮动功能,加以强化。

    MyCAT功能和特性

    • 支持SQL 92标准
    • 支持Mysql集群,可以作为Proxy使用
    • 支持JDBC连接多数据库
    • 支持NoSQL数据库
    • 支持galera sfor mysql集群,percona-cluster或者mariadb cluster,提供高可用性分片集群
    • 自动故障切换,高可用性
    • 支持读写分离,支持MySQL双主多从,以及一主多从的模式
    • 支持全局表,数据自动分片到多个节点,用于高效表关联查询
    • 支持一致性Hash分片,有效解决分片扩容难题
    • 多平台支持,部署和试试简单
    • 支持Catelet开发,类似数据库存储过程,用于跨分片复杂SQL的人工智能编码实现
    • 支持NIO与AIO两种网络通信机制,windows下建议AIO,Linux下目前建议NIO
    • 支持MySQL存储过程调用
    • 以插件的方式支持SQL拦截和改写
    • 支持自增长逐渐、支持Oracle的Sequence机制
    • 支持Mysql, MongoDB,Oracle, SQL Server, Hive, DB2, PostgreSQL等。

    MyCAT目前的项目

    • MyCAT-Server:MyCAT核心服务
    • MyCAT-Spider:MyCAT爬虫技术
    • MyCAT-ConfigCenter:MyCAT配置中心
    • MyCAT-BigSQL:MyCAT大数据处理(暂未更细)
    • MyCAT-Web:MyCAT监控及web(新版开发中)
    • MyCAT-Balance:MyCAT负载均衡(暂未更细)

    DRDS/TDDL

    alibaba. Distributed Relational Database Service.

    阿里分布式数据库DRDS的前身是淘宝分布式数据库层TDDL,大概在2012年的时候,阿里开始尝试将TDDL这套体系输出到阿里云上,也有了一个新的名字:DRDS.

    TDDL

    Tabao根据自己的业务特点开发了TDDL(Tabao Distributed Data Layer, 外号:头都大了)。主要解决了分库分表对应用的透明化以及异构数据库之间的数据复制,它是一个基于集中式配置的jdbc datasourcce实现,具有主备,读写分离,动态数据库配置等功能。

    TDDL并非独立的中间件,只能算作中间层,是以Jar包方式提供给应用调用。属于JDBC Shard的思想。

    TDDL处于业务层和JDBC层中间。

    TDDL其实主要可以划分为3层架构,分别是Matrix层,Group层和Atom层。Matrix层用于实现分库分表逻辑,底层多个Group实例。而Group和Atom共同组成了动态数据源,Group层实现了数据库的Master/Slave模式的写分离逻辑,底层持有多个Atom实例。最后Atom层(持有数据源)实现数据库ip, port, password, connectionProperties等信息的动态推送,以及持有院子的数据源分离的JBoss数据源。

    TDDL社区处于停滞状态,网上可查资源也较少。

    RDRS

    DRDS/TDDL是阿里巴巴自主研发的分布式数据库服务。DRDS脱胎于阿里巴巴开源的Cobar分布式数据库引擎,吸收了Cobar核心的Cobar-Proxy源码,实现了一套独立的类似MySQL-Proxy协议的解析端,能够对传入的SQL进行解析和处理,对应用程序屏蔽各种复杂的底层DB拓扑结构,获得单机数据库一样的使用体验,同时借鉴了淘宝TDDL丰富的分布式数据库实践经验,实现了对分布式Join支持,SUM/MAX/COUNT/AVG等聚合函数支持以及排序等函数支持,通过异构索引、小表广播等解决分布式数据库使用场景下衍生出的一系列问题,最终形成了完整的分布式数据库方案。

    DRDS在整个阿里系统中所处的位置:

    对于很多应用而言,单机数据库最终都会碰到单机性能上的天花板,在TPS/QPS/内存容量/磁盘容量等等一系列系统资源上会碰到各类限制。DRDS的主要目标就是帮您解决这方面的各类问题,他主要提供了两个功能,读写分离和数据库切分:

    • 读写分离,能够运行实现一台机器写入,多台机器读取,这对于读多写少的应用,能够以极低的成本解决系统的瓶颈。
    • 数据库切分是一个解决系统存储瓶颈的最终极解决方案,数据库切分的核心思想其实很简单,就是分而治之。将数据分散到多台机器,并保证请求能够平均的分发到这些机器上,就可以以极低的成本来解决业务的各类性能瓶颈。当然切分也是有代价的,最明显的代价就是,分布式数据库会对一些原有单机数据的场景进行限制,因为这些操作,在分布式环境下的延迟或效率非常低效,就算是能够实现出来,也会因为性能问题而无法使用。

    其他功能特性

    1.分布式MySQL执行引擎

    主要目标是实现与单机数据库SQL引擎的完全兼容,实现SQL的智能下推,能够智能分析SQL,解析出那些SQL可以直接下发,那些SQL需要进行优化改造,优化成什么样,以及路由到哪些实例节点上执行,充分发挥数据库实例的全部能力,减少网络之间的数据传输量,最终对不同实例处理后的少量结果进行聚合计算返回给应用调用方。这就是分布式SQL引擎的智能下推功能。
    分布式引擎的职责包含SQL解析,优化,执行和合并四个流程。

    支持市面上几乎所有的语言(具有MySQL访问能力的),兼容90%以上MySQL语法。

    案例分析:
    比如一个简单的AVG操作,对于一些比较初级的分布式数据库模型而言,常见做法是把AVG直接下发到所有存储节点,这样造成的结果就是语法兼容,语义不兼容,最终拿到的是错误结果。而DRDS的智能下推引擎,对SQL的语法做充分的语义兼容性适配,针对AVG操作,只能由引擎将逻辑AVG SQL解析优化为SUM和COUNT的SQL然后进行下推,由底层的数据库实例节点完成SUM和COUNT计算,充分利用底层节点的计算能力,在引擎层将各个存储节点的SUM和COUNT结果聚合计算,最终计算出AVG。

    2.在线平滑扩容

    在线数据扩容的重点在于“在线”两字,也就是用户不需要停止业务进行割接操作,直接就可以添加新的RDS节点到集群中,实现无缝的自由扩展。RDRS则将整个扩容过程分为几个阶段,包括全量迁移,增量同步,切换数据库等几个步骤。数据会提前进行搬迁,并进行增量并行同步一段时间,因此,我们可以在非常短的时间内(秒级别)完成数据库的最终扩容切换工作,对业务没有影响。

    3.小表广播

    在一些大的业务表进行了切分后,总会存在一些表的数据量不大,更新量也不大的原始信息表。这些表往往会与我们的切分后大表进行join操作,这种操作物理上就会造成分布式join查询,效率从整体上会比较地下。针对这种分布式join的场景,开发了OETL专用工具来进行小表广播,将原信息表的所有数据(包括增量更新)全部自动的广播到大表的机器上,这样,就可以让原来的分布式查询变成单机本地查询了。

    4.全局唯一ID

    DRDS sequence功能的目标只是为了保证数据的全局唯一,虽然基本上是按时间序列获取的,但并不全局有序。

    5.异构索引

    解决分布式场景下数据拆分维度和数据查询使用维度不一致导致的低效问题。

    当数据表被拆分为多个分库分表时,数据在分库分表的分布规则就固定了。但是通常数据的业务使用场景非常复杂,如果数据的查询维度和数据拆分分布的规则一直,单条SQL会在一个分库分表上执行;如果数据的查询使用维度和数据拆分分布的规格不一致,单条SQL可能在多个分库分表上执行,出现跨库查询,跨库查询会增加IO成本,查询效率必然下降。

    解决这个问题的思路还是分布式数据库的一贯原则,让SQL执行在单库上完成,实际采用的方式就是用“空间换效率”的方案,也就是将同一份数据表,冗余存储多份,按照不同的业务使用场景进行拆分,保持拆分维度和使用维度统一,而多份数据之间会实时数据复制以解决数据一致性问题,这就是“异构索引”方案。当然异构索引表不能无限制滥用,过多的异构索引表会影响同步效率,对源数据表造成同步压力。

    其他同款中间件

    Altas, Vitess, Heisenberg, CDS, DDB, OneProxy等等。

    Atlas

    Qihoo 360.
    Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目,它是在mysql-proxy 0.8.2版本上对其进行优化,增加了一些新的功能特性。
    Atlas是一个位于应用程序与MySQL之间,它实现了MySQL的客户端和服务端协议,作为服务端与应用程序通讯,同时作为客户端与MySQL通讯。它对应用程序屏蔽了DB的细节。
    Altas不能实现分布式分表,所有的字表必须在同一台DB的同一个DataBase里且所有的字表必须实现建好,Altas没有自动建表的功能。

    Heisenberg

    Baidu.
    其优点:分库分表与应用脱离,分库表如同使用单库表一样,减少db连接数压力,热重启配置,可水平扩容,遵守MySQL原生协议,读写分离,无语言限制,mysqlclient, c, Java都可以使用Heisenberg服务器通过管理命令可以查看,如连接数,线程池,结点等,并可以调整采用velocity的分库分表脚本进行自定义分库表,相当的灵活。
    (开源版已停止维护)

    CDS

    JD. Completed Database Sharding.
    CDS是一款基于客户端开发的分库分表中间件产品,实现了JDBC标准API,支持分库分表,读写分离和数据运维等诸多共,提供高性能,高并发和高可靠的海量数据路由存取服务,业务系统可近乎零成本进行介入,目前支持MySQL, Oracle和SQL Server.
    (架构上和Cobar,MyCAT相似,直接采用jdbc对接,没有实现类似MySQL协议,没有NIO,AIO,SQL Parser模块采用JSqlParser, Sql解析器有:druid>JSqlParser>fdbparser.)

    DDB

    猪场. Distributed DataBase.
    DDB经历了三次服务模式的重大更迭:Driver模式->Proxy模式->云模式。

    • Driver模式:基于JDBC驱动访问,提供一个db.jar, 和TDDL类似, 位于应用层和JDBC之间.
    • Proxy模式:在DDB中搭建了一组代理服务器来提供标准的MySQL服务,在代理服务器内部实现分库分表的逻辑。应用通过标准数据库驱动访问DDB Proxy, Proxy内部通过MySQL解码器将请求还原为SQL, 并由DDB Driver执行得到结果。
    • 私有云模式:基于网易私有云开发的一套平台化管理工具Cloudadmin, 将DDB原先Master的功能打散,一部分分库相关功能集成到proxy中,如分库管理、表管理、用户管理等,一部分中心化功能集成到Cloudadmin中,如报警监控,此外,Cloudadmin中提供了一键部署、自动和手动备份,版本管理等平台化功能。

    数据增量订阅与消费

    基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了mysql.
    有关数据增量订阅与消费的中间件回顾一下:

    • 增量订阅和消费模块应当包括binlog日志抓取,binlog日志解析,事件分发过滤(EventSink),存储(EventStore)等主要模块。
    • 如果需要确保HA可以采用Zookeeper保存各个子模块的状态,让整个增量订阅和消费模块实现无状态化,当然作为consumer(客户端)的状态也可以保存在zk之中。
    • 整体上通过一个Manager System进行集中管理,分配资源。

    Canal

    Canal架构图:

    说明:

    • server代表一个canal运行实例,对应于一个jvm
    • instance对应于一个数据队列 (1个server对应1..n个instance)

    instance模块:

    • eventParser (数据源接入,模拟slave协议和master进行交互,协议解析)
    • eventSink (Parser和Store链接器,进行数据过滤,加工,分发的工作)
    • eventStore (数据存储)
    • metaManager (增量订阅&消费信息管理器)

    说明:一台机器下部署一个canal,一个canal可以运行多个instance(通过配置destinations等), 一般情况下一个client连接一个instance(每个instance可以配置standby功能), 可以多个client连接同一个instance,但是同一时刻只能有一个client消费instance的数据,这个通过zookeeper控制。


    数据库同步

    Otter

    背景:alibaba B2B因为业务的特性,卖家主要集中在国内,买家主要集中在国外,所以衍生出了杭州和美国异地机房的需求,同时为了提升用户体验,整个机房的架构为双A,两边均可写,由此诞生了otter这样一个产品。

    otter第一版本可追溯到04~05年,此次外部开源的版本为第4版,开发时间从2011年7月份一直持续到现在,目前阿里巴巴B2B内部的本地/异地机房的同步需求基本全上了otter4。

    基于数据库增量日志解析,准实时同步到本地机房或异地机房的mysql/oracle数据库,一个分布式数据库同步系统。

    工作原理

    原理描述

    1. 基于Canal开源产品,获取数据库增量日志数据。
    2. 典型管理系统架构,manager(Web管理)+node(工作节点)
      • manager运行时推送同步配置到node节点
      • node节点将同步状态反馈到manager上
    3. 基于zookeeper,解决分布式状态调度的,允许多node节点之间协同工作。

    Otter的作用

    1. 异构库
      • mysql->mysql、oracle. (目前开原版只支持mysql增量,目标库可以是mysql或者oracle,取决于canal的功能)
    2. 单机房同步(数据库之间RTT(Round-Trip Time)<1ms)
      • 数据库版本升级
      • 数据表迁移
      • 异步二级索引
    3. 跨机房同步(比如阿里巴巴国际站就是杭州和美国机房的数据库同步,RTT>200ms)
      • 机房容灾
    4. 双向同步
      • 避免回环算法(通用的解决方案,支持大部分关系型数据库)
      • 数据一致性算法(保证双A机房模式下,数据保证最终一直性)
    5. 文件同步
      • 站点镜像(进行数据复制的同时,复制关联的图片,比如复制产品数据,同事复制产品图片)

    单机房复制示意图

    说明:
    - 数据On-Fly, 尽可能不落地,更快的进行数据同步。(开启node load balance算法, 如果Node节点S+ETL落在不同的Node上,数据会有个网络传输过程)
    - node节点可以有failover/loadBalancer.

    SETL

    S: Select
    为解决数据来源的差异性,比如接入canal获取增量数据,也可以接入其他系统获取其他数据等。

    E: Extract

    T: Transform

    L: Load

    类似于数据仓库的ETL模型,具体可为数据join,数据转化,数据加载。

    跨机房复制示意图

    数据涉及网络传输,S/E/T/L几个阶段会分散在2个或者更多Node节点上,多个Node之间通过zookeeper进行协同工作(一般是Select和Extract在一个机房的Node, Transform/Load落在另一个机房的Node)
    node节点可以有failover/loadBalancer。(每个机房的Node节点,都可以是集群,一台或者多台机器)

    More:

    异地双活数据架构基础设施DRC

    所谓DRC,就是Data Replication Center的缩写,数据复制中心。这种复制是同步的,支持异构的,高可用的(有严格容灾系统,实时性好),支持订阅分发的。项目期初是为了淘宝异地容灾而成立的,用于数据库之间主备同步,后来采用这套技术方案衍生出了DRC-TAIR, DRC-DUMP等项目。

    所谓异地双活主要关注两件事,一个数据同步,一个数据分发。

    到底怎样的应用会需要异地的双活?比较常见的场景有三个:

    1. 两个地域或多个地域都有大量用户的场景,比如在中国的用户希望他们用杭州的RDS服务,在美国的用户用美国的RDS服务,这就需要数据在异地同步。很多游戏,金融,传媒,电商业务都有这种需求。满足这个需求的难点在于跨地域的网络,比如网络延时长,丢包多,而且数据在公网传输会有数据泄露风险。
    2. 数据来源较多,需要介入各种异构数据的场景。比如一个应用需要从ODPS, RDS, OTS, OceanBase, PostgreSQL这几个服务介入数据,他们的数据结构和接口都不同,这种接入的成本会比较高。因此另一个可用的方法是数据写入的时候就一份多谢为不同数据结构
    3. 下游订阅很多的情况,比如一份数据,备份系统、通知系统、大数据分析系统、索引系统等等都要来取,如果用上面一份数据多写的方案是可以应对的,但这里还有其他难点,就是数据一致性、可扩展性、跨网同步稳定性、以及同步的实时性。

    DRC支持读取集团MySQL, RDS, OceanBase, HBase, Oracle等多种不同的数据源的实时增量数据,支持写入数据库、MetaQ, ODPS等多种存储媒介.

    以前在一个城市做双机房主备,两个机房是数据对等的,写入是随机分布,然后通过主备HA进行数据同步。这样机房对等的思路会导致业务增长、数据增长只能通过两个机房不停堆机器来解决。另一方面,如果整个城市断电,那么双活就成了双死。下一个思路是做跨城市,早期常用的做法是一个城市写,另一个城市冷备,就是晚上做同步,但这就意味着白天如果发生了什么事儿,这一天的数据就比较危险。另一个思路是两个城市多写,数据落两边,这样的问题是应用调用次数频繁的话,如果调用异地数据多来那么一两次,整个应用的延时就很长。这个思路再进一步发展,就是做单元内封闭以减少异地调用,这就涉及到业务上的改造。

    顺着这个思路,阿里的异地双活重点做了几件事。一个是热插拔,可以做到在业务高峰时增加节点,高峰过了把增加的节点关闭。做到这个的一个关键是流量实时切换 ,DRC可以在20秒以内把一个单元(region)的流量迁移到另一个单元。另一个是数据实时恢复,就是通过一定的冗余设计,一旦一个单元挂掉了,可以在另一个单元做全量恢复。

    异地多活在数据方面的挑战是非常大的。双十一期间,交易会激增,所以交易链路做了单元化。交易链路的数据分为三个维度:买家、卖家、商品。买家之间通常没有太多交叉,天然的适应这种隔离,而且卖家对延迟的敏感度非常高,所以按照卖家维度切分,在单元内封闭,而卖家和商品都是在中心写入。

    数据方面的两个核心要求:

    1. 一致性,要求卖家和商品一致,单元和中心一致,也就是数据同步不能丢数据,不能错数据,还要保证事务。
    2. 实时性,需要做到秒级别的延迟。

    双单元的同步架构有两种:
    一种是读写分离的方式,中心写,单元读。单元需要的数据如果没有从中心及时同步过来,或者同步错了,那有问题这段时间的交易会全部收到影响。这里的核心是,保证秒级延迟,同时保证一致性。(JD的多中心交易系统就采用了这种方式)

    第二种同步架构是单元封闭的方式。中心和单元各有写入,我们通过冗余是的中心和单元随时可以各自接管。(类似Otter)

    这里的关键是:

    • 避免循环复制:通过在DB透传打标事务的方式实现。
    • 限流:峰值的压力,我们单元化本来就选取了流量激增业务,两边都实时同步100%全量数据,峰值对每个系统的压力有增无减。DRC的store和congo都可以根据TPS或者流量限流。限速算法的核心思想分为批量采样,奖惩时间,平滑变速。

    Otter与DRC的区别:
    - Otter是阿里B2B的产品,DRC是阿里技术保障团队的产品
    - Otter是针对MySQL的,DRC可以支持多种类型的数据源
    - DRC从业务上进行了划分,可以实现单元内封闭,Otter的实现不涉及业务,而是在纯数据库层打通的技术
    - Otter是双写,DRC是中心写、分中心读,或者都部分写,相互同步。
    - Otter所处的网络环境较DRC差,解决一致性问题也较复杂(基于trusted source的单向环回的补救,基于时间交集的补救),DRC有两种实现方式,具体参考上面。

    异地多活中DRC的核心能力就是在低延迟,一致性和高可用。

    • 一致性:基于日志流式抓取、回放库表结构变更、基于事务的冲突检测。
    • 低延迟:最大延迟不超过1s, 消息协议优化,三级数据存储,预读优化IO, 多连接复用和传输压缩,高效的并发复制算法。
    • 高可用:主备切换,拓扑变化,心跳跟踪,多维度容灾。

    JD多中心交易系统

    JD. 多中心交易系统。

    JD数据复制中间件考察和借鉴了开源社区的实现,例如Databus、Canal/Otter、OpenReplicator等,解析部分使用了Canal的DBSync。

    多中心交易本质上是一个更大的分布式系统,交易流程中依赖和产生的数据和服务有不同的特点,必然涉及到数据分区、路由、复制、读写一致性、延迟等分布式领域的常见问题。

    其中,数据一致性是电商网站需要面临的首要问题,越是流量增大的时候越要保证数据更新的即时性和准确性。在多中心之间需要同步卖家数据和商品数据,如果同步的延时太长,买家、卖家都不可接受。比如,卖家改了价格或库存,用户不能过很久才看到。同样,数据正确性也是很大的挑战,卖掉的商品能够及时减少,退货的商品能够及时增加。这都时刻考验着后端系统和数据库平台的健壮性。

    除了数据一致性之外,如何保证路由规则的一致性也是关键性的问题。从技术角度来说,要保障单一用户从登录到访问服务、到访问数据库,全链路的路由规则都是完全一致的。如果路由错误,看到的数据不正确,也会影响到最终用户的体验。

    架构

    系统包括一个主中心和多个分中心,主中心与分中心之间通过数据总线交换数据。数据流向中,主数据(商品数据、商家数据、用户数据等)的流向从主中心通过数据总线实时同步到分中心,分中心只读;而交易数据(订单数据)的流向从分中心实时同步到主中心;在故障时,会从分中心转移到主中心。

    在这个系统中,有多处体现分流的概念。首先,买家访问京东网站下单时,会被优先分流到附近的交易中心;其次,根据交易系统的特点,接单前(包括购物车、结算页等),多中心交易按用户维度分流,如下图所示。用户登录时,查询用户与区域的映射关系表(类似你是哪个片区的),标识此用户属于哪个分中心,并保存标识到cookie中,然后将用户路由到指定的分中心。用户访问其他系统,如购物车和结算页时,从cookie中读取标识,重定向到相应分中心页面。

    通过分流,将用户分配到相应的分中心,一方面响应速度快,用户体验更好,不用跨地域访问数据中心了;另一方面,每个中心服务一定数量的用户,水平扩展性好,也能支撑更大的交易规模了。当然,多数据中心不能盲目干活,还考虑到容灾备份的问题。(支付宝光纤事件)

    交易系统包括应用和数据部分,应用部分是无状态的,就是说,这些工作是无差别的,一台服务器出问题,我换一台服务器来处理就是了,较容易实现多机房多活。但是数据不一样,多中心交易本质上是一个更大的分布式系统,必然涉及到数据分区、路由、复制、读写一致性、延迟等分布式领域的常见问题。

    另外,交易流程中依赖和产生的数据和服务有不同的特点。比如商品、促销和价格、库存的读服务,我们可以将之称为基础主数据,它们在用户下单流程中是无法分区的,否则无法实现单机房内流量闭环,也就是说,不能因为分区数据的不一致,导致同一用户在单一流程中看到不同的数据(假如你加入购物车时是促销20块,结账是25块,你会不会表情扭曲?)而商品、促销和价格的写服务,是给采销、第三方POP商家应用调用的,这种业务场景的可用性目标,主机房部署和冷备模式即可满足,而且业务人员的操作流程会抵消写复制延迟。

    简单来说,数据的问题表现在以下几个方面:一、 如何保证数据的即时性和准确性,多中心之间需要同步卖家数据和商品数据,如果同步的延时太长,买家、卖家都不可接受,由于是异地部署,最好延时能控制在1秒内。比如,卖家改了价格或库存,用户不能过很久才看到。同样,数据正确性也是很大的挑战,因为数据故障跟应用层故障不一样,应用出故障了,可能只影响用户访问;数据写错了无法恢复。2、如何保证路由规则的一致性,要保障这个用户从进来到访问服务,到访问数据库,全链路的路由规则都是完全一致的;如果路由错误,看到的数据不正确。

    从同城双机房的分布转变为异地多机房的分布,给数据同步带来了新的挑战,因此如何设计数据总线也是项目能否实现的关键因素。京东的多中心交易系统通过数据总线JingoBus进行快速数据交换,同步性能是mysql的3倍以上,而且可用性高,架构灵活。其中,全新的总线设计解决了多中心交易跨机房的数据库复制和多数据源间的数据异构同步等难题,实现了高性能、低延时、健壮的数据同步机制。

    如图所示,数据总线主要分Relay、Snapshot和Replicator三部分构成,其中Relay从来源数据库抽取事务日志,并对Replicator提供日志订阅服务,角色上相当于Mysql Slave IO Thread。Snapshot从Relay订阅所有事务日志,写入持久存储作为快照,同时向Replicator提供批量日志订阅服务,角色上相当于Mysql Slave Relay Log。Replicator:事务日志的消费端,从Relay或Snapshot拉取事务日志将事务日志按配置的一致性应用到目标数据库,角色上相当于Mysql Slave SQL Thread。(参考下面MySQL主备复制原理图)

    正常情况下,Replicator直接连接Relay,消费Relay内存队列中的事务日志。但有些情况下,因为网络抖动、目标库的负载过高等因素,可能导致Replicator相对Relay落后很多。另外,当新的消费端加入同一数据源的订阅者时,新消费端有冷启动的问题。为了避免重新从数据源做全量快照,Snapshot作为Relay的一个特殊消费端,通过一种高吞吐的消费方式,从Relay源源不断的消费在线事务日志,通过对事务日志的有效处理,最终保存了数据源的一份一致快照(Consistent Snapshot),即包括了数据源库表中每一行的最新状态的快照,同时保留了一段比Relay buffer更旧的事务日志(Log Store)。由此看来,数据总线作为一个数据层的通用CDC组件,对于多中心交易项目以及异步复制场景提供了整体解决方案,奠定了项目的核心内容。


    跨数据库(数据源)迁移

    yugong

    去Oracle数据迁移同步工具。定位:数据库迁移(目前主要支持Oracle->mysql/DRDS)

    08年左右,阿里巴巴开始尝试MySQL的相关研究,并开发了基于MySQL分库分表技术的相关产品,Cobar/TDDL(目前为阿里云DRDS产品),解决了单机Oracle无法满足的扩展性问题,当时也掀起一股去IOE项目的浪潮,愚公这项目因此而诞生,其要解决的目标就是帮助用户完成从Oracle数据迁移到MySQL上,完成去IOE的第一步.

    概述

    整个数据迁移过程,分为两个部分:

    1. 全量迁移
    2. 增量迁移

    过程描述:

    1. 增量数据收集(创建Oracle表的增量物化视图)
    2. 进行全量复制
    3. 进行增量复制(可并行进行数据校验)
    4. 原库停写,切换到新库

    Oracle全量基于JDBC拉取数据,增量基于物化视图来实现。

    架构

    说明:

    1. 一个JVM Container 对应多个instance,每个instance对应于一张表的迁移任务
    2. instance分为三部分
      • extractor (从数据源库上提取数据,可分为全量/增量实现)
      • translator (将源库上的数据按照目标库的需求进行自定义转化)
      • applier(将数据更新到目标库,可分为全量/增量/对比的实现)

    自定义数据转换

    如果要迁移的Oracle和mysql的表结构不同,比如表名,字段名有差异,字段类型不兼容,需要使用自定义数据转换。如果完全相同则可以跳过。

    整个数据流为:DB->Extractor->DataTranslator->Applier->DB, 本程序预留DataTranslator接口(仅支持Java),允许外部用户自定义数据处理逻辑。比如:

    1. 表名不同
    2. 字段名不同
    3. 字段类型不同
    4. 字段个数不同
    5. 运行过程join其他表的数据做计算等

    运行模式介绍

    1.MARK模式(MARK)

    开启增量日志模式,如果是Oracle就是创建物化视图(materialized view)。

    2.CLEAR模式(CLEAR)

    清理增量日志的几率,如果是Oracle就是删除物化视图

    3.全量模式(FULL)

    全量模式,顾名思议即为对源表进行一次全量操作,遍历源表所有的数据后,插入目标表.

    全量有两种处理方式:

    1. 分页处理:如果源表存在主键,只有一个主键字段,并且主键字段类型为Number类型,默认会选择该分页处理模式. 优点:支持断点续做,对源库压力相对较小。 缺点:迁移速度慢
    2. once处理:通过select * from访问整个源表的某一个mvcc版本的数据,通过cursor.next遍历整个结果集. 优点:迁移速度快,为分页处理的5倍左右。 缺点:源库压力大,如果源库并发修改量大,会导致数据库MVCC版本过多,出现栈错误. 还有就是不支持断点续做.

    4.增量模式(INC)

    全量模式,顾名思议即为对源表增量变化的数据插入目标表,增量模式依赖记录日志功能.

    目前增量模式的记录日志功能,是通过oracle的物化视图功能。

    5.自动模式(ALL)

    自动模式,是对全量+增量模式的一种组合,自动化运行,减少操作成本.

    自动模式的内部实现步骤:

    1. 开启记录日志功能. (创建物化视图)
    2. 运行全量同步模式. (全量完成后,自动进入下一步)
    3. 运行增量同步模式. (增量模式,没有完成的概念,所以也就不会自动退出,需要业务判断是否可以退出,可以看一下切换流程)

    6.对比模式(CHECK)

    对比模式,即为对源库和目标库的数据进行一次全量对比,验证一下迁移结果. 对比模式为一种可选运行,做完全量/增量/自动模式后,可选择性的运行对比模式,来确保本次迁移的正确性.

    DataX

    DataX是一个在异构的数据库/文件系统之间高速交换数据的工具,实现了在任意的数据处理系统(RDBMS/Hdfs/Local filesystem)之间的数据交换。

    目前成熟的数据导入导出工具比较多,但是一般都只能用于数据导入或者导出,并且只能支持一个或者几个特定类型的数据库。

    这样带来的一个问题是,如果我们拥有很多不同类型的数据库/文件系统(Mysql/Oracle/Rac/Hive/Other…),并且经常需要在它们之间导入导出数据,那么我们可能需要开发/维护/学习使用一批这样的工具(jdbcdump/dbloader/multithread/getmerge+sqlloader/mysqldumper…)。而且以后每增加一种库类型,我们需要的工具数目将线性增长。(当我们需要将mysql的数据导入oracle的时候,有没有过想从jdbcdump和dbloader上各掰下来一半拼在一起到冲动?)这些工具有些使用文件中转数据,有些使用管道,不同程度的为数据中转带来额外开销,效率差别很非常大。很多工具也无法满足ETL任务中常见的需求,比如日期格式转化,特性字符的转化,编码转换。另外,有些时候,我们希望在一个很短的时间窗口内,将一份数据从一个数据库同时导出到多个不同类型的数据库。DataX正是为了解决这些问题而生。

    • 左图:新增第n+1个数据源,是不是需要开发n个数据同步工具?
    • 右图:只需要针对新增的数据源开发一套Reader/Writer插件,即可实现任意数据的互导。

    设计理念

    为了解决异构数据源同步问题,DataX将复杂的网状的同步链路变成了星型数据链路,DataX作为中间传输载体负责连接各种数据源。当需要接入一个新的数据源的时候,只需要将此数据源对接到DataX,便能跟已有的数据源做到无缝数据同步。

    DataX在阿里巴巴集团内被广泛使用,承担了所有大数据的离线同步业务,并已持续稳定运行了6年之久。目前每天完成同步8w多道作业,每日传输数据量超过300TB。

    框架设计

    DataX本身作为离线数据同步框架,采用Framework+plugin架构构建。将数据源读取和写入抽象称为Reader/Writer插件,纳入到整个同步框架中。

    • Reader: Reader为数据采集模块,负责采集数据源的数据,将数据发送给Framework.
    • Writer:Writer为数据写入模块,负责不断向Framework取数据,并将数据写入到目的端
    • Framework:Framework用于连接reader和writer,作为两者的数据传输通道,并处理缓存,流控,并发,数据转换等核心技术问题。

    DataX框架内部通过双缓冲队列、线程池封装等技术,集中处理了高速数据交换遇到的问题,提供简单的接口与插件交互,插件分为Reader和Writer两类,基于框架提供的插件接口,可以十分便捷的开发出需要的插件。比如想要从oracle导出数据到mysql,那么需要做的就是开发出OracleReader和MysqlWriter插件,装配到框架上即可。并且这样的插件一般情况下在其他数据交换场合是可以通用的。

    核心架构

    DataX3.0 开源版本支持单机多线程模式完成同步作业运行,这里按一个DataX作业生命周期的时序图,从整体架构设计非常简要说明DataX各个模块相互关系。

    核心模块介绍:

    1. DataX完成单个数据同步的作业,我们称之为Job,DataX接受到一个Job之后,将启动一个进程来完成整个作业同步过程。DataX Job模块是单个作业的中枢管理节点,承担了数据清理、子任务切分(将单一作业计算转化为多个子Task)、TaskGroup管理等功能。
    2. DataXJob启动后,会根据不同的源端切分策略,将Job切分成多个小的Task(子任务),以便于并发执行。Task便是DataX作业的最小单元,每一个Task都会负责一部分数据的同步工作。
    3. 切分多个Task之后,DataX Job会调用Scheduler模块,根据配置的并发数据量,将拆分成的Task重新组合,组装成TaskGroup(任务组)。每一个TaskGroup负责以一定的并发运行完毕分配好的所有Task,默认单个任务组的并发数量为5。
    4. 每一个Task都由TaskGroup负责启动,Task启动后,会固定启动Reader—>Channel—>Writer的线程来完成任务同步工作。
    5. DataX作业运行起来之后, Job监控并等待多个TaskGroup模块任务完成,等待所有TaskGroup任务完成后Job成功退出。否则,异常退出,进程退出值非0。

    DataX调度流程:

    举例来说,用户提交了一个DataX作业,并且配置了20个并发,目的是将一个100张分表的mysql数据同步到odps里面。 DataX的调度决策思路是:
    1. DataXJob根据分库分表切分成了100个Task。
    2. 根据20个并发,DataX计算共需要分配4个TaskGroup。
    3. 4个TaskGroup平分切分好的100个Task,每一个TaskGroup负责以5个并发共计运行25个Task。

    Datax插件开发:https://github.com/alibaba/DataX/wiki/DataX%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E5%AE%9D%E5%85%B8

    展开全文
  • 数据库中间件的基本功能简介
    数据库中间件的几种功能
    数据库中间件是处于数据库与应用程序之间提供通用、复用服务的系统,减少应用结构的复杂性。如开源的mycat,是由java编写。提供了以下几种功能。
    1. 异构数据库的通用:通用的数据库中间件会支持多种数据库的协议。如图所示:应用程序连接数据库中间件用的是标准的数据库协议如jdbc,而数据库中间件在与各种数据库通讯时用的是各数据库的协议。这样在应用程序中就可以透明化的使用数据库。减少开发成本,与适配数据库所带来开发成本。
    2. 读、写分离:读、写分离的原理是将事务型操作(增、删、改)与非事务弄操作(读)分发到不同数据库实例上去执行。数据库实例之间要进行数据的主、从同步,往往写数据库实例为主数据库;读数据库实例为从数据库。如下图所示:
    3. 分库分表:分库、分表是为了将不同的业务数据存储于不同数据库实例上。从而达到减少数据库实例表的基础数据量和业务的分布式处理。业务数据的分布要在数据库中间件里配置,方便数据库中间件在处理数据时的分发到正确的数据库实例。如下图:
    展开全文
  • 数据库相关中间件收录集

    万次阅读 2016-10-09 18:15:09
    数据库中间件 这里主要介绍互联网行业内有关数据库的相关中间件数据库相关平台主要解决以下三个方面的问题: 为海量前台数据提供高性能、大容量、高可用性的访问 为数据变更的消费提供准实时的保障 高效的异地...

    欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。


    欢迎跳转到本文的原文链接:https://honeypps.com/architect/collection-of-database-related-middleware/

    数据库中间件

    这里主要介绍互联网行业内有关数据库的相关中间件。数据库相关平台主要解决以下三个方面的问题:

    • 为海量前台数据提供高性能、大容量、高可用性的访问
    • 为数据变更的消费提供准实时的保障
    • 高效的异地数据同步

    应用层通过分表分库中间件访问数据库,包括读操作(Select)和写操作(update, insert和delete等,DDL, DCL)。写操作会在数据库上产生变更记录,MySQL的变更记录叫binlog, Oracle的称之为redolog, 增量数据订阅与消费中间件解析这些变更,并以统一的格式保存起来,下层应用根据这些数据进行消费应用。当然,在数据库与数据库本身之间也会有数据库迁移的操作,这种操作可以不需要增量数据订阅与消费中间件的数据,而可以自行处理。

    数据库中间件有以下几种:

    • 分布式数据库分表分库
    • 数据增量订阅与消费
    • 数据库同步(全量、增量、跨机房、复制)
    • 跨数据库(数据源)迁移

    整个产品族图如下:

    这里写图片描述

    • 最上层的是分布式数据库分表分库中间件,负责和上层应用打交道,对应用可表现为一个独立的数据库,而屏蔽底层复杂的系统细节。分布式数据库中间件除了基本的分表分库功能,还可以丰富一下,比如讲读写分离或者水平扩容功能集成在一起,或者比如读写分离本身也可以作为一个独立的中间件。(Cobar, MyCAT, TDDL, DRDS, DDB)
    • 增量数据订阅和消费,用户对数据库操作,比如DML, DCL, DDL等,这些操作会产生增量数据,下层应用可以通过监测这些增量数据进行相应的处理。典型代表Canal,根据MySQL的binlog实现。也有针对Oracle(redolog)的增量数据订阅与消费的中间件。(Canal, Erosa)
    • 数据库同步中间件涉及数据库之间的同步操作,可以实现跨(同)机房同步以及异地容灾备份、分流等功能。可以涉及多种数据库,处理之后的数据也可以以多种形式存储。(Otter, JingoBus, DRC)
    • 数据库与数据库之间会有数据迁移(同步)的动作,同款数据同步原理比较简单,比如MySQL主备同步,只要在数据库层进行相应的配置既可,但是跨数据库同步就比较复杂了,比如Oracle->MySQL. 数据迁移一般包括三个步骤:全量复制,将原数据库的数据全量迁移到新数据库,在这迁移的过程中也会有新的数据产生;增量同步,对新产生的数据进行同步,并持续一段时间以保证数据同步;原库停写,切换新库。将“跨数据库”这个含义扩大一下——“跨数据源”,比如HDFS, HBase, FTP等都可以相互同步。(yugong, DataX)

    分布式数据库

    随着互联网产品在体量和规模上日益膨胀,无论是Oracle还是MySQL,都会第一时间面临来自磁盘,CPU和内存等单机瓶颈,为此,产品方除了需要不断购买成本难以控制的高规格服务器,还要面临不断迭代的在线数据迁移。在这种情况下,无论是海量的结构化数据还是快速成长的业务规模,都迫切需要一种水平扩展的方法将存储成本分摊到成本可控的商用服务器上。同时,也希望通过线性扩容降低全量数据迁移对线上服务带来的影响,分库分表方案便应运而生。

    分表分库类的中间件主要有两种形式向应用提供服务:

    • 一种是以JDBC的jar包形式为Java应用提供直接依赖,Java应用通过提供的JDBC包实现透明访问分布式数据库集群中的各个分库分表,典型代表网易的DDB和阿里的TDDL.
    • 另一种是为应用部署独立的服务来满足应用分库分表的需求,在这种方式下通过标准JDBC访问Proxy,而Proxy则根据MySQL标准通信协议对客户端请求解析,还原应用SQL请求,然后通过本地访问数据库集群,最后再将得到的结果根据MySQL标准通信协议编码返回给客户端。典型代表阿里的Cobar, Cobar变种MyCAT, 阿里的DRDS,网易的DDB proxy模式以及DDB的私有云模式。

    Cobar

    Cobar 是提供关系型数据库(MySQL)分布式服务的中间件,它可以让传统的数据库得到良好的线性扩展,并看上去还是一个数据库,对应用保持透明。

    Cobar以Proxy的形式位于前台应用和实际数据库之间,对前台的开放的接口是MySQL通信协议。将前台SQL语句变更并按照数据分布规则发到合适的后台数据分库,再合并返回结果,模拟单库下的数据库行为。

    Cobar属于阿里B2B事业群,始于2008年,在阿里服役3年多,接管3000+个MySQL数据库的schema,集群日处理在线SQL请求50亿次以上。由于Cobar发起人的离职,Cobar停止维护。后续的类似中间件,比如MyCAT建立于Cobar之上,包括现在阿里服役的RDRS其中也复用了Cobar-Proxy的相关代码。

    Cobar结构

    这里写图片描述

    • 与应用之间通过MySQL protocol进行交互,是一个proxy的结构,对外暴露jdbc:mysql://CobarIP:port/schema。对应用透明。
    • 无需引入新的jar包,从访问迁移到数据库访问Cobar可以复用原有的基于JDBC的DAO。
    • Cobar前后端都实现了MySQL协议,当接受到SQL请求时,会一次进行解释(SQL Parser)和路由(SQL Router)工作,然后使用SQL Executor去后端模块获取数据集(后端模块还负责心跳检查功能);如果数据集来自多个数据源,Cobar则需要把数据集进行组合(Result Merge),最后返回响应。
    • 数据库连接复用。Cobar使用连接词与后台真是数据库进行交互。(实际应用中,根据应用的不同,使用proxy结构后数据库连接数能够节约2-10倍不等。)
    • Cobar事务,Cobar在单库的情况下保持事务的强一致性,分库的情况下保持事务的弱一致性,分库事务采用2PC协议,包括执行阶段和提交阶段。

    Cobar的前端是NIO的,而后端跟MySQL交互是阻塞模式,其NIO代码只给出了框架,还没有来得及实现。 据称未开源版的Cobar实现了后端的NIO。
    Cobar会出现假死,假死以后Cobar会频繁进行主从切换(如果配置了的话),自动切换本身也存在隐患。
    可以计算:Cobar的TPS=5,000,000,000/(3000*24*60*60)=20。

    与Cobar相关的还有一共Cobar-Client.

    Cobar通过SQL语句转发的方式实现数据访问。用户发来的SQL语句,Cobar解析其内容,判断该语句所涉及的数据分布在哪个分库上,再将语句转发给此分库执行。当SQL语句中涉及的拆分字段有多值,如 IN, 或where条件中没有出现拆分字段时,该语句将会转发至后台所有分库执行,再将执行结果以MySQL协议包的形式送回应用端。

    通信模块,负责从连续的网络数据流中识别出一个个MySQL协议包,再解析协议包识别出SQL语句输出给Parser模块,同时,把Result Merge模块输入的执行结果,编码成MySQL的协议包。它以NIO方式实现,有很高的执行效率。之后进行优化,引入了一个ByteBuffer池,将NIO的Buffer统一管理起来,减少了NIO数据交互时的垃圾回收。

    Cobar前端使用的是优化后的NIO通信模块,为了让该模块在后端使用,Cobar去除了JDBC。与后端数据库交互,Cobar直接面向协议,目前实现了基于MySQL协议的后端交互。

    水平拆分后,后台有多个数据源,对他们的管理分为两个层次:DataNode和replica(HA Pool)。
    DataNode管理拆分,一个DataNode存放一个分片的数据,彼此无数据交集。每个分片的数据存多份以保证高可用,每一份叫做一个replica,由HA层管理。每一个replica表示一个具体的数据源,它是一个连接池,池内管理每一个具体的JDBC连接。路由运算只关注到DataNode层,之下的层次对其不可见。
    每一份replica之间的数据复制和同步由MySQL本身的replication协议完成,同一时刻只有一个replica提供服务(称为Master,其余replica称为Slave).Cobar会与之保持心跳,一旦发现它不可用,会切换至另一个replica,解决Oracle单点的第二个问题。

    为了节省数据库的机器数量,可以采用下图中的方式部署:

    这里写图片描述

    HA

    在用户配置了MySQL心跳的情况下,Cobar可以自动向后端连接的MySQL发生心跳,判断MySQL运行状况,一旦运行出现异常,Cobar可以自动切换到备机工作,但需要强调的是:

    1. Cobar的主备切换有两种触发方式,一种是用户手动触发,一种是Cobar的心跳语句检测到异常后自动触发。那么,当心跳检测到主机异常,切换到备机,如果主机恢复了,需要用户手动切回主机工作,Cobar不会在主机恢复时自动切换回主机,除非备机的心跳也返回异常。
    2. Cobar只检查MySQL主备异常,不关心主备之间的数据同步,因此用户需要在使用Cobar之前在MySQL主备上配置双向同步,详情可以参阅MySQL参考手册。

    Cobar解决的问题

    分布式:Cobar的分布式主要是通过将表放入不同的库来实现。

    1. Cobar支持将一张表水平拆分成多份分别放入不同的库来实现表的水平拆分
    2. Cobar也支持将不同的表放入不同的库
    3. 多数情况下,用户将以上两种方式混合使用

    这里需要强调的是,Cobar不支持将一张表,例如test表拆分成test_1, test_2, test_3…放在同一个库中,必须拆分后的表分别放入不同的库来实现分布式。

    Cobar的约束

    1. 不支持跨库情况下的join、分页、排序、子查询操作
    2. SET语句执行会被忽略,事务和字符集设置除外
    3. 分库情况下,insert语句必须包括拆分字段列名
    4. 分库情况下,update语句不能更新拆分字段的值
    5. 不支持SAVEPOINT操作
    6. 暂时只支持MySQL数据节点
    7. 使用JDBC时,不支持rewriteBatchedStatements=true参数设置(默认为false)
    8. 使用JDBC时,不支持useServerPrepStmts=true参数设置(默认为false)
    9. 使用JDBC时,BLOB, BINARY, VARBINARY字段不能使用setBlob()或setBinaryStream()方法设置参数

    MyCAT

    从定义和分类看,它是一个开源的分布式数据库系统,是一个实现了MySQL协议的Server,前端用户可以把它看做是一个数据库代理,用MySQL客户端工具和命令行访问,而其后端可以用MySQL Native Protocol与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。

    MyCAT发展到目前的版本,已经不是一个单纯的MySQL代理了,它的后端可以支持MySQL, SQL Server, Oracle, DB2, PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储,未来还会支持更多类型的存储。

    MyCAT是一个强大的数据库中间件,不仅仅可以用作读写分离,以及分表分库、容灾管理,而且可以用于多租户应用开发、云平台基础设施,让你的架构具备很强的适应性和灵活性,借助于即将发布的MyCAT只能优化模块,系统的数据访问瓶颈和热点一目了然,根据这些统计分析数据,你可以自动或手工调整后端存储,将不同的表隐射到不同存储引擎上,而整个应用的代码一行也不用改变。

    MyCAT是在Cobar基础上发展的版本,两个显著提高:

    • 后端由BIO改为NIO,并发量有大幅提高;
    • 增加了对Order By, Group By, Limit等聚合功能(虽然Cobar也可以支持Order By, Group By, Limit语法,但是结果没有进行聚合,只是简单返回给前端,聚合功能还是需要业务系统自己完成)

    MyCAT架构

    这里写图片描述

    • 事务是弱XA
    • MyCAT的原理中最重要的一个动词是“拦截”,它拦截了用户发来的SQL语句,首先对SQL语句做了一些特定的分析:如分片分析,路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
    • MyCAT对自身不支持的SQL语句提供了一种解决方案——在要执行的SQL语句前添加额外的一段由注解SQL组织的代码,这样SQL就能正确执行,这段代码称之为“注解”。注解的使用相当于对MyCAT不支持的SQL语句做了一层透明代理转发,直接交给目标的数据节点进行SQL语句执行。
    • MyCAT自身有类似其他数据库的管理监控方式,可以通过MySQL命令行,登录管理端口(9066)执行相应的SQL进行管理,也可以通过jdbc的方式进行远程连接管理。

    HA

    MyCAT作为一个代理层中间件,MyCAT系统的高可用设计到MyCAT本身的高可用以及后端MySQL的高可用. 在多数情况下,建议采用MySQL主从复制高可用性配置并交付给MyCAT来完成后端MySQL节点的主从自动切换。

    这里写图片描述

    MySQL侧的HA

    • MySQL节点开启主从复制的配置方案,并将主节点配置为MyCAT的dataHost里的writeNode,从节点配置为readNode,同时MyCAT内部定期对一个dataHost里的所有writeHost与readHost节点发起心跳检测。
    • 正常情况下,MyCAT将第一个writeHost作为写节点,所有的DML SQL会发送此节点。
    • 若MyCAT开启了读写分离,则查询节点会根据读写分离的策略发往readHost(+writeHost)执行。
    • 如果第一个writeHost宕机,MyCAT会在默认的三次心跳检测失败后,自动切换到下一个可用的writeHost执行DML SQL语句
    • 当原来配置的MySQL写节点宕机恢复后,作为从节点,跟随新的主节点,重新配置主从同步。

    MyCAT自身的HA

    • 官方建议是采用基于硬件的负载聚亨或者软件方式的HAproxy等。
    • 如果还担心HAproxy的稳定性和但节点问题,则可以用keepalived的VIP的浮动功能,加以强化。

    MyCAT功能和特性

    • 支持SQL 92标准
    • 支持Mysql集群,可以作为Proxy使用
    • 支持JDBC连接多数据库
    • 支持NoSQL数据库
    • 支持galera sfor mysql集群,percona-cluster或者mariadb cluster,提供高可用性分片集群
    • 自动故障切换,高可用性
    • 支持读写分离,支持MySQL双主多从,以及一主多从的模式
    • 支持全局表,数据自动分片到多个节点,用于高效表关联查询
    • 支持一致性Hash分片,有效解决分片扩容难题
    • 多平台支持,部署和试试简单
    • 支持Catelet开发,类似数据库存储过程,用于跨分片复杂SQL的人工智能编码实现
    • 支持NIO与AIO两种网络通信机制,windows下建议AIO,Linux下目前建议NIO
    • 支持MySQL存储过程调用
    • 以插件的方式支持SQL拦截和改写
    • 支持自增长逐渐、支持Oracle的Sequence机制
    • 支持Mysql, MongoDB,Oracle, SQL Server, Hive, DB2, PostgreSQL等。

    MyCAT目前的项目

    • MyCAT-Server:MyCAT核心服务
    • MyCAT-Spider:MyCAT爬虫技术
    • MyCAT-ConfigCenter:MyCAT配置中心
    • MyCAT-BigSQL:MyCAT大数据处理(暂未更细)
    • MyCAT-Web:MyCAT监控及web(新版开发中)
    • MyCAT-Balance:MyCAT负载均衡(暂未更细)

    DRDS/TDDL

    alibaba. Distributed Relational Database Service.

    阿里分布式数据库DRDS的前身是淘宝分布式数据库层TDDL,大概在2012年的时候,阿里开始尝试将TDDL这套体系输出到阿里云上,也有了一个新的名字:DRDS.

    TDDL

    Tabao根据自己的业务特点开发了TDDL(Tabao Distributed Data Layer, 外号:头都大了)。主要解决了分库分表对应用的透明化以及异构数据库之间的数据复制,它是一个基于集中式配置的jdbc datasourcce实现,具有主备,读写分离,动态数据库配置等功能。

    TDDL并非独立的中间件,只能算作中间层,是以Jar包方式提供给应用调用。属于JDBC Shard的思想。

    TDDL处于业务层和JDBC层中间。

    这里写图片描述

    TDDL其实主要可以划分为3层架构,分别是Matrix层,Group层和Atom层。Matrix层用于实现分库分表逻辑,底层多个Group实例。而Group和Atom共同组成了动态数据源,Group层实现了数据库的Master/Slave模式的写分离逻辑,底层持有多个Atom实例。最后Atom层(持有数据源)实现数据库ip, port, password, connectionProperties等信息的动态推送,以及持有院子的数据源分离的JBoss数据源。

    TDDL社区处于停滞状态,网上可查资源也较少。

    RDRS

    DRDS/TDDL是阿里巴巴自主研发的分布式数据库服务。DRDS脱胎于阿里巴巴开源的Cobar分布式数据库引擎,吸收了Cobar核心的Cobar-Proxy源码,实现了一套独立的类似MySQL-Proxy协议的解析端,能够对传入的SQL进行解析和处理,对应用程序屏蔽各种复杂的底层DB拓扑结构,获得单机数据库一样的使用体验,同时借鉴了淘宝TDDL丰富的分布式数据库实践经验,实现了对分布式Join支持,SUM/MAX/COUNT/AVG等聚合函数支持以及排序等函数支持,通过异构索引、小表广播等解决分布式数据库使用场景下衍生出的一系列问题,最终形成了完整的分布式数据库方案。

    DRDS在整个阿里系统中所处的位置:
    这里写图片描述

    对于很多应用而言,单机数据库最终都会碰到单机性能上的天花板,在TPS/QPS/内存容量/磁盘容量等等一系列系统资源上会碰到各类限制。DRDS的主要目标就是帮您解决这方面的各类问题,他主要提供了两个功能,读写分离和数据库切分:

    • 读写分离,能够运行实现一台机器写入,多台机器读取,这对于读多写少的应用,能够以极低的成本解决系统的瓶颈。
    • 数据库切分是一个解决系统存储瓶颈的最终极解决方案,数据库切分的核心思想其实很简单,就是分而治之。将数据分散到多台机器,并保证请求能够平均的分发到这些机器上,就可以以极低的成本来解决业务的各类性能瓶颈。当然切分也是有代价的,最明显的代价就是,分布式数据库会对一些原有单机数据的场景进行限制,因为这些操作,在分布式环境下的延迟或效率非常低效,就算是能够实现出来,也会因为性能问题而无法使用。

    这里写图片描述

    其他功能特性

    1.分布式MySQL执行引擎

    主要目标是实现与单机数据库SQL引擎的完全兼容,实现SQL的智能下推,能够智能分析SQL,解析出那些SQL可以直接下发,那些SQL需要进行优化改造,优化成什么样,以及路由到哪些实例节点上执行,充分发挥数据库实例的全部能力,减少网络之间的数据传输量,最终对不同实例处理后的少量结果进行聚合计算返回给应用调用方。这就是分布式SQL引擎的智能下推功能。
    分布式引擎的职责包含SQL解析,优化,执行和合并四个流程。

    这里写图片描述

    支持市面上几乎所有的语言(具有MySQL访问能力的),兼容90%以上MySQL语法。

    案例分析:
    比如一个简单的AVG操作,对于一些比较初级的分布式数据库模型而言,常见做法是把AVG直接下发到所有存储节点,这样造成的结果就是语法兼容,语义不兼容,最终拿到的是错误结果。而DRDS的智能下推引擎,对SQL的语法做充分的语义兼容性适配,针对AVG操作,只能由引擎将逻辑AVG SQL解析优化为SUM和COUNT的SQL然后进行下推,由底层的数据库实例节点完成SUM和COUNT计算,充分利用底层节点的计算能力,在引擎层将各个存储节点的SUM和COUNT结果聚合计算,最终计算出AVG。

    2.在线平滑扩容

    在线数据扩容的重点在于“在线”两字,也就是用户不需要停止业务进行割接操作,直接就可以添加新的RDS节点到集群中,实现无缝的自由扩展。RDRS则将整个扩容过程分为几个阶段,包括全量迁移,增量同步,切换数据库等几个步骤。数据会提前进行搬迁,并进行增量并行同步一段时间,因此,我们可以在非常短的时间内(秒级别)完成数据库的最终扩容切换工作,对业务没有影响。

    3.小表广播

    在一些大的业务表进行了切分后,总会存在一些表的数据量不大,更新量也不大的原始信息表。这些表往往会与我们的切分后大表进行join操作,这种操作物理上就会造成分布式join查询,效率从整体上会比较地下。针对这种分布式join的场景,开发了OETL专用工具来进行小表广播,将原信息表的所有数据(包括增量更新)全部自动的广播到大表的机器上,这样,就可以让原来的分布式查询变成单机本地查询了。

    4.全局唯一ID

    DRDS sequence功能的目标只是为了保证数据的全局唯一,虽然基本上是按时间序列获取的,但并不全局有序。

    5.异构索引

    解决分布式场景下数据拆分维度和数据查询使用维度不一致导致的低效问题。

    当数据表被拆分为多个分库分表时,数据在分库分表的分布规则就固定了。但是通常数据的业务使用场景非常复杂,如果数据的查询维度和数据拆分分布的规则一直,单条SQL会在一个分库分表上执行;如果数据的查询使用维度和数据拆分分布的规格不一致,单条SQL可能在多个分库分表上执行,出现跨库查询,跨库查询会增加IO成本,查询效率必然下降。

    解决这个问题的思路还是分布式数据库的一贯原则,让SQL执行在单库上完成,实际采用的方式就是用“空间换效率”的方案,也就是将同一份数据表,冗余存储多份,按照不同的业务使用场景进行拆分,保持拆分维度和使用维度统一,而多份数据之间会实时数据复制以解决数据一致性问题,这就是“异构索引”方案。当然异构索引表不能无限制滥用,过多的异构索引表会影响同步效率,对源数据表造成同步压力。

    其他同款中间件

    Altas, Vitess, Heisenberg, CDS, DDB, OneProxy等等。

    Atlas

    Qihoo 360.
    Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目,它是在mysql-proxy 0.8.2版本上对其进行优化,增加了一些新的功能特性。
    Atlas是一个位于应用程序与MySQL之间,它实现了MySQL的客户端和服务端协议,作为服务端与应用程序通讯,同时作为客户端与MySQL通讯。它对应用程序屏蔽了DB的细节。
    Altas不能实现分布式分表,所有的字表必须在同一台DB的同一个DataBase里且所有的字表必须实现建好,Altas没有自动建表的功能。

    Heisenberg

    Baidu.
    其优点:分库分表与应用脱离,分库表如同使用单库表一样,减少db连接数压力,热重启配置,可水平扩容,遵守MySQL原生协议,读写分离,无语言限制,mysqlclient, c, java都可以使用Heisenberg服务器通过管理命令可以查看,如连接数,线程池,结点等,并可以调整采用velocity的分库分表脚本进行自定义分库表,相当的灵活。
    (开源版已停止维护)

    CDS

    JD. Completed Database Sharding.
    CDS是一款基于客户端开发的分库分表中间件产品,实现了JDBC标准API,支持分库分表,读写分离和数据运维等诸多共,提供高性能,高并发和高可靠的海量数据路由存取服务,业务系统可近乎零成本进行介入,目前支持MySQL, Oracle和SQL Server.
    (架构上和Cobar,MyCAT相似,直接采用jdbc对接,没有实现类似MySQL协议,没有NIO,AIO,SQL Parser模块采用JSqlParser, Sql解析器有:druid>JSqlParser>fdbparser.)

    DDB

    猪场. Distributed DataBase.
    DDB经历了三次服务模式的重大更迭:Driver模式->Proxy模式->云模式。

    • Driver模式:基于JDBC驱动访问,提供一个db.jar, 和TDDL类似, 位于应用层和JDBC之间.
    • Proxy模式:在DDB中搭建了一组代理服务器来提供标准的MySQL服务,在代理服务器内部实现分库分表的逻辑。应用通过标准数据库驱动访问DDB Proxy, Proxy内部通过MySQL解码器将请求还原为SQL, 并由DDB Driver执行得到结果。
    • 私有云模式:基于网易私有云开发的一套平台化管理工具Cloudadmin, 将DDB原先Master的功能打散,一部分分库相关功能集成到proxy中,如分库管理、表管理、用户管理等,一部分中心化功能集成到Cloudadmin中,如报警监控,此外,Cloudadmin中提供了一键部署、自动和手动备份,版本管理等平台化功能。

    数据增量订阅与消费

    基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了mysql.
    有关数据增量订阅与消费的中间件回顾一下:

    这里写图片描述

    • 增量订阅和消费模块应当包括binlog日志抓取,binlog日志解析,事件分发过滤(EventSink),存储(EventStore)等主要模块。
    • 如果需要确保HA可以采用Zookeeper保存各个子模块的状态,让整个增量订阅和消费模块实现无状态化,当然作为consumer(客户端)的状态也可以保存在zk之中。
    • 整体上通过一个Manager System进行集中管理,分配资源。

    Canal

    Canal架构图:

    这里写图片描述

    说明:

    • server代表一个canal运行实例,对应于一个jvm
    • instance对应于一个数据队列 (1个server对应1…n个instance)

    instance模块:

    • eventParser (数据源接入,模拟slave协议和master进行交互,协议解析)
    • eventSink (Parser和Store链接器,进行数据过滤,加工,分发的工作)
    • eventStore (数据存储)
    • metaManager (增量订阅&消费信息管理器)

    说明:一台机器下部署一个canal,一个canal可以运行多个instance(通过配置destinations等), 一般情况下一个client连接一个instance(每个instance可以配置standby功能), 可以多个client连接同一个instance,但是同一时刻只能有一个client消费instance的数据,这个通过zookeeper控制。


    数据库同步

    Otter

    背景:alibaba B2B因为业务的特性,卖家主要集中在国内,买家主要集中在国外,所以衍生出了杭州和美国异地机房的需求,同时为了提升用户体验,整个机房的架构为双A,两边均可写,由此诞生了otter这样一个产品。

    otter第一版本可追溯到04~05年,此次外部开源的版本为第4版,开发时间从2011年7月份一直持续到现在,目前阿里巴巴B2B内部的本地/异地机房的同步需求基本全上了otter4。

    基于数据库增量日志解析,准实时同步到本地机房或异地机房的mysql/oracle数据库,一个分布式数据库同步系统。

    工作原理

    这里写图片描述

    原理描述

    1. 基于Canal开源产品,获取数据库增量日志数据。
    2. 典型管理系统架构,manager(Web管理)+node(工作节点)
      • manager运行时推送同步配置到node节点
      • node节点将同步状态反馈到manager上
    3. 基于zookeeper,解决分布式状态调度的,允许多node节点之间协同工作。

    Otter的作用

    1. 异构库
      • mysql->mysql、oracle. (目前开原版只支持mysql增量,目标库可以是mysql或者oracle,取决于canal的功能)
    2. 单机房同步(数据库之间RTT(Round-Trip Time)<1ms)
      • 数据库版本升级
      • 数据表迁移
      • 异步二级索引
    3. 跨机房同步(比如阿里巴巴国际站就是杭州和美国机房的数据库同步,RTT>200ms)
      • 机房容灾
    4. 双向同步
      • 避免回环算法(通用的解决方案,支持大部分关系型数据库)
      • 数据一致性算法(保证双A机房模式下,数据保证最终一直性)
    5. 文件同步
      • 站点镜像(进行数据复制的同时,复制关联的图片,比如复制产品数据,同事复制产品图片)

    单机房复制示意图

    这里写图片描述

    说明:

    • 数据On-Fly, 尽可能不落地,更快的进行数据同步。(开启node load balance算法, 如果Node节点S+ETL落在不同的Node上,数据会有个网络传输过程)
    • node节点可以有failover/loadBalancer.

    SETL

    S: Select
    为解决数据来源的差异性,比如接入canal获取增量数据,也可以接入其他系统获取其他数据等。

    E: Extract

    T: Transform

    L: Load

    类似于数据仓库的ETL模型,具体可为数据join,数据转化,数据加载。

    跨机房复制示意图

    这里写图片描述

    数据涉及网络传输,S/E/T/L几个阶段会分散在2个或者更多Node节点上,多个Node之间通过zookeeper进行协同工作(一般是Select和Extract在一个机房的Node, Transform/Load落在另一个机房的Node)
    node节点可以有failover/loadBalancer。(每个机房的Node节点,都可以是集群,一台或者多台机器)

    More:

    异地双活数据架构基础设施DRC

    所谓DRC,就是Data Replication Center的缩写,数据复制中心。这种复制是同步的,支持异构的,高可用的(有严格容灾系统,实时性好),支持订阅分发的。项目期初是为了淘宝异地容灾而成立的,用于数据库之间主备同步,后来采用这套技术方案衍生出了DRC-TAIR, DRC-DUMP等项目。

    所谓异地双活主要关注两件事,一个数据同步,一个数据分发。

    到底怎样的应用会需要异地的双活?比较常见的场景有三个:

    1. 两个地域或多个地域都有大量用户的场景,比如在中国的用户希望他们用杭州的RDS服务,在美国的用户用美国的RDS服务,这就需要数据在异地同步。很多游戏,金融,传媒,电商业务都有这种需求。满足这个需求的难点在于跨地域的网络,比如网络延时长,丢包多,而且数据在公网传输会有数据泄露风险。
    2. 数据来源较多,需要介入各种异构数据的场景。比如一个应用需要从ODPS, RDS, OTS, OceanBase, PostgreSQL这几个服务介入数据,他们的数据结构和接口都不同,这种接入的成本会比较高。因此另一个可用的方法是数据写入的时候就一份多谢为不同数据结构
    3. 下游订阅很多的情况,比如一份数据,备份系统、通知系统、大数据分析系统、索引系统等等都要来取,如果用上面一份数据多写的方案是可以应对的,但这里还有其他难点,就是数据一致性、可扩展性、跨网同步稳定性、以及同步的实时性。

    DRC支持读取集团MySQL, RDS, OceanBase, HBase, Oracle等多种不同的数据源的实时增量数据,支持写入数据库、MetaQ, ODPS等多种存储媒介.

    DRC架构
    这里写图片描述

    这里写图片描述

    以前在一个城市做双机房主备,两个机房是数据对等的,写入是随机分布,然后通过主备HA进行数据同步。这样机房对等的思路会导致业务增长、数据增长只能通过两个机房不停堆机器来解决。另一方面,如果整个城市断电,那么双活就成了双死。下一个思路是做跨城市,早期常用的做法是一个城市写,另一个城市冷备,就是晚上做同步,但这就意味着白天如果发生了什么事儿,这一天的数据就比较危险。另一个思路是两个城市多写,数据落两边,这样的问题是应用调用次数频繁的话,如果调用异地数据多来那么一两次,整个应用的延时就很长。这个思路再进一步发展,就是做单元内封闭以减少异地调用,这就涉及到业务上的改造。

    顺着这个思路,阿里的异地双活重点做了几件事。一个是热插拔,可以做到在业务高峰时增加节点,高峰过了把增加的节点关闭。做到这个的一个关键是流量实时切换 ,DRC可以在20秒以内把一个单元(region)的流量迁移到另一个单元。另一个是数据实时恢复,就是通过一定的冗余设计,一旦一个单元挂掉了,可以在另一个单元做全量恢复。

    这里写图片描述

    异地多活在数据方面的挑战是非常大的。双十一期间,交易会激增,所以交易链路做了单元化。交易链路的数据分为三个维度:买家、卖家、商品。买家之间通常没有太多交叉,天然的适应这种隔离,而且卖家对延迟的敏感度非常高,所以按照卖家维度切分,在单元内封闭,而卖家和商品都是在中心写入。

    数据方面的两个核心要求:

    1. 一致性,要求卖家和商品一致,单元和中心一致,也就是数据同步不能丢数据,不能错数据,还要保证事务。
    2. 实时性,需要做到秒级别的延迟。

    双单元的同步架构有两种:
    一种是读写分离的方式,中心写,单元读。单元需要的数据如果没有从中心及时同步过来,或者同步错了,那有问题这段时间的交易会全部收到影响。这里的核心是,保证秒级延迟,同时保证一致性。(JD的多中心交易系统就采用了这种方式)

    这里写图片描述

    第二种同步架构是单元封闭的方式。中心和单元各有写入,我们通过冗余是的中心和单元随时可以各自接管。(类似Otter)

    这里写图片描述

    这里的关键是:

    • 避免循环复制:通过在DB透传打标事务的方式实现。
    • 限流:峰值的压力,我们单元化本来就选取了流量激增业务,两边都实时同步100%全量数据,峰值对每个系统的压力有增无减。DRC的store和congo都可以根据TPS或者流量限流。限速算法的核心思想分为批量采样,奖惩时间,平滑变速。

    Otter与DRC的区别:

    • Otter是阿里B2B的产品,DRC是阿里技术保障团队的产品
    • Otter是针对MySQL的,DRC可以支持多种类型的数据源
    • DRC从业务上进行了划分,可以实现单元内封闭,Otter的实现不涉及业务,而是在纯数据库层打通的技术
    • Otter是双写,DRC是中心写、分中心读,或者都部分写,相互同步。
    • Otter所处的网络环境较DRC差,解决一致性问题也较复杂(基于trusted source的单向环回的补救,基于时间交集的补救),DRC有两种实现方式,具体参考上面。

    异地多活中DRC的核心能力就是在低延迟,一致性和高可用。

    这里写图片描述

    • 一致性:基于日志流式抓取、回放库表结构变更、基于事务的冲突检测。
    • 低延迟:最大延迟不超过1s, 消息协议优化,三级数据存储,预读优化IO, 多连接复用和传输压缩,高效的并发复制算法。
    • 高可用:主备切换,拓扑变化,心跳跟踪,多维度容灾。

    JD多中心交易系统

    JD. 多中心交易系统。

    JD数据复制中间件考察和借鉴了开源社区的实现,例如Databus、Canal/Otter、OpenReplicator等,解析部分使用了Canal的DBSync。

    多中心交易本质上是一个更大的分布式系统,交易流程中依赖和产生的数据和服务有不同的特点,必然涉及到数据分区、路由、复制、读写一致性、延迟等分布式领域的常见问题。

    其中,数据一致性是电商网站需要面临的首要问题,越是流量增大的时候越要保证数据更新的即时性和准确性。在多中心之间需要同步卖家数据和商品数据,如果同步的延时太长,买家、卖家都不可接受。比如,卖家改了价格或库存,用户不能过很久才看到。同样,数据正确性也是很大的挑战,卖掉的商品能够及时减少,退货的商品能够及时增加。这都时刻考验着后端系统和数据库平台的健壮性。

    除了数据一致性之外,如何保证路由规则的一致性也是关键性的问题。从技术角度来说,要保障单一用户从登录到访问服务、到访问数据库,全链路的路由规则都是完全一致的。如果路由错误,看到的数据不正确,也会影响到最终用户的体验。

    架构

    这里写图片描述

    系统包括一个主中心和多个分中心,主中心与分中心之间通过数据总线交换数据。数据流向中,主数据(商品数据、商家数据、用户数据等)的流向从主中心通过数据总线实时同步到分中心,分中心只读;而交易数据(订单数据)的流向从分中心实时同步到主中心;在故障时,会从分中心转移到主中心。

    在这个系统中,有多处体现分流的概念。首先,买家访问京东网站下单时,会被优先分流到附近的交易中心;其次,根据交易系统的特点,接单前(包括购物车、结算页等),多中心交易按用户维度分流,如下图所示。用户登录时,查询用户与区域的映射关系表(类似你是哪个片区的),标识此用户属于哪个分中心,并保存标识到cookie中,然后将用户路由到指定的分中心。用户访问其他系统,如购物车和结算页时,从cookie中读取标识,重定向到相应分中心页面。

    通过分流,将用户分配到相应的分中心,一方面响应速度快,用户体验更好,不用跨地域访问数据中心了;另一方面,每个中心服务一定数量的用户,水平扩展性好,也能支撑更大的交易规模了。当然,多数据中心不能盲目干活,还考虑到容灾备份的问题。(支付宝光纤事件)

    交易系统包括应用和数据部分,应用部分是无状态的,就是说,这些工作是无差别的,一台服务器出问题,我换一台服务器来处理就是了,较容易实现多机房多活。但是数据不一样,多中心交易本质上是一个更大的分布式系统,必然涉及到数据分区、路由、复制、读写一致性、延迟等分布式领域的常见问题。

    另外,交易流程中依赖和产生的数据和服务有不同的特点。比如商品、促销和价格、库存的读服务,我们可以将之称为基础主数据,它们在用户下单流程中是无法分区的,否则无法实现单机房内流量闭环,也就是说,不能因为分区数据的不一致,导致同一用户在单一流程中看到不同的数据(假如你加入购物车时是促销20块,结账是25块,你会不会表情扭曲?)而商品、促销和价格的写服务,是给采销、第三方POP商家应用调用的,这种业务场景的可用性目标,主机房部署和冷备模式即可满足,而且业务人员的操作流程会抵消写复制延迟。

    简单来说,数据的问题表现在以下几个方面:一、 如何保证数据的即时性和准确性,多中心之间需要同步卖家数据和商品数据,如果同步的延时太长,买家、卖家都不可接受,由于是异地部署,最好延时能控制在1秒内。比如,卖家改了价格或库存,用户不能过很久才看到。同样,数据正确性也是很大的挑战,因为数据故障跟应用层故障不一样,应用出故障了,可能只影响用户访问;数据写错了无法恢复。2、如何保证路由规则的一致性,要保障这个用户从进来到访问服务,到访问数据库,全链路的路由规则都是完全一致的;如果路由错误,看到的数据不正确。

    从同城双机房的分布转变为异地多机房的分布,给数据同步带来了新的挑战,因此如何设计数据总线也是项目能否实现的关键因素。京东的多中心交易系统通过数据总线JingoBus进行快速数据交换,同步性能是mysql的3倍以上,而且可用性高,架构灵活。其中,全新的总线设计解决了多中心交易跨机房的数据库复制和多数据源间的数据异构同步等难题,实现了高性能、低延时、健壮的数据同步机制。

    这里写图片描述

    如图所示,数据总线主要分Relay、Snapshot和Replicator三部分构成,其中Relay从来源数据库抽取事务日志,并对Replicator提供日志订阅服务,角色上相当于Mysql Slave IO Thread。Snapshot从Relay订阅所有事务日志,写入持久存储作为快照,同时向Replicator提供批量日志订阅服务,角色上相当于Mysql Slave Relay Log。Replicator:事务日志的消费端,从Relay或Snapshot拉取事务日志将事务日志按配置的一致性应用到目标数据库,角色上相当于Mysql Slave SQL Thread。(参考下面MySQL主备复制原理图)

    这里写图片描述

    正常情况下,Replicator直接连接Relay,消费Relay内存队列中的事务日志。但有些情况下,因为网络抖动、目标库的负载过高等因素,可能导致Replicator相对Relay落后很多。另外,当新的消费端加入同一数据源的订阅者时,新消费端有冷启动的问题。为了避免重新从数据源做全量快照,Snapshot作为Relay的一个特殊消费端,通过一种高吞吐的消费方式,从Relay源源不断的消费在线事务日志,通过对事务日志的有效处理,最终保存了数据源的一份一致快照(Consistent Snapshot),即包括了数据源库表中每一行的最新状态的快照,同时保留了一段比Relay buffer更旧的事务日志(Log Store)。由此看来,数据总线作为一个数据层的通用CDC组件,对于多中心交易项目以及异步复制场景提供了整体解决方案,奠定了项目的核心内容。


    跨数据库(数据源)迁移

    yugong

    去Oracle数据迁移同步工具。定位:数据库迁移(目前主要支持Oracle->mysql/DRDS)

    08年左右,阿里巴巴开始尝试MySQL的相关研究,并开发了基于MySQL分库分表技术的相关产品,Cobar/TDDL(目前为阿里云DRDS产品),解决了单机Oracle无法满足的扩展性问题,当时也掀起一股去IOE项目的浪潮,愚公这项目因此而诞生,其要解决的目标就是帮助用户完成从Oracle数据迁移到MySQL上,完成去IOE的第一步.

    概述

    整个数据迁移过程,分为两个部分:

    1. 全量迁移
    2. 增量迁移

    这里写图片描述

    过程描述:

    1. 增量数据收集(创建Oracle表的增量物化视图)
    2. 进行全量复制
    3. 进行增量复制(可并行进行数据校验)
    4. 原库停写,切换到新库

    Oracle全量基于JDBC拉取数据,增量基于物化视图来实现。

    架构

    这里写图片描述

    说明:

    1. 一个JVM Container 对应多个instance,每个instance对应于一张表的迁移任务
    2. instance分为三部分
      • extractor (从数据源库上提取数据,可分为全量/增量实现)
      • translator (将源库上的数据按照目标库的需求进行自定义转化)
      • applier(将数据更新到目标库,可分为全量/增量/对比的实现)

    自定义数据转换

    如果要迁移的Oracle和mysql的表结构不同,比如表名,字段名有差异,字段类型不兼容,需要使用自定义数据转换。如果完全相同则可以跳过。

    整个数据流为:DB->Extractor->DataTranslator->Applier->DB, 本程序预留DataTranslator接口(仅支持Java),允许外部用户自定义数据处理逻辑。比如:

    1. 表名不同
    2. 字段名不同
    3. 字段类型不同
    4. 字段个数不同
    5. 运行过程join其他表的数据做计算等

    运行模式介绍

    1.MARK模式(MARK)

    开启增量日志模式,如果是Oracle就是创建物化视图(materialized view)。

    2.CLEAR模式(CLEAR)

    清理增量日志的几率,如果是Oracle就是删除物化视图

    3.全量模式(FULL)

    全量模式,顾名思议即为对源表进行一次全量操作,遍历源表所有的数据后,插入目标表.

    全量有两种处理方式:

    1. 分页处理:如果源表存在主键,只有一个主键字段,并且主键字段类型为Number类型,默认会选择该分页处理模式. 优点:支持断点续做,对源库压力相对较小。 缺点:迁移速度慢
    2. once处理:通过select * from访问整个源表的某一个mvcc版本的数据,通过cursor.next遍历整个结果集. 优点:迁移速度快,为分页处理的5倍左右。 缺点:源库压力大,如果源库并发修改量大,会导致数据库MVCC版本过多,出现栈错误. 还有就是不支持断点续做.

    4.增量模式(INC)

    全量模式,顾名思议即为对源表增量变化的数据插入目标表,增量模式依赖记录日志功能.

    目前增量模式的记录日志功能,是通过oracle的物化视图功能。

    5.自动模式(ALL)

    自动模式,是对全量+增量模式的一种组合,自动化运行,减少操作成本.

    自动模式的内部实现步骤:

    1. 开启记录日志功能. (创建物化视图)
    2. 运行全量同步模式. (全量完成后,自动进入下一步)
    3. 运行增量同步模式. (增量模式,没有完成的概念,所以也就不会自动退出,需要业务判断是否可以退出,可以看一下切换流程)

    6.对比模式(CHECK)

    对比模式,即为对源库和目标库的数据进行一次全量对比,验证一下迁移结果. 对比模式为一种可选运行,做完全量/增量/自动模式后,可选择性的运行对比模式,来确保本次迁移的正确性.

    DataX

    DataX是一个在异构的数据库/文件系统之间高速交换数据的工具,实现了在任意的数据处理系统(RDBMS/Hdfs/Local filesystem)之间的数据交换。

    目前成熟的数据导入导出工具比较多,但是一般都只能用于数据导入或者导出,并且只能支持一个或者几个特定类型的数据库。

    这样带来的一个问题是,如果我们拥有很多不同类型的数据库/文件系统(Mysql/Oracle/Rac/Hive/Other…),并且经常需要在它们之间导入导出数据,那么我们可能需要开发/维护/学习使用一批这样的工具(jdbcdump/dbloader/multithread/getmerge+sqlloader/mysqldumper…)。而且以后每增加一种库类型,我们需要的工具数目将线性增长。(当我们需要将mysql的数据导入oracle的时候,有没有过想从jdbcdump和dbloader上各掰下来一半拼在一起到冲动?)这些工具有些使用文件中转数据,有些使用管道,不同程度的为数据中转带来额外开销,效率差别很非常大。很多工具也无法满足ETL任务中常见的需求,比如日期格式转化,特性字符的转化,编码转换。另外,有些时候,我们希望在一个很短的时间窗口内,将一份数据从一个数据库同时导出到多个不同类型的数据库。DataX正是为了解决这些问题而生。

    这里写图片描述

    • 左图:新增第n+1个数据源,是不是需要开发n个数据同步工具?
    • 右图:只需要针对新增的数据源开发一套Reader/Writer插件,即可实现任意数据的互导。

    设计理念

    为了解决异构数据源同步问题,DataX将复杂的网状的同步链路变成了星型数据链路,DataX作为中间传输载体负责连接各种数据源。当需要接入一个新的数据源的时候,只需要将此数据源对接到DataX,便能跟已有的数据源做到无缝数据同步。

    DataX在阿里巴巴集团内被广泛使用,承担了所有大数据的离线同步业务,并已持续稳定运行了6年之久。目前每天完成同步8w多道作业,每日传输数据量超过300TB。

    框架设计

    这里写图片描述

    DataX本身作为离线数据同步框架,采用Framework+plugin架构构建。将数据源读取和写入抽象称为Reader/Writer插件,纳入到整个同步框架中。

    • Reader: Reader为数据采集模块,负责采集数据源的数据,将数据发送给Framework.
    • Writer:Writer为数据写入模块,负责不断向Framework取数据,并将数据写入到目的端
    • Framework:Framework用于连接reader和writer,作为两者的数据传输通道,并处理缓存,流控,并发,数据转换等核心技术问题。

    DataX框架内部通过双缓冲队列、线程池封装等技术,集中处理了高速数据交换遇到的问题,提供简单的接口与插件交互,插件分为Reader和Writer两类,基于框架提供的插件接口,可以十分便捷的开发出需要的插件。比如想要从oracle导出数据到mysql,那么需要做的就是开发出OracleReader和MysqlWriter插件,装配到框架上即可。并且这样的插件一般情况下在其他数据交换场合是可以通用的。

    核心架构

    DataX3.0 开源版本支持单机多线程模式完成同步作业运行,这里按一个DataX作业生命周期的时序图,从整体架构设计非常简要说明DataX各个模块相互关系。

    这里写图片描述

    核心模块介绍:

    1. DataX完成单个数据同步的作业,我们称之为Job,DataX接受到一个Job之后,将启动一个进程来完成整个作业同步过程。DataX Job模块是单个作业的中枢管理节点,承担了数据清理、子任务切分(将单一作业计算转化为多个子Task)、TaskGroup管理等功能。
    2. DataXJob启动后,会根据不同的源端切分策略,将Job切分成多个小的Task(子任务),以便于并发执行。Task便是DataX作业的最小单元,每一个Task都会负责一部分数据的同步工作。
    3. 切分多个Task之后,DataX Job会调用Scheduler模块,根据配置的并发数据量,将拆分成的Task重新组合,组装成TaskGroup(任务组)。每一个TaskGroup负责以一定的并发运行完毕分配好的所有Task,默认单个任务组的并发数量为5。
    4. 每一个Task都由TaskGroup负责启动,Task启动后,会固定启动Reader—>Channel—>Writer的线程来完成任务同步工作。
    5. DataX作业运行起来之后, Job监控并等待多个TaskGroup模块任务完成,等待所有TaskGroup任务完成后Job成功退出。否则,异常退出,进程退出值非0。

    DataX调度流程:

    举例来说,用户提交了一个DataX作业,并且配置了20个并发,目的是将一个100张分表的mysql数据同步到odps里面。 DataX的调度决策思路是:

    1. DataXJob根据分库分表切分成了100个Task。
    2. 根据20个并发,DataX计算共需要分配4个TaskGroup。
    3. 4个TaskGroup平分切分好的100个Task,每一个TaskGroup负责以5个并发共计运行25个Task。

    Datax插件开发:https://github.com/alibaba/DataX/wiki/DataX%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E5%AE%9D%E5%85%B8

    欢迎跳转到本文的原文链接:https://honeypps.com/architect/collection-of-database-related-middleware/


    欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。


    展开全文
  • 数据库相关中间件

    千次阅读 2016-11-17 20:52:56
    这里主要介绍互联网行业内有关数据库的相关中间件数据库相关平台主要解决以下三个方面的问题: 为海量前台数据提供高性能、大容量、高可用性的访问 为数据变更的消费提供准实时的保障 高效...
  • 数据库相关中间件介绍

    千次阅读 2018-06-01 02:40:46
    数据库相关中间件介绍这里主要介绍互联网行业内有关数据库的相关中间件数据库相关平台主要解决以下三个方面的问题:为海量前台数据提供高性能、大容量、高可用性的访问为数据变更的消费提供准实时的保障高效的异地...
  • 数据库中间件漫谈

    千次阅读 2020-03-14 15:37:03
    1.前言 随着业务的发展,MySQL数据库中的表会越来越多,表中的数据量也会越来越大,相应地,数据操作的开销也会越来越大;...本文主要针对业界主流的数据库中间件的实现、功能、成本等方面进行对...
  • 数据库访问中间件

    2020-06-26 10:35:15
    一、ORM ORM:对象关系映射(Jbject Relational Mapping),实现面向对象编程语言里不同类型系统... 映射:ORM提供了实现持久化层的另一种模式,采用映射元数据(XML)来描述对象-关系的映射细节,使得ORM中间件能在任...
  • 数据库中间件 这里主要介绍互联网行业内有关数据库的相关中间件数据库相关平台主要解决以下三个方面的问题: 为海量前台数据提供高性能、大容量、高可用性的访问为数据变更的消费提供准实时的保障高效的异地数据...
  • 相对于业务逻辑分库分表,通过DBProxy数据库中间件,可以更简单轻松更快的对数据库进行水平扩展,由原来单台数据库扩展到多台数据库数据库中间件通过路由规则将数据的访问请求路由到其中一台数据库上,从而...
  • 数据库同步中间件

    千次阅读 2016-03-23 11:57:29
    不过早期的数据库同步业务,主要是基于trigger的方式获取增量变更,不过从2010年开始,阿里系公司开始逐步的尝试基于数据库的日志解析,获取增量变更进行同步,由此衍生出了增量订阅&消费的业务,从此开启了一段新...
  • 简介数据库中间件设计理论和要点,了解数据库中间件选型。
  • 网上搜索Delphi三层架构的服务器端开发,大部分的博文都详细阐述了如何使用DataSnap、Socket或者Dcom技术来时间与客户端的信息交互,大部分需要安装插件……虽然这种种方式能实现三层通讯,但是在跨语言通信方面似乎...
  • 数据库中间件-Middleware

    千次阅读 2018-08-19 19:37:52
    中间件根据不同的功能又可以分为不同的种类,比如服务中间件Tomcat,消息中间件MQ等,这里主要讨论数据库中间件数据库平台需要解决以下三个问题: 可以为各个服务提供高性能、大容量、高可用的数据访问 满足...
  • 比较两个非常流行的开源分布式数据库中间件:Mycat 和 ShardingSphere(包括 Sharding-JDBC、Sharding-Proxy 和 Sharding-Sidecar 3 款产品)。另外还有一个增强版的Mycat:DBLE(专注于 MySQL) 。
  • 分布式数据库中间件—TDDL

    千次阅读 2018-06-05 21:15:20
    项目中一直在用着TDDL,但除了接入时简单了解了下他的用法和原理外,也没有过多的深究其背后的实现,毕竟在阿里内部用到的中间件太多,每一个都深入的学习需要的周期太长,再者项目中数据库层也没有用到分布式,没有...
  • 数据库中间件——MyCat

    千次阅读 2018-01-23 17:20:21
    第一章 概述 数据库切分概述 1-1-1 OLTP和OLAP 1-1-2 关系型数据库和NoSQL数据库 1-1-3 数据切分 第二章 MyCat简介 ...3-1 数据库中间件 3-2 逻辑库schema 3-3 逻辑表table 3-3-1 逻辑表 3-3-2 分片表 3-3-3 非
  • 数据库相关中间件(下)

    千次阅读 2016-11-23 11:16:40
    基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了mysql. 有关数据增量订阅与消费的中间件回顾一下: 增量订阅和消费模块应当包括binlog日志抓取,binlog日志解析,事件分发过滤...
  • 全球最大的开源软件基金会Apache软件基金会...Apache ShardingSphere是一款分布式数据库中间件,该项目在京东数科逐渐发展壮大,成为业界首个Apache分布式数据库中间件项目。Apache ShardingSphere目前已被130家以...
  • Tddl是一个分布式数据库中间件,主要是为了解决分布式数据库产生的相关问题,因此在学习tddl之前我们先了解一下分布式数据库的演化历程,所谓磨刀不误砍柴工,知其然亦要知其所以然,分布式数据库数据库中间件...
  • Web数据库中间件技术

    2008-04-30 21:56:00
    站点的用户交互的各种程序的标准,使用CGI脚本允许用户在浏览器中等服务器上的数据库交互,完成对数据库的各种操作。 几乎使用的服务器软件都支持CGI,开发者可以使用任何一种 Web 服务器内置语言编写CGI,包括Perl...
  • Mycat是数据库中间件,就是介于数据库与应用之间,进行数据处理与交互的中间服务。由于前面讲的对数据进行分片处理之后,从原有的一个库,被切分为多个分片数据库,所有的分片数据库集群构成了整个完整的数据库存储...
  • 通过无中心、零侵入的方案提供与数据库交互的的啮合层,即Database Mesh,又可称数据库网格。 Apache ShardingSphere的亮点包括: 完善的分布式数据库解决方案。提供数据分片、分布式事务、数据弹性迁移、数据库和...
  • ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(计划中)这3款相互独立的产品组成。 他们均提供标准化的数据分片、分布式事务和数据库...
  • Vitess 是一个用于 MySql 扩展的数据库解决方案。它以能够像运行在专用硬件上那样有效地运行在云体系为目标进行架构。它集 MySql 数据库的很多重要特性和 NoSQL 数据库的可扩展性于一体。Vitess 已经成功侍服了 2011...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,083
精华内容 18,833
热门标签
关键字:

数据库作为交互中间件