1.mycat介绍
Mycat是一个数据库中间件。它可以将数据按照水平或者垂直进行切分,然后通过mycat连接底层数据库,用户进行数据的读写访问的时候直接访问的是中间件mycat,然后mycat再去访问物理库。
2.mycat的主要配置文件
使用mycat进行分库分表是通过修改mycat/conf文件夹下的三个配置文件来进行操作的这三个配置文件是:server.xml、schema.xml、rule.xml。下面分别介绍三个配置文件的作用。
server.xml:此配置文件是用来定义mycat逻辑库的连接信息的,主要配置如下图:
其中分为连接用户,和只读权限的测试用户,user的name和password属性可以自己定义,schema属性根据实际定义的逻辑库进行填写。
schema.xml:这可以说是mycat 的核心配置文件,数据的分库分表都是在这个配置文件中完成的,主要配置如下图:
上图为此次垂直分库的配置图,schema标签为逻辑库标签,用户访问mycat时看到就是schema标签配置的逻辑库。它里面的table标签是逻辑库中的表,name属性为表名,dataNode是数据节点,数据节点中的dn1、dn2表示此表中的内容会被切分到这两个数据节点所表示的物理库中。rule标签表示此表所采用的分片的规则,此次采用的是枚举分片规则。
dataNode标签是连接逻辑库和物理库的桥梁,name属性为数据节点的名称,dataHost表示物理主机,database表示物理机上的物理数据库。
dataHost标签用来配置mycat所连接的物理数据库,maxCon表示最大接受的访问连接,minCon表示最少接受的访问连接。Balance和writeType属性用来控制数据的分发规则。上图所示balance=“0”表示所有读操作都发到当前可用的writehost上,balance和writeType的具体其他数值所表示的含义如下:
balance=“1”,所有读操作都随机的发送到readHost。
balance=“2”,所有读操作都随机的在writeHost、readhost上分发。
writeType=“0”, 所有写操作都发送到可用的writeHost上。
writeType=“1”,所有写操作都随机的发送到readHost。
writeType=“2”,所有写操作都随机的在writeHost、readhost分上发。
WriteHost标签中的各种配置按照自己本地真实的物理数据库的连接信息进行配置即可。
rule.xml:此配置文件中都是mycat进行水平切分所使用的的分片规则,mycat的分片规则有分片枚举、固定分片hash算法、范围约定、取模、按日期(天)分片、取模范围约束、截取数字做hash求模范围约束、应用指定、截取数字hash解析、一致性hash、按单月小时拆分、范围求模分片、日期范围hash分片、冷热数据分片、自然月分片。
3.分库分表的方式
Mycat数据切分分为垂直切分和水平切分,其中垂直切分是根据数据的业务逻辑进行的切分,它将具有相同业务逻辑的表分到一个数据库。例如订单表,用户表,用户评论表,因为他们业务的不同,可以将使用垂直切分将他们分别放到三个数据库中。这样可以使我们的数据结构清晰,还能解决单机性能的瓶颈。
水平切分是根据表的某一个字段按照特定的分片规则进行切分。
4.水平切分的分片规则
1.分片枚举:
通过在配置文件中配置可能的枚举id,自己配置分片,此规则使用与特定的场景下,例如某些业务需要按照省份或区县等来做保存,或者按照某些固定不变的分类来进行保存都可以使用此规则。具体配置如下图所示:
其中columns表示分片表字段,algorithm表示分片函数。此函数就是function标签中所定义的内容。我们所要关注的属性如下:
Name=”mapfile”中所定义的是此函数所使用的配置文件,type默认值为0,0表示配置文件中的配置信息为Integer类型,如果配置成非0则表示String类型,所有的节点配置都是从0开始,即0表示节点1。DefaultNode表示默认节点。属性值小于0表示不设置默认节点,大于等于0表示设置默认节点。如果不配置默认节点当碰到不识别的枚举值就会报错。报错形式如下:can’t find datanode for shardingcolumn:column_name val:XXXXX
2.固定分片hash算法
此规则本质为二进制的求模运算,它只取二进制数的低十位进行相关运算。此种算法的好处是根据二进制进行运算可能分到连续的分片,可以减少事务控制难度主要配置如下图:
PartitionCount中的参数表示分片的份数,partitionLength表示没份分片的大小
其中份数和大小的积要恒等于1024,例如上图的配置将1024分成三份 前两份为256第三份为512 则256*2+512*1=1024符合规则,这样分配其实就是讲所有数据分成三份,前两份各占总数据的25%,最后一份占总数据的50%,因为此次分片为非均匀分片。
3.范围约定
此分片适用于提前规划好分片字段的某个范围属于哪个分片,
配置如下:
此配置只需提前在配置文件autopartion-long.txt中预先制定可能的id范围划分到某个分片就行。其余参数意义同上。
4.取模
此方法类似固定分片hash,所不同的是此算法采用十进制取模运算,此算法在进行连续插入如1-10时候回被分到1-10个分片,增大了事务控制难度。
配置如下:
5.按日期(天)分片
此算法为按天进行分片。其中dateFormat 为日期格式,sBeginDate 为开始日期,sEndDate为结束日期,sPartionDay 为分区天数,即默认从开始日期算起,分隔10天一个分区。如果配置了 sEndDate 则代表数据达到了这个日期的分片后后循环从开始分片插入。
6.取模范围约束
此种规则是将上面的取模运算和范围约束规则结合到一起。
配置如下:
其中patternValue表示mod的值即id%256,此规则和取模规则不同的是他还提供了配置文件,配置文件中可以自定义取模后数据分到哪个区。
7.截取数字做hash求模范围约束
此种规则类似于上面的取模范围约束,此规则支持数据符号字母取模。配置如下:
其中perfixLength是取数据的前几位进行取模,如图配置表示去user_id的前5位的ascll值的和然后%256进行运算。
8.应用指定
此规则实在运行阶段由应用自主决定路由到哪个分片。配置如下:
此方法为直接根据字符子串(必须是数字)计算分区号(由应用传递参数,显式指定分区号)例如 user_id=”0112-55220”在此配置中代表根据user_id中从startIndex=0,开始,截取user_id字符串的前size=2位数字即01,则01就是获取的分区,如果没传值则默认分配到dafaultPartition
9.截取数字hash解析
此规则是截取字符串中的int数值进行hash分片。配置如下:
10.一致性hash
一致性hash预算有效解决了分布式数据的扩容问题。
配置如下:
11.按单月小时拆分
此规则是单月内按照小时拆分,最小粒度是小时,可以一天最多24个分片,最少1个分片,一个月完后下月从头开始循环。 每个月月尾,需要手工清理数据。配置如下:
12.范围求模分片
先进行范围分片计算出分片组,组内再求模
配置如下:
13.日期范围hash分片
思想与范围求模一致,当由于日期在取模会有数据集中问题,所以改成hash方法。先根据日期分组,再根据时间hash使得短期内数据分布的更均匀。
配置如下:
其中sPartionDay代表多少天分一个分片,groupPartionSize代表分片组的大小。
14..冷热数据分片
根据日志查询日志数据,冷热数据分布,最近n个月的到实时交易库中查询,超过n个月的按照m天分片。配置如下:
15.自然月分片
按月份来分区,每个自然月一个分片。配置如下:
5测试环境搭建
从官网上下载mycathttp://www.mycat.org.cn/然后将其解压到某一个目录。安装虚拟机,在虚拟机上安装centOs系统。在linux,windows上分别创建一个mysql数据库实例在Windows上安装jdk,然后在windows上装mycat,通过mycat连接linux和windowds上的mysql数据库。
6.搭建垂直分库
垂直分库配置文件如下:
schema.xml
server.xml
步骤:使用navicat连接上两个mysql实例,然后分别创建相应的物理数据库。然后到mycat的bin目录下启动startup_nowrap。接着通过navicat按照server.xml上的配置连接mycat数据库。在测试的数据库中先创建测试表,然后在打开物理库发现已经自动创建了刚才在mycat中创建的表。这时候就可以进行通过操作mycat操作物理数据库了。
7.搭建水平分库
相关配置文件如下:
schema.xml
server.xml
操作步骤参见搭建垂直分库。
8.注意事项
部分日志数据:
INSERTINTO `rs_resources_statistics_sourcetype_use_hourly` VALUES ('yanguanjun', '2','perio', 'WF', 'DB_CSPD', '酿酒科技', '2017-11-16', '14', '2', '', '10000');
INSERTINTO `rs_resources_statistics_sourcetype_use_hourly` VALUES ('Admin.admin','3',
上面所示日志信息在插入数据时没有写列明 这样就会出错 因为mycat在进行分片的时候要根据列明进行分片分表所以日志数据不能跑
截图如下:
出错信息如下:
而且navicat中的数据只能导出不带列名的insert语句,这样就无法用日志数据测试水平切分 准备构造类似结构的数据重新进行测试)
水平切分用java进行查询数据库和平常查询数据库一样,需要注意的是mycat的默认端口是8066而不是3306,如果是本地连接mycat不能使用localhost一定要使用127.0.0.1。
9.测试数据
1.insert测试数据
Mycat 垂直insert日志数据224w 时间:1415s=23m35s 100w数据:11m23s
Mycat 水平insert自己构造的日志数据224w 时间:1465s=24m24s 100w数据12m左右
不使用mycatinsert自己构造的日志数据224w 时间:1065s=17m45s 100w数据8m53s
相比较不使用mycat减少了6-7分钟
Mangodbinsert 100w数据177s=2m57s
总结:Mangodb相比较mycat速率提升了4倍左右mangodb相比较mysql(关系型数据库)速录提升了3倍
2.select测试数据
测试用普通数据库的查询操作和用mycat的查询比较
mycat水平切分查询1w数据(数据总量1120100*2):2867s=47m47s
mycat 垂直切分查询1w数据单库(数据总量1120100*2):2023s=33m43s(相当于只查了一个库也就是100w数据的库)
mycat 垂直切分查询1w数据多库(数据总量1120100*2)2713s=45m13s
普通数据库查询1w数据(数据总量1120100*2):48m左右
普通数据库查询1w数据(数据总量110w):1493s=24m53s
Mangodb查询1w数据(数据总量100w):558毫秒
10.各种方式优缺点
1.关系型数据库优点
结构化存储,完整性约束
可以进行join等复杂查询
有事务处理能够保持数据的一致性
通用化,技术成熟
缺点:
高并发环境下读写性能不足
对数据读写需要加锁,影响并发操作
无法使用非结构化存储
扩展困难
2.nosql数据库优点
高并发,大数据写读写能力强
易于扩展
简单、弱结构化存储
缺点:
无完整性约束
事务支持较弱
Join等复杂操作能力较弱
通用性差
Nosql虽然速度快但是还是不能替代关系型数据库,它只能作为一个辅助型数据库,mycat的出现使数据易于切分,易于扩展,可以将数据切分到不同的主机,这样避免了单机单库的性能缺陷。Mycat的优点在于可以解决单机性能瓶颈,而不是在于纯粹的速率比较
3.mycat垂直切分的优点
由于垂直切分是按照业务逻辑进行的切分所以
拆分后业务清晰,拆分规则明确。
系统之间整合或者扩展容易
数据维护简单
缺点:
部分业务无法join,只能通过接口方式解决,提高了系统的复杂度。
受每种业务不同的限制存在单库性能瓶颈,不易数据扩展跟性能提高
事务处理复杂
由于垂直切分是按照业务的分类将表分散到不同的库,所以有些业务表会过于庞大,存在单库读写与存储瓶颈,所以就需要水平拆分来做解决
4.mycat水平分库的优点
不存在单库大数据,能避免高并发的性能瓶颈
提高了性能的稳定性跟负载能力
缺点:
分片事物一致性难以解决
数据多次扩展难度跟维护量极大
夸库join性能较差
5.mycat垂直分库和水平分库的共同缺点
引入分布式事务的问题
跨节点join的问题
跨节点合并排序分页问题
多数据源管理问题
参考资料:mycat官方文档:http://www.mycat.io/document/Mycat_V1.6.0.pdf