表广播机制在MyCat中的实现
2018-03-20梁正和王法强
王 锦,梁正和,王法强
(河海大学 计算机与信息学院,江苏 南京 211110)
0 引 言
随着互联网技术的飞速发展,移动网络、局域网、广域网、Internet得到了巨大的发展,集中部署的单机数据库系统己经不能够适应这样的环境[1],使用服务器集群来解决海量数据[2]成为必然趋势,分布式数据库应运而生。MyCat分布式数据库中间件[3]由阿里巴巴的开源项目cobar[4]发展而来,其本身提供了分布式资源整合方案。该产品具有双机热备份、负载均衡、SQL语句重写、读写分离[5]、查询路由、多台数据库并行处理以及结果集合并等功能[6],并提供了对MySQL、PostGreSQL等应用广泛的开源关系型数据库的分布式支持。该分布式数据库中间件为用户提供廉价的数据库集群,平滑地将现有的单机集中式数据库和应用迁移到“云”[7]端,同时保留原有数据库的查询能力。
通过MyCat可以搭建以MySQL为底层节点的分布式数据库系统,系统通过MySQL的通信协议[8]与用户以及底层数据库通信。对于用户,通过该中间件能够透明地访问整个集群,故而原有的基于MySQL开发的应用均无需修改,直接迁移到分布式系统中。该系统在中间件中建立了完整的Schema(模式)、Table(表)、User(用户)的逻辑模型,将整套模型通过逻辑规则映射到每个数据节点上的MySQL实例中,并可以实现事务处理。
面对一些数据量巨大的表,可以通过MyCat对数据进行水平切分[9],在保证每个分片节点的表结构一致的情况下,将表映射到不同的数据引擎上,从逻辑上实现数据库容量的扩充。MyCat不支持跨分片连接查询,需要将与其关联的表设置为全局表分布在各个分片上。由于MyCat的弱Xa事务[10]机制,频繁操纵全局表可能会导致异常情况的发生:某个用户在修改好全局表提交的一瞬间,忽然某个节点出错了,可能会出现某些节点已成功修改而出错节点数据无变更,使得各个节点数据不一致的情况。对于一个大企业,该类问题是难以忍受的。MyCat中的表广播机制改变了原始的对全局表的操作逻辑,把原来的同时向多个节点发送的DML[11]消息,修改为只向全局表中的主节点发送广播消息,待主节点接收消息后再向其他节点发送广播,通知其他节点有新消息到达,实现各节点间的数据同步。若主节点在修改过程中突遇异常情况致使操作中断,则所有节点均无修改操作;若其他节点在同步过程中出现意外中断,待故障排除后,继续未完成的同步工作,成功解决了多个节点数据不一致的问题。
1 MyCat中的表广播机制
1.1 MyCat中的弱XA事务
MyCat中的事务主要包括SQL不跨分片事务和SQL跨分片事务[3]。对于SQL不跨分片这种情况,SQL仅仅是在一个数据节点上执行,此时MyCat事务模式同标准的数据库事务模式[12]完全一致,或提交、或回滚,能够保证强一致性[13];对于SQL跨分片的事务,首先事务内的SQL在各自的分片上执行并返回状态码,若某个分片上的返回码为ERROR,则MyCat认为事务失败,应用端只能回滚(rollback)事务,MyCat收到回滚指令后,依次回滚事务中涉及到的所有分片;若事务中的所有SQL的执行都返回成功(OK)的返回码,则应用程序提交事务,由MyCat同时向事务中涉及到的节点发送提交事务的指令(commit),在commit的时候,若某个节点出错,MyCat也无法等节点恢复后重新commit,出现部分节点commit成功而部分节点没有commit的情况。由于跨分片事务的第二阶段无法保证强一致性,称MyCat是一种弱XA事务模式。
1.2 表广播机制的基本原理
表广播机制的实现主要分为三个步骤:
(1)用户发送DML(数据操作语言)请求,主机接收到命令,向主节点发送广播。主节点接收到消息,将消息记录到二进制文件,并将消息发送给其他从节点。
(2)从节点读取消息,并将消息写入到自己的中继日志。
(3)从节点重做中继日志中的事件,并改变自己的数据。
如图1所示,主机接受请求后向主节点发送广播,主节点接收消息并记录二进制文件。在每个事务更新数据完成之前,主节点在二日志文件中记录这些改变。MySQL线程将事务串行地写入二进制日志,在事件写入完成后,主节点通知存储引擎提交事务并向其他从节点发送广播。
图1 表广播机制原理图
从节点接收到消息,将主节点的二进制日志拷贝到自己的中继日志。首先,从节点开始一个工作线程(I/O线程),I/O线程在主节点上打开一个普通的连接,然后开始二进制转存。二进制转存程序从主节点的二进制日志中读取消息事件,如果没有新的消息,它会睡眠并等待主节点发送新的广播。
SQL从线程从中继日志读取消息事件,并重放其中的事件以更新从节点中的数据,使其与主节点中的数据一致。
1.3 表广播机制在MyCat中的应用
MyCat是一个开源的分布式数据库系统,是一个实现了MySQL协议的server,前端用户可以把它看作一个数据库代理[14],用MySQL客户端工具和命令行访问,而其后端可以用MySQL原声(Native)协议[15]与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器[16]通信。MyCat中有两种典型类型的表,一种是按照某种给定的分片规则,将数据进行水平切分,把一个大表水平分割成N个小表,存储在后端MySQL服务器或者其他不同的数据库;另一种是全局表,MyCat接收外界发送来的SQL语句,将DML SQL语句分别发送到各个数据库节点上依次执行,图2形象地描述了全局表的DML操作过程。若对全局表频繁地进行增删改操作,由于MyCat的弱XA机制,很容易发生各节点数据不一致的情况。
图2 原始MyCat全局表的DML操作过程
MyCat中的表广播机制是针对全局表的,为全局表新增了一个属性,当该属性值为true时,改变原始SQL语句的执行逻辑。MyCat接收到DML命令,向主节点发送广播,主节点执行命令并保存二进制消息文件,同时向从节点推送消息,从节点接收到广播,同步主节点的数据。实现了表广播机制的MyCat即使在修改数据时出现节点异常的情况,待异常解除后,会主动读取存放消息的日志文件、同步数据,保证了强一致性。
图3形象展示了DML操作在表广播机制下的执行过程,即当MyCat接收到插入类型的SQL语句时,只向主节点发送相应的SQL语句,再通过日志文件,同步到其他节点。
图3 表广播机制下的DML操作过程
2 表广播机制在MyCat中的实现
2.1 配置文件的修改
MyCat启动时,首先读取配置文件,根据其中table标签的设置信息,判断各张表的类型。在配置文件schema.xml的table标签中增加一个属性“writeOneNode”作为启用表广播机制的标志,当逻辑表的类型是全局表即“type=globle”时,才启用表广播功能机制。
新增的属性为布尔类型,默认值为“false”。“writeOneNode=true”时,过滤DML操作的SQL语句,通过表广播作用于主节点;当“writeOneNode=false”时,DML操作的SQL语句按照原始逻辑作用于所有节点。
2.2 配置文件的初始化
通过Java应用程序访问XML时,要先把Java对象转化成XML文件(称作marshall),再将XML文件中的内容转化成相应的Java对象(称作unmarshal),该对象需要用JAXB(Java architecture for XML binding,XML绑定的Java体系结构)注解来标注[17]。因此需要修改注解类Schemas.java,在其内部类中添加“writeOneNode”的属性设置,使配置文件“schema.xml”中的内容unmarshal成Table类型的对象时,包含“writeOneNode”字段的相应信息。
初始化XML配置文件类XmlToYaml.java中,增加对参数“writeOneNode”的初始化功能,在启动程序时加载配置文件,通过解析XML配置文件,对配置文件中设置的相关参数进行初始化,在Schemas的各个内部静态类中实例化本类对象,最后再通过HashMap存储好所需要配置的Key-value键值对,对外提供本类实例化对象。
2.3 MyCat中表广播机制的执行流程
MyCat中的表广播机制是针对于全局表的DML操作而提出的,且只有在writeOneNode=true时其功能才会奏效,因此需要增加新的SQL执行逻辑。如图4所示,MyCat对接收到的sql语句进行以下判断:
图4 MyCat中的表广播机制执行流程
(1)sql语句的类型是否为insert或update或delete;
(2)待插入的表是否为全局表;
(3)是否写入单节点,即writeOneNode=true。
只有三个条件同时满足,才能将原始的多节点插入功能修改为单节点插入,启用表广播功能。
3 实验与分析
为了分析表广播机制在MyCat中的实现方案的可行性,在真实环境下进行实验分析。
3.1 实验设置
实验环境:三台配置完全相同的服务器。配置如下:操作系统为RedHat7.2;1*6 Core的CPU;内存16 G;硬盘16*1 T;千兆网卡。
步骤1:新建数据库和数据表。
实验中的全局表“teacher”具有4个分片,分别位于4个不同的数据库中,数据库名称分别为MyCat1,MyCat2,MyCat3,MyCat4,所属服务器ip为172.172.0.104,并在各个数据库中分别新建表“teacher”(含有字段:tid,name,sex,class;tid为关键字);在另外一台ip为172.172.0.106的服务器上也新建4个数据库:broadcastMyCat1、broadcastMyCat2、broadcastMyCat3、broadcastMyCat4,每个数据库中也分别包含同样表结构的“teacher”表,并配置broadcastMyCat1为broadcastMyCat2、broadcastMyCat3、broadcastMyCat4的主数据库,broadcastMyCat2、broadcastMyCat3、broadcastMyCat4为broadcastMyCat1的从数据库,启用表广播功能。
步骤2:安装MyCat。
在ip为172.172.0.107的服务器上分别安装官方MyCat(端口号为8068,命名为MyCat_8068)和实现表广播机制的MyCat(端口号为8069,命名为broadcastMyCat_8069),进行正确的配置文件设置,两者的区别如下:
MyCat_8068的schema.xml部分配置如下:
broadcastMyCat_8069中的schema.xml配置如下:
完成配置文件的设置后,分别启动MyCat_8068和broadcastMyCat_8069。
3.2 实验结果分析
实验1:为验证MyCat中的表广播机制,实现了原始MyCat中全局表功能,通过程序分别向MyCat_8068和broadcastMyCat_8069中的teacher表中连续作插入操作。一段时间后,分别到本地的各个数据库中查询teacher表中的数据,对各个表中的记录总数和数据内容进行对比,结果如表1所示。
表1 正常插入时的数据对比表
由表1可知,各个表中的记录数量几乎相同,同一个MyCat下各个节点中的数据均一致。结果表明,在各个数据节点运行正常的情况下,原始的MyCat和实现表广播机制的MyCat均可以做到数据的高效插入,且保证了各个节点间的数据一致性。
实验2:为验证在DML操作过程中出现节点异常后实现表广播机制的MyCat仍旧能保证各节点间的数据一致性,清空各个数据表中的数据后,通过程序分别向MyCat_8068和MyCat_8069中的teacher表中连续作插入操作,在插入过程中,关闭MyCat2和broadcastMyCat2两台数据库,一段时间后恢复两台数据库,多次尝试此操作,并对比各个MySQL数据库中的数据状况。
表2记录了各个节点异常消除后的数据情况,原始MyCat下的异常节点中的数据明显少于其他节点中的数据,而实现表广播机制的MyCat下的四个数据节点中的数据始终一致。
表2 异常解除后的数据对比表
由实验2结果可以看出,MyCat的弱XA机制,确实导致了节点间的数据不一致,而实现了表广播机制的MyCat,在异常节点恢复正常后,成功同步数据,保证与主节点的数据同步。
以上实验表明,实现表广播机制的MyCat的可靠性较高,在保证数据高效插入的同时,也保证了数据一致性。
4 结束语
提出了一种表广播机制在MyCat中的实现方案,通过对MyCat提供的操作全局表的相关功能进行优化,把对多个节点的操作修改为对单个节点的操作,有效解决了MyCat面临的弱XA问题。实验结果表明,该方案在实现全局表原有功能的同时,有效提高了全局数据表中各节点数据的一致性。
目前,对于分库表的查询操作,MyCat只会返回各分库合并后的数据,在排序、分页等功能上做得还不够完善,因此,未来计划运用其他的方法解决这类问题。
[1] 庄天红.常用数据库系统性能解析[J].微型电脑应用,1999,15(2):52-54.
[2] BOYD D, CRAWFORD K. Critical questions for big data[J].Information Communication & Society,2012,15(5):662-679.
[3] 项 凯.面向海量高并发数据库中间件的研究与应用[D].上海:上海交通大学,2015.
[4] 邱 硕.Cobar的架构与实践[J].程序员,2012(9):90-93.
[5] 祝雄锋.数据库集群中间件MySQL Proxy研究与分析[D].武汉:武汉理工大学,2011.
[6] 王 葱.基于MyCAT的分布式数据存储研究与应用[D].上海:东华大学,2016.
[7] HAYES B.Cloud computing[J].Communications of the ACM,2008,51(7):9-11.
[8] 安延文.数据库审计系统中MySQL协议的研究与解析[D].北京:华北电力大学,2016.
[9] 杨 晶,刘天时,马 刚.分布式数据库数据分片与分配[J].现代电子技术,2006,29(18):119-121.
[10] 赵 艳,李 钧.异构数据源分布式事务处理研究[J].计算机工程,2009,35(4):69-71.
[11] 胡百敬,陈俊宇,杨先民,等.SQL Server 2005 T-SQL数据库设计[M].北京:电子工业出版社,2008.
[12] 黄雅萍,刘晓强,吴成义.基于MySQL和PHP的分布式事务处理[J].东华大学学报:自然科学版,2011,37(1):81-85.
[13] 张旭刚,李东辉,俞 俊,等.基于zookeeper和强一致性复制实现MySQL分布式数据库集群[J].微型电脑应用,2016,32(1):77-80.
[14] 徐 恪,刘亚霄,刘卫东.数据库应用系统中的安全访问代理的设计与实现[J].计算机工程与应用,2000,36(1):105-107.
[15] 李曙强,蒋树春,吕 兵.一种基于mysql数据库的sql信息采集审计系统:CN,CN103488797A[P].2013-10-14.
[16] 黄春华.常用数据库的比较[J].科技信息,2011(14):200.
[17] 李占波,李 娜.XML数据在关系数据库中的存储[J].微计算机信息,2007,23(27):192-194.