从Cobar到Mycat,从闭源到开源,作为一个开源的分布式数据库中间件,Mycat已经被众多开源项目使用。本文简要介绍下Mycat的特性、基本架构以及分库分表和读写分离的配置。
Mycat是一个开源的分布式数据库中间件,前端用户将其看作是一个数据库代理,使用mysql客户端和命令行工具进行访问,后端使用mysql协议或者JDBC协议与主流的数据库服务器如MySQL、Oracle、DB2、PostgreSQL等进行通信。Mycat本身并不存储数据,数据的存储是由后端的存储引擎实现的,因此数据的可靠性以及事务等都由后端数据库保证。
Mycat作为数据库中间件,其核心功能是分表分库,将一个大表根据切分策略分为不同的小表分布在不同的数据存储分片上,所有的数据分片构成完整的数据库存储。
数据切分指的是将数据根据某种规则分散存放在多个数据库服务器上,以达到负载分散的效果。数据的切分(sharding)根据切分规则的类型,可以分为垂直切分和水平切分两种模式:
分库分表根据垂直和水平切分分为四种:水平分库、水平分表、垂直分库、垂直分表。
Mycat主要原理是通过对SQL的拦截,然后经过一定规则的分片解析、路由分析、读写分离分析、缓存分析等,然后将SQL发给后端真实的数据块,并将返回的结果做适当处理返回给客户端。如图,表t1分为3个分片,这三个分片分布在两台mysql数据库服务器上,这里的分片字段为city分片规则为字符串枚举方式。
当Mycat收到一个SQL时,会先解析这个SQL,查找涉及到的表,然后看此表的定义,如果有分片规则,则获取到SQL里分片字段的值,并匹配分片函数,得到该SQL对应的分片列表,然后将SQL发往这些分片去执行,最后收集和处理所有分片返回的结果数据,并输出到客户端。
Mycat从2013年发展到现在Mycat 1.6版本,再到Mycat2,有以下典型的使用场景:
Mycat不适合无分片条件的SQL、跨分片join超过3个会带来性能问题、分片表分片表不建议使用深分页即limit 10000,1。
Mycat整体架构上由以下模块组成:通信协议、路由解析、结果集处理、数据库连接、监控等模块。
1)通信协议模块
通信协议模块承担底层的收发数据、线程回调处理工作,主要采用Reactor、proactor模式来提高效率。目前Mycat通信模块默认釆用Reactor模式,在协议层采用MySQL协议。
2)路由解析模块
路由解析模块负责对传入的SQL语句进行语法解析,解析从MySQL协议中解析出来并进入该模块的SQL语句的条件、语句类型、携带的关键字等,对符合要求的SQL语句进行相关优化,最后根据这些路由计算单元进行路由计算。
3)结果集处理模块
结果集处理模块负责对跨分片的结果进行汇聚、排序、截取等。由于数据存储在不同的数据库中,所以对跨分片的数据需要进行汇聚。
4)数据库连接模块
数据库连接模块负责创建、管理、维护后端的连接池。为了诚少每次建立数据库连接的开销,数据库使用连接池机制对连接生命周期进行管理
5)监控管理模块
监控管理模块负责对Mycat中的连接、内存等资源进行监控和管理。监控主要是通过管理命令实时地展现一些监控数据,例如连接数、缓存命中数等;管理则主要通过轮询事件来检测和释放不使用的资源。
6)SQL执行模块
SQL执行模块负责从连接池中获取相应的目标连接,对目标连接进行信息同步后,再根据路由解析的结果,把SQL语句分发到相应的节点执行。
Mycat主要线程如下:
Mycat通过定义表的分片规则来实现分片,分片规则中会定义分片字段和分片算法,分片算法包括hash、取模和范围分区等。每个表可以捆绑一个分片规则,每个分片规则指定一个分片字段并绑定一个函数,来实现动态分片算法 。
Mycat中配置文件主要有schema.xml和rule.xml:schema.xml指定的是各个数据库节点与Mycat中虚拟数据库和表的关联关系,并且指定了当前表的分表策略;在rule.xml中则指定了具体的分表策略及其所使用的算法实现类。Mycat中常用分片算法包括取模、范围分片和一致性hash算法,以下分别介绍三种算法配置。
取模分片规则是对分片字段进行求模运算。
select user()
a
select user()
select user()
rules.xml配置如下:
id
mod-long
3
按照范围分片,顾名思义,就是首先对整体数据进行范围划分,然后将各个范围区间分配到对应的数据库节点上,当用户插入数据时,根据指定字段的值,判断其属于哪个范围,然后将数据插入到该范围对应的数据库节点上。
rules.xml配置如下:
id
range-id-count
files/tb-range-partition.txt
0
其中mapFile指定范围和数据节点的对应关系,如下:
0-10=0
11-50=1
51-100=2
101-1000=0
1001-9999=1
10000-9999999=2
一致性Hash是基于一致性Hash算法实现分片
rule.xml文件如下:
id
hash
0
3
160
/usr/local/mycat/bucketMap.txt
在MySQL集群主从复制架构中,通过配置mysql可以实现读写分离。如图所示,MySQL节点开启主从复制的配置方案,并将主节点配置为Mycat的dataHost里的writeNode,从节点配置为readNode,同时Mycat内部定期对一个dataHost里的所有writeHost与readHost节点发起心跳检测.正常情况下,Mycat会将第一个writeHost作为写节点,所有的DML SQL会发送给此节点,因为Mycat开启了读写分离,则查询节点会根据读写分离的策略发往 readHost(+writeHost)执行。
在schema.xml文件中配置读写分离,通过配置writeHost和readHost实现读写分离策略。
show slave status
Mycat的诞生源自于阿里Cobar数据库中间件,这是一个完全由开源社区自主研发的分布式数据库中间件,自诞生以来深受各类开源软件项目喜爱,一直保持着社区活跃度。Mycat 1.6版本更新停滞有一段时间,现在又出现mycat2,据说是代码层完全重构了,但依旧秉持着开源的理念在贡献着,即使是在目前如火如荼发展的分布式数据库产品中,各类商业化的分布式数据库中间件层出不穷。就像mycat官网说的:
MYCAT并不依托于任何一个商业公司,因此不像某些开源项目,将一些重要的特性封闭在其商业产品中,使得开源项目成了一个摆设。
参考资料: