如今随着互联网的发展数据的量级也是成指数增长,从GB到TB再到PB,对数据的各种操作也是愈发的困难,传统的关系型数据库已经无法满足快速查询域插入数据的需求,这个时候NoSQL的出现暂时缓解了这一危机,它通过降低数据的安全性,减少对事务的支持,减少对复杂查询的支持,来获取性能上的提升。
但是,在有些场合,NoSQL一些折中是无法满足使用场景的,就比如有些场景是绝对要有事务与安全指标的,这个时候,NoSQL肯定无法满足,所以还是需要使用关系型数据库。那么如何解决关系型数据库处理海量存储问题了?此时就需要对数据库做个集群,为了提高查询性能,将一个数据库分散到不同的数据库中存储。
MyCat背后是阿里曾经开源的知名产品——Cobar。Cobar的核心功能和优势是MySQL数据库分片,此产品曾经广为流传,据说是最早发起者对MySQL很精通,后来从阿里跳槽了,阿里随后开源的Cobar,并维持到2013年初,就没有然后了。
Cobar的思路和实现路径的确不错,基于java开发的,实现了MySQL公开的二进制传输协议,巧妙的将自己伪装成一个MySQLServer,目前市面上绝大多数MySQL客户端工具和应用都能兼容,比自己实现一个新的数据库协议要明智的多。
MyCat是基于Cobar演变而来的,对Cobar的代码进行了彻底的重构,使用NIO重构了网络模块,并且优化了Buffer内核,增强了聚合,join等基本特性,同时兼容绝大多数数据库成为通用的数据库中间件。
简单的说MyCat就是:一个新颖的数据库中间件产品支持MySQL集群,或者mariadb clusor,提供高可用性数据库分片集群,你可以像使用MySQL一样使用MyCat,对于开发人员来说,根本感觉不到MyCat的存在。
官网地址:http://www.mycat.org.cn/
软件包地址:
安装步骤:
1)将MyCat上传到服务器
2)解压:tar -zxvf Mycat.tar.gz -C /usr/soft/mycat
3)进入MyCat的bin目录,启动MyCat
./mycat.start
注意:
1. 停止MyCat命令:./mycat stop
2. mycat支持的命令 console | start | stop | restart | status | dump
3. mycat默认端口号:8066
简单来说,就是指通过某种特定条件,将我们存放在同一个数据库中的数据分散存储在不同的数据库(主机)上,以达到分散单台设备负载的效果。
数据的切分(sharding)根据其切分规则的类型,可以分为两种切分模式
1)按照不同的表(或者schema)来切分到不同的数据库(主机)之上,这种切分可以称之为数据库垂直(纵向)切分,这种切分一般是根据业务需求来切分,比方说切分成用户系统数据库,订单交易系统数据库,支付系统数据库等。
2)根据表中数据逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上,这种切分称之为水平(横向)切分。
通常对实际应用来说,并不需要知道中间件的存在,业务开发人员只需要知道数据库的概念,所以数据库中间件可以被看做是一个或多个数据库集群构成的逻辑库,如上图中的schema
既然有逻辑库,那么就会存在逻辑表,分布式数据库中,对应用来说。读写数据的表就是逻辑表,逻辑表可以是数据切片后,分布在一个或多个分片库中,也可以不做数据切分,不分片,只有一个表结构,如上图中的Table A 与 Table B都是逻辑表
1)分片表:指那些原有的很大数据的表,需要切分到多个数据库的表,这样,每个分片都有一部分数据,所有分片构成了完整的数据,总而言之就是需要进行分片的表。
2)非分片表:一个数据库中并不是所有的表都很大,某些表是可以不用进行切分的,非分片是相对分片表来说的,就是那些不需要进行数据切分的表。
数据切分后,一个大表被分到不同的分片数据库上面,每个表分片所在的数据库就是分片节点(datanode),如上图中的每个datanode都是一个分片节点。
数据切分后,每个分片节点(datanode)不一定都会独占一台机器,同一机器上可以有多个分片数据库,这样一个多个分片节点所在的机器就是节点主机(dataHost),为了规避单节点主机并发数限制,尽量将读写压力高的分片节点均衡的放在不同的节点主机,如上图中的DataBase a b c d e
一个大表被分成了若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将极大的避免手续数据处理的难度。
schema.xml作为MyCat中重要的配置文件之一,管理着MyCat的逻辑库、逻辑表以及对应的分片规则、dataNode以及DataSource、弄懂这些配置,是正确使用MyCat的前提。这里就一层层的对该文件进行解析。
以下是简单的schema.xml配置文件
select user()
schema标签用于定义MyCat实例中的逻辑库
1)name:逻辑库库名称,程序连接数据库的时候,就是连接的它
Table标签定义了MyCat中的逻辑表
1)rule用于指定分片规则
2)auto-sharding-long的分片规则是按照ID值的范围进行分片1-5000000为第一片,5000001-10000000为第二片。。。
3)dataNode:数据节点,多个数据节点用逗号分隔,表示这个表来自这几个节点
dataNode标签定义了MyCat中的数据节点,也就是我们通常说的数据分片。
1)name:数据节点的名称,与table标签中的dataNode属性值对应
2)dataHost:数据节点所在主机IP
3)database:物理数据库库名,其属性值为数据库的名称
dataHost标签在MyCat逻辑库中也是作为最底层的标签存在,直接定义了具体的数据库实例、读写分离配置和心跳语句。
1)name:dataHost名称,与dataNode标签的dataHost属性值对应
2)子标签heartbeat:select user() 心跳语句,用来检查节点是否能正常连接的。
3)子标签writeHost:host=hostM1表示主节点,hostS1表示从节点
在服务器上创建3个数据库,分别是db1 db2 db3,那么修改schema.xml如下:
注意:真实开发中这三个数据库分布在不同的主机上。如果位于不同的主机,那么在schema.xml中dataHost标签配置多份与主机一一对应即可。
server.xml几乎保存了所有MyCat需要的系统配置信息,最常用的是在此配置用户名、密码以及权限。在System中添加utf8字符集设置,否则存储中文会出现乱码。
utf8
修改user配置,一个user节点表示一个用户,例如:
root
TESTDB
false
1)user标签的属性name表示用户名
2)property标签配置两个,一个是密码一个是schema逻辑库库名称(注意:这里的名称必须要在schema.xml中配置过的)
3)readOnly表示只读,属性值为false,相当于没有配置这句话
改完配置之后,重启MyCat:./mycat restart
如图:
注意:mycat的默认端口是8066
在mycat创建表tb_test
CREATE TABLE tb_test(
id BIGINT(20) NOT NULL,
title VARCHAR(100) NOT NULL,
PRIMARY KEY(id)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
再看我们的三个数据库,发现同步创建了三张表,如图;
在mycat中执行插入语句
INSERT INTO tb_test(id,title) VALUES(1,'goods1'),(2,'goods2'),(3,'goods3'),(4,'goods4');
注意:在mycat中不能缺省列明,必须指定列明。
再查看数据库,发现db1成功插入了数据,如图:
而,另外两个数据库,没有插入数据
注意:
在mycat中通过工具打开表查询的时候,会报如下错误
是因为mycat在执行SQL的时候,必须指定列明,也就是不能用*
前面介绍了,当id值为5000000的时候会进行分片,所以,这次我们插入id值为5000001的数据
如图:
在mycat中的数据:
然后查看数据库,如图;
db1依然是之前的4条数据
再看db2,如图:
发现db2是新插入的数据。
然后,我们再试试插入id=15000001,发现mycat报错了,如图;
总结:通过15000001报错信息,可以知道,mycat根据id分片有一个取值范围,该范围与数据库节点数有关,超过这个范围就会报错,所以,我们在开发中都会根据实际需要设置分片规则
rule.xm用于定义分片规则,介绍两种最常见的分片规则
如图:
1)tableRule:定义具体某个表或某一类表的分片规则名称
2)columns:用于定义分片的列,即指定根据哪个字段进行分片
3)algorithm:用于指定规则算法。其属性值对应下面function标签的name属性值,具体规则逻辑在function标签的class类中定义的,function下有一个子标签property,用于我们修改默认的配置
上面的例子中,当id=1500000的时候,会报错,可以在autopartition-long.txt中修改范围值,例如:
当我们需要将数据平均分在几个分区中,需要使用一致性hash规则,我们找到function的name为murmur的定义,将count属性改为3,因为我们要将数据分成3片。
0
3
160
如图:
注意:如果两个表分的片不一样的话,可以将整个function复制一份,重新定义name的名称,将count改成需要分成的片的数量即可
配置一个表并指定算法的步骤:
1)在rule.xml配置文件中指定我们需要的规则,如图:
我需要一致性哈希算法,所以我可以直接将算法algorithm=murmur的tableRule复制一份,并指定分片字段,例如:order_id
2)如果要修改分片数量,那么就根据murmur找到对应的function,修改function的name和count,如图:
3)在schema.xml配置文件中的schema标签添加需要配置的表配置,如图:
name是标明,rule就是我们刚才指定的规则名称
数据库读写分离对于大型的系统或者访问量很高的互联网应用来说,是必不可少的一个重要功能,对于mysql来说,标准的读写分离是主从模式,一个写节点Master后面跟着多个读节点,读节点的数量取决于系统的压力,通常1-3个读节点的配置。
mycat的读写分离和自动切换机制,需要mysql的主从复制机制配合。