数据库相关中间件(上)

来源:互联网 发布:广电网络电视怎么点播 编辑:程序博客网 时间:2024/05/21 18: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基础上发展的版本,两个显著提高:

  1. 后端由BIO改为NIO,并发量有大幅提高;

  2. 增加了对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中提供了一键部署、自动和手动备份,版本管理等平台化功能。

0 0
原创粉丝点击