将原本存放与一台数据库服务器里的数据,按照特定的方式进行拆分,分散存放到多台数据库中,以达到减轻单台数据库服务器压力,实现数据库负载均衡的效果
1.水平分割
将每条记录按分片规则(图中是通过求余数的方式)分散到多个数据库中,要求每台数据库服务器中拥有相同的数据库和数据表
2.垂直分割
将单个数据库中的多个表按业务类型分类,分散存储到不同的表中,假设有4台数据库服务器,那可以按照客户,存款,贷款,支付创建四张表,安装表来识别数据库服务器,从而实现分散存储的效果
不管是水平分割还是垂直分割,都需要有一个中间件来处理请求,将客户端的请求分发给不同的数据库,Mycat就是作为中间件的软件.
Mycat是基于java的分布式数据库系统中间件,为高并发环境的分布式存储提高解决方案
概述
-适合数据大量写入的存储需求
-支持Oracal,Sql Server,Mysql,Mongdb
-提供数据读写分离服务
-提供数据分片服务
-基于阿里巴巴Cobar进行研发的开源软件,是阿里巴巴用于处理数据分片的核心软件
Mycat支持的分片规则
mycat支持10种分片规则
Mycat的工作过程
1.解析Sql命令涉及到的表
2.查看mycat配置文件中对表的配置,查看分片规则,如果有对应的表和分片规则,则获取Sql命令里分片字段的值(由你自己设置,一般是id值),并匹配分片函数,对照分片列表,选择一台服务器
3.将sql命令发往对应的数据库服务器去执行
4.收集和处理由数据库返回的结果数据,返回给客户端
5.Mycat
1.拓扑图
准备五台服务器,分片服务器1台,3台数据库服务器,1台客户端
ip配置拓扑
2.部署分片服务器,安装mycat软件
需要安装jdk,前面说了mycat是基于java的,所以需要java环境
[mycat下载地址]http://www.mycat.io/
1)准备java环境
]# yum -y install java-1.8.0-openjdk //安装JDK
[root@mycat56 ~]# which java //查看命令
/usr/bin/java
[root@mycat56 ~]# java –version //显示版本
openjdk version "1.8.0_161"
OpenJDK Runtime Environment (build 1.8.0_161-b14)
OpenJDK 64-Bit Server VM (build 25.161-b14, mixed mode)
2)安装提供服务的软件包
[root@mycat56 ~]# tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz //解压源码
[root@mycat56 ~]# mv mycat /usr/local/ //移动目录
[root@mycat56 ~]# ls /usr/local/mycat/ //查看文件列表
bin catlet conf lib logs version.txt
2.5)mycat目录结构和配置文件信息
我们一般用到的是bin和conf,用于启动mycat和修改配置文件
我们在本次实验中要修改的文件是server.xml和schema.xml,下一节会使用rule.xml
3)设置连接账号
连接账号是用来访问mycat服务的,逻辑库是对外展示的库,并非真实用于存储数据的库,逻辑库位于mycat代理服务器上,真实库位于数据库服务器上
- ]# vim /usr/local/mycat/conf/server.xml
//连接mycat服务时使用的用户名 123456 //用户连接mycat用户时使用的密码TESTDB //逻辑库名user TESTDB true //只读权限,连接mycat服务后只有读记录的权限,不写这一行则是可读可写- :wq
4)配置数据分片
修改配置文件,这个配置文件中有比较多的注释文件,我这里不写出来,大家在修改文件之前应该要做一个备份,防止修改出错后能还原环境,整个文件格式如下,我们需要定义三个标签,一个是定义分片的库与表,然后定义数据节点,再定义数据库服务器的连接信息,包括数据库ip,登录账户密码.
定义分片的库表,
定义数据库节点,数据库节点连接数据库中的真实库,定义三个选项,name是dataNode的别称,dataHost是数据库服务器的别称,database是数据库服务器中的真实库
定义数据库服务器的信息,这里我们需要定义3个数据库服务器,包括ip地址,连接用户名与密码
如果复制的话记得把注释删了,这是源配置文件我加入了一些注释
- [root@mycat56 conf]# vim /usr/local/mycat/conf/schema.xml
- //对TESTDB库下的表做分片存储
- //对travelrecord表做分片存储
- //对company表做分片存储
- //对goods表做分片存储
- //对hotnews表做分片存储
- //对employee表做分片存储
- //对customer表做分片存储,这张表较为特殊,有子表
- //定义数据库主机名及存储数据的库
- //定义localhost53主机名对应的数据库服务器ip地址
select user() - //定义localhost54主机名对应的数据库服务器ip地址
select user() - //定义localhost54主机名对应的数据库服务器ip地址
select user()
5)配置数据库服务器
根据分片文件的设置在对应的数据库服务器上创建存储数据的数据库,要求每台主机安装mariadb服务
yum -y install mariadb
输入命令进入mariadb: mysql -uroot
- mysql> create database db1; //在数据库53上,创建db1库
- mysql> create database db2; //在数据库54上,创建db2库
- mysql> create database db3; //在数据库55上,创建db3库
根据分片文件配置,在对应的数据库服务器上创建授权用户(3台数据库服务器都要添加,在数据库服务器本机管理员root用户登录后执行授权命令)
- mysql> grant all on *.* to adminplj@"%" identified by "123qqq...A" ; //在数据库服务器192.168.4.53 执行
- mysql> grant all on *.* to adminplj@"%" identified by "123qqq...A" ; //在数据库服务器192.168.4.54 执行
- mysql> grant all on *.* to adminplj@"%" identified by "123qqq...A" ; //在数据库服务器192.168.4.55 执行
6)测试数据库服务器是否能够连通
测试授权用户:在192.168.4.56主机,使用授权用户分别连接3台数据库服务器,若连接失败,请检查数据库服务器是否有对应的授权用户。确认三台数据库服务器可以使用
- [root@mycat56 ~]# which mysql || yum -y install mariadb //安装提供mysql命令的软件包
- //连接数据库服务器192.168.4.53
- [root@mycat56 ~]# mysql -h192.168.4.53 -uadminplj -p123qqq...A
- mysql: [Warning] Using a password on the command line interface can be insecure.
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 54
- Server version: 5.7.17 MySQL Community Server (GPL)
- mysql> exit; //连接成功 断开连接
- Bye
- //连接数据库服务器192.168.4.54
- [root@mycat56 ~]# mysql -h192.168.4.54 -uadminplj -p123qqq...A
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 47
- Server version: 5.7.17 MySQL Community Server (GPL)
- mysql> exit; //连接成功 断开连接
- Bye
- //连接数据库服务器192.168.4.55
- [root@mycat56 ~]# mysql -h192.168.4.55 -uadminplj -p123qqq...A
- mysql: [Warning] Using a password on the command line interface can be insecure.
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 49
- Server version: 5.7.17 MySQL Community Server (GPL)
- mysql> exit ; //连接成功 断开连接
7)启动服务mycat分片服务器
- [root@mycat56 ~]/usr/local/mycat/bin/mycat --help //查看一下可以用的命令
- Usage /usr/local/mycat/bin/mycat {console | start | stop | restart | status | dump}
- [root@mycat56 ~]# /usr/local/mycat/bin/mycat start
- Starting Mycat-server...
查看服务状态
- [root@mycat56 ~]# netstat -utnlp | grep :8066 //查看端口
- tcp6 0 0 :::8066 :::* LISTEN 2924/java
- [root@mycat56 ~]# ps -C java //查看进程
- PID TTY TIME CMD
- 2924 ? 00:00:01 java
8) 测试mycat分片
这里测试的目的是测试是否在配置文件中创建的数据库和表正确显示,下一小节再演示如何实现分片插入数据
在客户端192.168.4.50 连接分片服务器,访问数据
命令: mysql -hmycat主机的IP -P端口号 -u用户 -p密码
- [root@client50 ~]# mysql -h192.168.4.56 -P8066 -uroot –p123456
- mysql> show databases; //显示已有的库
- +----------+
- | DATABASE |
- +----------+
- | TESTDB |
- +----------+
- 1 row in set (0.00 sec)
- mysql> USE TESTDB; //进入TESTDB库
- mysql> show tables; //显示已有的表,配置文件里定义的表名
- +------------------+
- | Tables in TESTDB |
- +------------------+
- | company |
- | customer |
- | customer_addr |
- | employee |
- | goods |
- | hotnews |
- | orders |
- | order_items |
- | travelrecord |
- +------------------+
- 9 rows in set (0.00 sec)
- mysql>desc employee; //查看表信息会提示数据表不存在,这是因为在真实数据库中并没有创建这个表,下节演示如何创建真实表,和使用分片规则插入数据
- mysql>ERROR 1146(42S02):Table 'db1.employee' doesn't exist;
- mysql>exit; //断开连接
mycat有10中分片规则,这里讲解枚举法和求模法
枚举法 sharding-by-intfile
顾名思义,就是自己定义好枚举对象,根据指定的键值存储到对应的服务器(一般是id),以下是schema.xml的配置信息
以下是rule.xml和自己定义的*.txt枚举对象文件,两个文件需要在同一目录,这里的10000是什么意思呢?就是所谓的id,你在插入一条记录的时候,需要插入10000这一字段,用于指定插入的数据库服务器(为0,代表第一台) .这里服务器从0开始,代表第一台,依次向上加,我们可以看成是key-value的形式,也就是键值对形式,键的长度不固定,但是一般不会太大,一般你不会有太多的数据库服务器,5位即可
求模法 mod-long
枚举法的缺点就是你需要自己指定被插入的服务器,这样有很多缺点,一是需要人工指定,二是占用字段,浪费空间资源,三是后期修改较麻烦,当你添加服务器时还需要修改配置文件增加键值对
求模法要简单的多,也就是用余数来指定数据库服务器,一般用主键值作为被模数,改文件是schema.xml
指定服务器数量为3,也是余数,该文件是rule.xml
1.sharding-by-intfile分片规则的使用
1)查看配置文件,得知使用sharding-by-intfile分片规则的表名
[root@mycat56 ~]# vim /usr/local/mycat/conf/schema.xml
rule="sharding-by-intfile" />
:wq
2)查看规则文件,得知sharding-by-intfile分片规则使用的函数
- [root@mycat56 ~]# vim /usr/local/mycat/conf/rule.xml
sharding_id //数据分片字段名hash-int //使用的函数名- class="io.mycat.route.function.PartitionByFileMap">
partition-hash-int.txt //函数调用的配置文件- :wq
3)修改函数配置文件,添加dn3 数据节点
- [root@mycat56 ~]# vim /usr/local/mycat/conf/partition-hash-int.txt
- 10000=0 //当sharding_id字段的值是10000时,数据存储在数据节点dn1里
- 10010=1 //当sharding_id字段的值是10010时,数据存储在数据节点dn2里
- 10020=2 //当sharding_id字段的值是10020时,数据存储在数据节点dn3里
- :wq
4)重启mycat服务,使其修改有效
- [root@mycat56 ~]# /usr/local/mycat/bin/mycat stop //停止服务
- [root@mycat56 conf]# /usr/local/mycat/bin/mycat start //启动服务
- [root@mycat56 conf]# netstat -utnlp | grep :8066 //有端口
- tcp6 0 0 :::8066 :::* LISTEN 1364/java
- [root@mycat56 conf]#
- [root@mycat56 conf]# ps –C java //有进程
- PID TTY TIME CMD
- 1125 ? 00:00:01 java
- [root@mycat56 conf]#
5)客户端连接分片服务器,存取数据
有一点需要注意,就是数据库和表名不能随意创建,必须安装你配置文件中说明的去创建,因为我在schema.xml中配置了TESTDB这个库和employee这个表,所以下面我才可以创建它.简而言之就是你要创建什么表就必须先定义什么表
mycat的好处就是不需要你重复建表,只需要在mycat上创建表,数据库服务器就会同步创建这些表
- ]#mysql -h192.168.4.56 -P8066 -uroot -p123456 //访问服务
- mysql> use TESTDB; //进入TESTDB库 //建表,在分片服务器中键表会在数据库中同步建表
- mysql> create table employee(
- ID int primary key ,
- sharding_id int,
- -> name char(15) ,
- age int );
- Query OK, 0 rows affected (0.68 sec)
- mysql> desc employee; //查看表结构
- +-------------+----------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +-------------+----------+------+-----+---------+-------+
- | ID | int(11) | NO | PRI | NULL | |
- | sharding_id | int(11) | YES | | NULL | |
- | name | char(15) | YES | | NULL | |
- | age | int(11) | YES | | NULL | |
- +-------------+----------+------+-----+---------+-------+
- 4 rows in set (0.00 sec)
- //插入表记录,因为我这里使用枚举法,所以要指定枚举值sharding_id
- Mysql>insert into employee(ID,sharding_id,name,age) values
- (1,10000,"bob",19), //存储在53服务器的db1库的employee表里
- (2,10010,"tom",21), //存储在54服务器的db2库的employee表里
- (3,10020,"lucy2",16); //存储在55服务器的db3库的employee表里
- Query OK, 3 rows affected (0.07 sec)
- Records: 3 Duplicates: 0 Warnings: 0
- mysql> select * from employee; //查看表记录
- +----+-------------+------+------+
- | ID | sharding_id | name | age |
- +----+-------------+------+------+
- | 1 | 10000 | bob | 19 |
- | 2 | 10010 | tom | 21 |
- | 3 | 10020 | lucy | 16 |
- +----+-------------+------+------+
- 3 rows in set (0.06 sec)
- mysql>insert into employee(ID,sharding_id,name,age) values
- (4,10000,"bob2",19), //存储在53服务器的db1库的employee表里
- (5,10000,"tom2",21), //存储在53服务器的db1库的employee表里
- (6,10000,"lucy2",16); //存储在53服务器的db1库的employee表里
- Query OK, 3 rows affected (0.07 sec)
- Records: 3 Duplicates: 0 Warnings: 0
- mysql> select * from employee; //查看表记录
- | ID | sharding_id | name | age |
- +----+-------------+-------+------+
- | 1 | 10000 | bob | 19 |
- | 4 | 10000 | bob2 | 19 |
- | 5 | 10000 | tom2 | 21 |
- | 6 | 10000 | lucy2 | 16 |
- | 3 | 10020 | lucy | 16 |
- | 2 | 10010 | tom | 21 |
- +----+-------------+-------+------+
- 6 rows in set (0.00 sec)
6)在数据库服务器本机,查看表记录
在数据库服务器192.168.4.53 查看数据
- [root@host53 ~]# mysql -uroot -p123qqq...A -e "select * from db1.employee"
- mysql: [Warning] Using a password on the command line interface can be insecure.
- +----+-------------+-------+------+
- | ID | sharding_id | name | age |
- +----+-------------+-------+------+
- | 1 | 10000 | bob | 19 |
- | 4 | 10000 | bob2 | 19 |
- | 5 | 10000 | tom2 | 21 |
- | 6 | 10000 | lucy2 | 16 |
- +----+-------------+-------+------+
- [root@host53 ~]#
在数据库服务器192.168.4.54 查看数据
- [root@host54 ~]# mysql -uroot -p123qqq...A -e "select * from db2.employee"
- mysql: [Warning] Using a password on the command line interface can be insecure.
- +----+-------------+------+------+
- | ID | sharding_id | name | age |
- +----+-------------+------+------+
- | 2 | 10010 | tom | 21 |
- +----+-------------+------+------+
- [root@host54 ~]#
在数据库服务器192.168.4.55 查看数据
- [root@host55 ~]# mysql -uroot -p123qqq...A -e "select * from db3.employee"
- mysql: [Warning] Using a password on the command line interface can be insecure.
- +----+-------------+------+------+
- | ID | sharding_id | name | age |
- +----+-------------+------+------+
- | 3 | 10020 | lucy | 16 |
- +----+-------------+------+------+
- [root@host55 ~]#
2.mod-long分片规则的使用
1)查看配置文件,得知使用mod-long分片规则的表名
注意要删除 primaryKey="ID" autoIncrement="true" 不然无法存储数据,非自增长
[root@mycat56 ~]# vim /usr/local/mycat/conf/schema.xml
:wq
2)查看规则文件,得知 mod-long分片规则使用的函数
- [root@mycat56 ~]# vim /usr/local/mycat/conf/rule.xml
id //数据分片字段,与表中字段同名mod-long //函数名3 //指定求模数字- :wq
3)重启mycat服务,使其修改有效
- [root@mycat56 ~]# /usr/local/mycat/bin/mycat stop //停止服务
- [root@mycat56 conf]# /usr/local/mycat/bin/mycat start //启动服务
- [root@mycat56 conf]# netstat -utnlp | grep :8066 //有端口
- tcp6 0 0 :::8066 :::* LISTEN 1364/java
- [root@mycat56 conf]#
- [root@mycat56 conf]# ps –C java //有进程
- PID TTY TIME CMD
- 1125 ? 00:00:01 java
4)客户端连接分片服务器,存取数据
- ]#mysql -h192.168.4.56 -P8066 -uroot -p123456 //访问服务
- mysql> use TESTDB; //进入TESTDB库
- mysql> create table hotnews( //创建表时需要与rule.xml文件定义的求模值名一样
- id int ,title char(30),
- comment char(200));
- Query OK, 0 rows affected (0.79 sec)
- mysql> desc hotnews; //查看表结构
- +---------+-----------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +---------+-----------+------+-----+---------+-------+
- | id | int(11) | YES | | NULL | |
- | title | char(30) | YES | | NULL | |
- | comment | char(200) | YES | | NULL | |
- +---------+-----------+------+-----+---------+-------+
- 3 rows in set (0.00 sec)
- mysql> insert into hotnews(id,title,comment)values(9,"sc","xxxxx"); //插入第1条表记录,9和3取余 余0 记录存储在53服务器的db1库里
- Query OK, 1 row affected (0.11 sec)
- mysql> insert into hotnews(id,title,comment)values(10,"xx","haha");//插入第2条表记录,10和3取余 余1 记录存储在54服务器的db2库里
- Query OK, 1 row affected (0.05 sec)
- mysql> insert into hotnews(id,title,comment)values(11,"yy","zz");//插入第3条表记录,11和3取余 余2 记录存储在55服务器的db3库里
- Query OK, 1 row affected (0.03 sec)
- mysql> select * from hotnews; //查看表记录
- +------+-------+---------+
- | id | title | comment |
- +------+-------+---------+
- | 11 | yy | zz |
- | 10 | xx | haha |
- | 9 | sc | xxxxx |
- +------+-------+---------+
- 3 rows in set (0.01 sec)
5)在数据库服务器本机,查看表记录
在数据库服务器192.168.4.53 查看数据
- [root@host53 ~]# mysql -uroot -p123qqq...A -e "select * from db1.hotnews"
- mysql: [Warning] Using a password on the command line interface can be insecure.
- +------+-------+---------+
- | id | title | comment |
- +------+-------+---------+
- | 9 | sc | xxxxx |
- +------+-------+---------+
- [root@host53 ~]#
在数据库服务器192.168.4.54 查看数据
- [root@host54 ~]# mysql -uroot -p123qqq...A -e "select * from db2.hotnews"
- mysql: [Warning] Using a password on the command line interface can be insecure.
- +------+-------+---------+
- | id | title | comment |
- +------+-------+---------+
- | 10 | xx | haha |
- +------+-------+---------+
- [root@host54 ~]# [root@host54 ~]#
在数据库服务器192.168.4.55 查看数据
- [root@host55 ~]# mysql -uroot -p123qqq...A -e "select * from db3.hotnews"
- mysql: [Warning] Using a password on the command line interface can be insecure.
- +------+-------+---------+
- | id | title | comment |
- +------+-------+---------+
- | 11 | yy | zz |
- +------+-------+---------+
- [root@host55 ~]#
六、自定义数据库表
具体要求如下:
- 逻辑库名BBSDB
- 逻辑表名company2数据不分片,把数据存储到3台数据库服务器上
- 逻辑表名employee2 使用枚举法分片规则把数据存储到3台数据库服务器上
1.配置mycat服务器
1)添加新库
需要在server的property下添加一个库名
[root@mycat56 ~]# vim /usr/local/mycat/conf/server.xml
……
TESTDB,BBSDB //指定逻辑库名:wq
2)添加新表
- [root@mycat56 ~]# vim /usr/local/mycat/conf/schema.xml
company2" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" /> //指定逻辑表名company2
employee2" primaryKey="ID" dataNode="dn1,dn2,dn3" rule="sharding-by-intfile" />
- :wq
3)重启mycat服务
[root@mycat56 ~]# /usr/local/mycat/bin/mycat stop //停止服务
[root@mycat56 conf]# /usr/local/mycat/bin/mycat start //启动服务
2.测试配置
1)连接mycat服务器、建表、插入记录
[root@host50 ~]# mysql -h192.168.4.56 -P8066 -uroot -p123456 //连接mycat服务器
mysql> show databases; //显示已有的数据库
+----------+
| DATABASE |
+----------+
| BBSDB | //逻辑库BBSDB
| TESTDB |
+----------+
mysql> show tables; //查看表
+-----------------+
| Tables in BBSDB |
+-----------------+
| company | //逻辑表
| employee |
+-----------------+
mysql> desc company; //查看表表结构上一个实验创建了所以这里可以直接使用,否则你需要创建一下
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| ID | int(11) | NO | PRI | NULL | |
| name | char(50) | YES | | NULL | |
| addr | char(50) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into company(ID,name,addr)values(1,"tarena","beijing");//插入记录
Query OK, 1 row affected (0.10 sec)
mysql> insert into company(ID,name,addr)values(2,"tmall","beijing");
Query OK, 1 row affected (0.15 sec)
mysql> insert into company(ID,name,addr)values(3,"sina","beijing");
Query OK, 1 row affected (0.13 sec)
mysql> select * from company; //查看表记录
+----+--------+---------+
| ID | name | addr |
+----+--------+---------+
| 1 | tarena | beijing |
| 2 | tmall | beijing |
| 3 | sina | beijing |
+----+--------+---------+
3 rows in set (0.04 sec)
2)在数据库服务器本机,查看表记录,在数据库服务器53本机查看。
为什么会都有数据,因为我们这里并没有使用分片规则,没有定义规则就会默认在所有数据库上添加记录,这就相当于创建了一个数据集群
- [root@host53 ~]# mysql -uroot -p123qqq...A -e "select * from db1.company2"
- mysql: [Warning] Using a password on the command line interface can be insecure.
- +----+--------+---------+
- | ID | name | addr |
- +----+--------+---------+
- | 1 | tarena | beijing |
- | 2 | tmall | beijing |
- | 3 | sina | beijing |
- +----+--------+---------+
- [root@host53 ~]#
在数据库服务器54本机查看
- [root@host54 ~]# mysql -uroot -p123qqq...A -e "select * from db2.company2"
- mysql: [Warning] Using a password on the command line interface can be insecure.
- +----+--------+---------+
- | ID | name | addr |
- +----+--------+---------+
- | 1 | tarena | beijing |
- | 2 | tmall | beijing |
- | 3 | sina | beijing |
- +----+--------+---------+
- [root@host54 ~]#
在数据库服务器55本机查看
- [root@host55 ~]# mysql -uroot -p123qqq...A -e "select * from db3.company"
- mysql: [Warning] Using a password on the command line interface can be insecure.
- +----+--------+---------+
- | ID | name | addr |
- +----+--------+---------+
- | 1 | tarena | beijing |
- | 2 | tmall | beijing |
- | 3 | sina | beijing |
- +----+--------+---------+
你可能感兴趣的:(mysql)