谭鹏 朱艳辉 杨芸桦
摘要:目前互联网公司数据吞吐量急速上升,传统的单一数据库服务器架构已经不再满足需求。当数据库服务器出现性能瓶颈问题时,仅靠增加服务器性能无法从根本上解决问题,因此需要水平扩展,即将数据库水平扩展到多台服务器。实现水平扩展的软件就叫数据访问层中间件,该文采用分布式架构设计了两种数据访问层中间件:客户端数据库中间件和服务端数据库中间件。使用Java语言进行开发,数据库用的是使用最广的关系型数据库MySQL。实现了数据库的分库分表、读写分离等操作,提升了数据访问层的响应速度以及数据访问层的系统稳定性。
关键词:数据库中间件;分库分表;读写分离;限流;MySQL协议
中图分类号:TP391 文献标识码:A 文章编号:1009-3044(2018)24-0007-03
Abstract: At present the Internet company data throughput grew rapidly, the traditional single database server architecture is no longer meet the demand.When the database server performance bottleneck problems, only by increasing server performance can not fundamentally solve the problem, so you need to scale, the database level extended to multiple servers.Realize the scale of software is called the data access layer middleware, this paper adopts distributed architecture design for two kinds of data access layer middleware: client database middleware and the server database middleware.Using Java language development, database is the most widely use relational database MySQL.Separation for depots table, the database to read and write operations, improve the response speed of the data access layer and data access layer of the system stability.
Key words: Database Middleware; Sharding; Read Write splitting; current-limiting; MySQL protocol
目前互联网公司数据吞吐量急速上升,传统的单一数据库服务器架构已经无法满足需求。单一数据库服务器的架构方式在遇到系统访问量急剧上升时很容易出现响应速度变慢甚至数据库服务器宕机的情况。如何提升系统数据访问层的响应速度以及如何提升数据库这一层的稳定性成为我们急需解决的难题,数据库中间件就是解决上述问题的核心技术。数据库中间件具有削峰的能力[1],需要像MySQL一样支持事务操作[1]。
分布式数据层中间件(DDLM)把业务逻辑层的每条SQL语句(下文记作逻辑 SQL 语句)按照垂直、水平拆分的策略解释成多个SQL语句,解释后的每条 SQL 语句(下文记作物理 SQL 语句)对一个数据源进行操作,从而一条逻辑 SQL语句被解释成多条物理SQL语句,因此DDLM具有分布式的特性[2]。
数据库中间件在业界主要有两种做法,一个是将其部署到客户端,这种架构形式叫作客户端数据库中间件,另外一种是将其单独部署在服务器集群上,这种架构形式叫作服务端数据库中间件。本文对两种架构形式进行了对比分析设计和实现。
1 系统功能分析
1.1 分库分表(Sharding)
分库分表是数据库中间件最为核心的需求,主要包括分库、分表以及分库分表等。要求对原计划发往一个数据库的SQL请求进行尽可能均匀的分片,使其发往不同的数据库分片。从而降低单库的性能瓶颈,提高数据访问层的响应速度。
分库分表分为垂直切分和水平切分,切分的内容又包括数据表和数据库。垂直分库和垂直分表需在业务端处理,不属于数据库中间件的范畴。垂直分库是指将按照业务模块来划分出不同的数据库,而不是像早期一样将所有的数据表都放到同一个数据库中。垂直分表是指将表结构按照字段的常用与不常用进行切分,让一个表切分成多个表,这样做的好处在于有些大的字段并非经常使用的字段,将其分开之后可以极大地提升数据访问的效率。水平分表是指维持数据的表结构不变,按照某个特定的字段采取哈希等方式让其水平切分到多个表结构相同的表当中。
以上的切分方法各有各自的优缺点,所以一般会将其混合使用。目前最常见的方式為水平分库分表,所谓的水平分库分表是指在水平分表的基础上,让各子表按照一定的规则划分到不同的数据库分片当中,让多个数据库分片同时承担访问压力,这样就解决了水平分表无法解决单一数据库分片的瓶颈问题,也就提升了数据访问的速度。
1.2 读写分离
读写分离是数据库中间件的第二核心功能,主要是指在数据访问层将读操作和写操作进行分离。所有的写操作进入master库,所有的读操作进入slave库。主库和从库之间采用BinLog的形式进行数据同步。这样做的好处在于:提高数据访问层的响应速度、极大程度的缓解X锁和S锁争用、由于从库只负责读,所以可以将从库的MySQL存储引擎配置成MyISAM,提升查询效率、增加冗余,提高系统的可用性。
1.3 限流
在业务高峰期,整个系统的负载迅速上升,数据库的压力变大,这时候很容易造成大流量冲击数据库从而导致数据库响应速度过慢甚至出现宕机等现象,这会严重影响用户体验。数据库中间件可以做到在数据访问层进行限流操作,利用访问数据库之前先拿到数据库信号量的形式使得流量以可控的状态通往数据访问层下层的数据库层,从而起到限流以及保护数据库的作用。
2 系统设计与实现
2.1 技术介绍
本系统采用Java语言进行开发,采用了分布式架构,数据库采用MySQL数据库。客户端数据库中间件以重写JDBC接口的形式进行实现,服务端数据库中间件依赖Netty NIO线程池以及MySQL协议解析操作进行实现。其中服务端涉及MySQL的三次握手以及报文解析等操作。
目前业界对于数据库中间件有两种部署形式,一种是将其部署在客户端,叫作客户端数据库中间件,一种是将其部署在服务端,叫作服务端数据库中间件。
2.2 客户端数据库中间件
客户端数据库中间件是指将系统打包到公司的maven仓库当中,所有需要使用的应用程序以依赖导入的形式将其加载进来,然后进行数据库切片以及切片路由规则的配置就可以直接使用了。客户端数据库中间件的优点在于无需单独部署到服务器集群,节约了大量的硬件成本。且它的研发较服务端数据库中间件来说比较简单,无需涉及MySQL的报文解析等底层操作。但这种形式无法做到数据访问服务的集中管理,且监控和升级服务也会十分的不方便。
客户端数据库中间件的整体流程图如图1所示。
2.3.1 配置模块
配置模块主要采用Spring schema扩展技术,将对象的创建以xml配置的形式注入Spring容器当中,使得系统部分与功能部分进行大幅度的解耦。
核心步骤为:
1) 编写自定义类;
2) 编写schema来描述自定义元素;
3) 编写Handler ;
4) 编写Parser;
5) 编写META-INF/spring.handlers,META-INF/spring.schemas文件对Handler和schema进行注册。
2.3.2 实现JDBC核心接口
重写JDBC接口方法是客户端数据库中间件最核心的一个功能模块。Sharding、读写分离都需要依靠JDBC接口方法重写进行拦截。本系统主要实现的接口有DataSource接口、Connection接口、Statement接口以及PreparedStatement接口。
2.3.3 分库分表
分库分表是本系统最核心的一个功能模块,主要负责的是将原始的SQL请求进行拆分,使得原计划通往一个数据库的SQL请求尽可能均匀地切分到不同的分表中,然后分表按照一定的规则对应不同的数据库分片。让原本只会发往一个数据库分片的SQL请求尽可能均匀的发送到不同的数据库分片中,从而提升系统的响应速度。
2.4 服务端数据库中间件
服务端数据库中间件是指将数据库中间件作为一种服务进行单独部署。服务端数据库中间件介于客户端与数据库之间,是数据库的一种代理,用户可以像使用MySQL一样使用我们。其中涉及MySQL底层协议的分析及解析。服务端数据库中间件的优点在于支持多语言的应用,不管是Java应用还是Python应用,只要它使用的数据库是MySQL数据库,都可以直接使用我们的服务。但客户端数据库无法做到这点,客户端数据库需针对每种语言重写一套新的接口才能实现多语言的支持。服务端数据库中间件的第二个优点在于可以集中管理,监控和升级服务也很方便。初次之外,服务端数据库中间件还可以很好地在数据访问层做到数据库的限流操作。缺点在于需单独部署到服务器集群中,所以存在硬件成本开销。
服务端数据库中间件的整体流程图如图2所示。
2.4.1 系统架构说明
服务端数据库中间件是实现MySQL协议的一种MySQL代理,服务端数据库中间件在接入之后,客户端无需直连数据库。这种情形下,系统必须考虑高并发的情况。本系统分为前端和后端,前端后端各启了一个Netty的NIO线程池,前端负责数据库中间件服务与上层客户端的通信,后端负责数据库中间件服务于下层数据库之间的通信。
服务端数据库中间件的系统架构图如图3所示。
2.4.2 分库分表
与客户端数据库中间件的分库分表模块类似,服务端数据库最核心的功能也是实现数据库的分片操作。将原始的SQL请求进行拆分,使得原计划通往一个数据库的SQL请求尽可能均匀地切分到不同的数据库分片当中,从而提升系统的响应速度。
2.4.3 读写分离
读写分离的核心思想是在数据访问层将通往MySQL的请求按照读写进行分类,分为读操作和写操作。且所有的MySQL数据库分片都自带一个叫作role的属性,role可以是master也可以是slave。
将上述两项内容综合起来就是我们读写分离模块的架构了:所有的写操作全都路由到role为master的数据库分片当中,所有的读操作都路由到role为slave的数据库分片当中。
将读写操作进行分开之后,我们可以將所有的slave分库的MySQL存储引擎配置成MyISAM,这样会提升查询速度,从而提升数据访问层的响应速度。
3 结语
本文对数据库中间件进行了一个系统的描述,且按照客户端数据库中间件和服务端数据库中间件对其分别进行了设计和实现,比较了它们各自的优缺点。
无论是客户端数据库中间件还是服务端数据库中间件,都可以很好的提升数据访问层的响应速度,降低单节点的负载,提升系统的稳定性。
两种数据库中间件的对比:
(1) 客户端数据库中间件针对不同语言需开发一套系统;
(2) 客户端数据库中间件在升级时不方便统一管理,不方便监控;
(3) 客户端数据库中间件无需单独部署,节约了成本;
(4) 服务端数据库中间件支持多语言;
(5) 服务端数据库中间件在扩展数据库类型时,仅需实现一次数据库协议;
(6) 服务端数据库中间件需部署到物理服务器,成本较大;
(7) 服务端数据库中间件方便系统升级以及系统打点监控;
(8) 服务端数据库中间件是MySQL的一种代理,很方便做到限流
数据库中间件可以极大程度提升数据访问层的响应速度,降低数据库节点的负载,提高系统的稳定性,因此具有很高的经济价值,推广价值和应用价值。
参考文献:
[1] 漆绍洋.基于mysql的分布式访问中间件中sql处理模块的设计与实现[D].南京:南京大学,2016:26-29.
[2] 李文杰,周剑华.分布式应用层中间件的设计[J]. 微型机与应用, 2011,30(5): 14-16.
[3] 肖戈林.HTTP协议技术探析[J].江西通信科技,2001(1):20-27.
[4] MySQL网络协议分析[EB/OL]. https://www.colabug.com/1957195.html.
[5] 祝雄锋.数据库集群中间件MySQL Proxy研究与分析[D].武汉理工大学,2011.
【通联编辑:梁书】