1、分库分表
2、MyCAT软件介绍:提供数据分库分表存储的服务软件(中间件)
- mycat是基于java的分布式数据库系统中间件,为高并发环境的分布式存储提供解决数据的方案。
- 适合数据大量写入的存储需求,支持MySQL、Oracle、Sqlserver、Mongodb等。
- 提供数据读写分离服务,提供数据分片服务
- 基于阿里巴巴Cobar进行研发的开源软件,查询数据比较慢。
3、mycat分布服务器的工作过程
- 当mycat收到sql命令时,解析sql命令涉及到的表。
- 然后看对表的配置,如果有分片规则,则获取sql命令里分片字段的值,并匹配分片函数,获得分片列表。
- 然后将sql命令发往对应的数据库服务器去执行。
- 最后收集和处理所有分片结果数据,并返回到客户端。
- 分布式存储数据表名不允许重复
4、mycat服务部署
Schema
Schema:由它指定逻辑数据库(相当于MySQL的database数据库)Table
Table:逻辑表(相当于MySQL的table表)DataNode
DataNode:真正存储数据的物理节点DataHost
DataHost:存储节点所在的数据库主机(指定MySQL数据库的连接信息)User
User:MyCat的用户(类似于MySQL的用户,支持多用户)
4.1、环境准备
1)mycat分片服务器:192.168.4.40,不需要安装数据库服务软件
2)三台数据库服务器:192.168.4.10 / 20 / 30,3台全新的数据库服务器
3)客户端服务器:192.168.4.50,只需要有mysql命令,数据库服务不需要
注意:mycat内存不小于1G,所有服务器关闭firewalld、selinux
4.2、部署mycat服务(192.168.4.40)
链接:https://pan.baidu.com/s/1x8wG4qn3FsVaCfJnzMcM0g
提取码:xbjy
1)安装软件
[root@mycat ~]# yum -y install java-1.8.0-openjdk.x86_
[root@mycat ~]# tar xf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
[root@mycat ~]# mv mycat/ /usr/local/mycat
2)修改配置文件
- /usr/local/mycat/conf/*.xml:mycat服务软件的配置文件
- /usr/local/mycat/conf/*.txt:分片规则配置文件
- /usr/local/mycat/conf/*.properties:分片规则配置文件
- /usr/local/mycat/log:日志文件
- /usr/local/mycat/lib:java主程序存放目录
- /usr/local/mycat/version.txt:软件的一些信息以及开发团队的信息。
- /usr/local/mycat/catlet:和其他协同工作的时候存放的目录
主要是修改如下3个配置文件
- schema.xml:定义逻辑库,表、分片节点等内容
- rule.xml:定义分片规则
- server.xml:定义用户以及系统相关变量,如端口等
3) 定义客户端连接mycat使用的用户名、密码、虚拟库名
[root@mycat ~]# vim /usr/local/mycat/conf/server.xml
<user name="root"> 用户名
<property name="password">123456</property> 密码
<property name="schemas">TESTDB</property> 虚拟库名
</user>
<user name="user"> 用户名
<property name="password">user</property> 密码
<property name="schemas">TESTDB</property> 虚拟库名
<property name="readOnly">true</property> 只读访问权限
</user>
4)定义分片存储数据的表
设置分片存储数据的表配置文件说明:
[root@mycat ~]# vim /usr/local/mycat/conf/schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
#定义分片存储数据的表
<schema ....>
<table name="表名" dataNode="数据库要存储在几台服务器里" rule="分片规则名" / >
<table ...>
....
</table>
</schema>
#定义数据库服务器主机名
<dataNode name="第几台数据库服务器" dataHost="主机名" database="库名" />
<dataHost ..... >
......
</dataHost>
</mycat:schema>
5)备份源文件,删除不需要的行
[root@mycat ~]# cp /usr/local/mycat/conf/schema.xml /root/
[root@mycat ~]# sed -i '56,77d' /usr/local/mycat/conf/schema.xml
[root@mycat ~]# sed -i '39,42d' /usr/local/mycat/conf/schema.xml
6)修改配置文件,标红的部分是定义存储数据的数据库服务器
[root@mycat ~]# vim /usr/local/mycat/conf/schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/"><schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
<table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" />
<table name="goods" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" />
<table name="hotnews" primaryKey="ID" autoIncrement="true" dataNode="dn1,dn2,dn3"
rule="mod-long" />
<table name="employee" primaryKey="ID" dataNode="dn1,dn2,dn3"
rule="sharding-by-intfile" />
<table name="customer" primaryKey="ID" dataNode="dn1,dn2,dn3"
rule="sharding-by-intfile">
<childTable name="orders" primaryKey="ID" joinKey="customer_id"
parentKey="id">
<childTable name="order_items" joinKey="order_id"
parentKey="id" />
</childTable>
<childTable name="customer_addr" primaryKey="ID" joinKey="customer_id"
parentKey="id" />
</table>
</schema>
<dataNode name="dn1" dataHost="mysql10" database="db1" />
<dataNode name="dn2" dataHost="mysql20" database="db2" />
<dataNode name="dn3" dataHost="mysql30" database="db3" />
<dataHost name="mysql10" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="192.168.4.10:3306" user="jyadmin"
password="JY1987...zy2011">
</writeHost>
</dataHost>
<dataHost name="mysql20" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM2" url="192.168.4.20:3306" user="jyadmin"
password="JY1987...zy2011">
</writeHost>
</dataHost>
<dataHost name="mysql30" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM3" url="192.168.4.30:3306" user="jyadmin"
password="JY1987...zy2011">
</writeHost>
</dataHost>
</mycat:schema>
4.3、部署数据库服务器(192.168.4.10 | 20 |30)
1)三台数据库服务器都要添加用户jyadmin
mysql> grant all on *.* to jyadmin@"%" identified by "JY1987...zy2011";
Query OK, 0 rows affected, 1 warning (0.00 sec)
2)创建存储数据的库
mysql> create database db1; # 数据库mysql10创建
Query OK, 1 row affected (0.01 sec)
mysql> create database db2; #数据库mysql20创建
Query OK, 1 row affected (0.00 sec)
mysql> create database db3; #数据库mysql30创建
Query OK, 1 row affected (0.00 sec)
4.4、启动192.168.4.40主机的mycat服务
1)验证数据库服务器的授权用户
[root@mycat ~]# which mysql || yum -y install mariadb
[root@mycat ~]# mysql -h192.168.4.10 -ujyadmin -pJY1987...zy2011
[root@mycat ~]# mysql -h192.168.4.20 -ujyadmin -pJY1987...zy2011
[root@mycat ~]# mysql -h192.168.4.30 -ujyadmin -pJY1987...zy2011
2)启动mycat服务
[root@mycat ~]# /usr/local/mycat/bin/mycat start # 启动
Starting Mycat-server...
[root@mycat ~]# ls /usr/local/mycat/logs/
mycat.log mycat.pid wrapper.log
[root@mycat ~]# netstat -utnlp | grep 8066
tcp6 0 0 :::8066 :::* LISTEN 1808/java
[root@mycat ~]# /usr/local/mycat/bin/mycat stop # 停止
Stopping Mycat-server...
Stopped Mycat-server.
[root@mycat ~]# netstat -utnlp | grep 8066
[root@mycat ~]# ls /usr/local/mycat/logs/
mycat.log wrapper.log
[root@mycat ~]# cat /usr/local/mycat/logs/wrapper.log #排错的日志
4.5、客户端【192.168.4.50】连接mycat服务器,查看库和表
[root@host50 ~]# mysql -h192.168.4.40 -P8066 -uroot -p123456
mysql> use TESTDB;
Database changed
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> select * from goods;
ERROR 1146 (42S02): Table 'db2.goods' doesn't exist
4.5、建表并存储数据,分片规则配置说明:
- 定义分片规则的表名:(schema.xml 文件里 <table> )
- 定义分片字段的表头名:(rule.xml文件里 <tableRule> )
- 定义分片规则使用的配置文件,定义分片字段的值:(rule.xml文件里<function> )
4.6、枚举分片规则(sharding-by-intfile)
- 分片字段的值必须在分片规则配置文件中定义的值里选择。
- 分片字段 :表使用了分片规则存储数据,建表时必须创建分片规则要求的表头名
- 枚举分片规则表里必须有名称叫sharding_id的表头名
- 数据管理员在分片规则配置文件定义分片字段的值
[root@mycat ~]# vim /usr/local/mycat/conf/schema.xml
…………
<table name="employee" primaryKey="ID" dataNode="dn1,dn2"
rule="sharding-by-intfile" />
<table name="customer" primaryKey="ID" dataNode="dn1,dn2"
rule="sharding-by-intfile">
…………
2)查看employee分片字段名(sharding_id)
[root@mycat ~]# vim /usr/local/mycat/conf/rule.xml
…………
<tableRule name="rule1">
<rule>
<columns>sharding_id</columns> # 分片字段名
<algorithm>hash-int</algorithm> # 算法名,存储数据的计算规则
</rule>
</tableRule>
…………
3)找到对应sharding-by-intfile分片规则配置文件partition-hash-int.txt
[root@mycat ~]# vim /usr/local/mycat/conf/rule.xml
…………
<function name="hash-int" # 算法名
class="io.mycat.route.function.PartitionByFileMap"> # 算法调用的执行程序
<property name="mapFile">partition-hash-int.txt</property> # 配置文件名
</function>
…………
4)配置文件partition-hash-int.txt设置分片字段的值,定义sharding-by-intfile分片规则
[root@mycat ~]# vim /usr/local/mycat/conf/partition-hash-int.txt
10000=0 # 0对应dn1,主机192.168.4.10,数据库db1
10010=1 # 0对应dn2,主机192.168.4.20,数据库db2
10020=2 # 0对应dn3,主机192.168.4.30,数据库db3
[root@mycat ~]# /usr/local/mycat/bin/mycat restart
5)客户端根据分片规则建表,并存储数据
[root@host50 ~]# mysql -h192.168.4.40 -P8066 -uroot -p123456
mysql> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB |
+----------+
1 row in set (0.01 sec)
mysql> use 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> create table employee(sharding_id int ,name char(10),addr char(20));
Query OK, 0 rows affected (0.18 sec)
mysql> insert into employee(sharding_id,name,addr) values(10000,"xb","zb");
mysql> insert into employee(sharding_id,name,addr) values(10000,"xb2","zb");
mysql> insert into employee(sharding_id,name,addr) values(10000,"xb3","zb");
mysql> insert into employee(sharding_id,name,addr) values(10010,"zy","jj");
mysql> insert into employee(sharding_id,name,addr) values(10010,"jy","mm");
mysql> insert into employee(sharding_id,name,addr) values(10020,"jy2","mm");
# 错误示范,10040超出分片字段的范围
mysql> insert into employee(sharding_id,name,addr) values(10040,"jy2","mm");
ERROR 10 (HY000): can't find any valid datanode :EMPLOYEE -> SHARDING_ID -> 10040
mysql> select * from employee ;
+-------------+------+------+
| sharding_id | name | addr |
+-------------+------+------+
| 10010 | zy | jj |
| 10010 | jy | mm |
| 10000 | xb | zb |
| 10000 | xb2 | zb |
| 10000 | xb3 | zb |
| 10020 | jy2 | mm |
+-------------+------+------+
6 rows in set (0.19 sec)
6)在数据库服务器本机查看数据
[root@mysql10 ~]# mysql -uroot -pJY1987...zy2011 -e "select * from db1.employee"
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------------+------+------+
| sharding_id | name | addr |
+-------------+------+------+
| 10000 | xb | zb |
| 10000 | xb2 | zb |
| 10000 | xb3 | zb |
+-------------+------+------+
[root@mysql20 ~]# mysql -uroot -pJY1987...zy2011 -e "select * from db2.employee"
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------------+------+------+
| sharding_id | name | addr |
+-------------+------+------+
| 10010 | zy | jj |
| 10010 | jy | mm |
+-------------+------+------+
[root@mysql30 ~]# mysql -uroot -pJY1987...zy2011 -e "select * from db3.employee"
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------------+------+------+
| sharding_id | name | addr |
+-------------+------+------+
| 10020 | jy2 | mm |
+-------------+------+------+
4.7、mod-long分片规则工作过程
- 根据分片字段值与数据库服务器的台数取余计算,
- 根据余数存储数据到后端的数据库服务器。
- 使用求模分片规则存储数据的表里必须有名称叫id的表头(分片字段)
1)查看mod-long分片规则的表名
[root@mycat ~]# vim /usr/local/mycat/conf/schema.xml
…………
<table name="hotnews" primaryKey="ID" autoIncrement="true" dataNode="dn1,dn2,dn3"
rule="mod-long" />
…………
2)查看mod-long分片字段名(sharding_id)
[root@mycat ~]# vim /usr/local/mycat/conf/rule.xml
…………
<tableRule name="mod-long">
<rule>
<columns>id</columns> # 分片字段名
<algorithm>mod-long</algorithm> # 算法名,存储数据的计算规则
</rule>
</tableRule>
…………
3)确定分片规则使用的配置文件,定义分片字段的值
[root@mycat ~]# vim /usr/local/mycat/conf/rule.xml
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">3</property> # 定义分片字段,求模计算的数字,是数据库服务器的台数
</function>
4)重启mycat服务
[root@mycat ~]# /usr/local/mycat/bin/mycat restart
[root@mycat ~]# netstat -ntulp | grep 8066
tcp6 0 0 :::8066 :::* LISTEN 4551/java
5)客户端根据分片规则建表,并存储数据
[root@host50 ~]# mysql -h192.168.4.40 -P8066 -uroot -p123456
mysql> use TESTDB;
mysql> create table hotnews(id int , title char(30),comment varchar(150) ,worker char(3));
Query OK, 0 rows affected (0.12 sec)
mysql> insert into hotnews(id,title,comment,worker) values(1,"a","a","a");
mysql> insert into hotnews(id,title,comment,worker) values(2,"b","b","b");
mysql> insert into hotnews(id,title,comment,worker) values(3,"c","c","c");
mysql> insert into hotnews(id,title,comment,worker) values(108,"d","d","d");
mysql> insert into hotnews(id,title,comment,worker) values(0,"f","f","f");
mysql> select * from hotnews;
+------+-------+---------+--------+
| id | title | comment | worker |
+------+-------+---------+--------+
| 3 | c | c | c |
| 108 | d | d | d |
| 0 | f | f | f |
| 2 | b | b | b |
| 1 | a | a | a |
+------+-------+---------+--------+
5 rows in set (0.18 sec)
6)在数据库服务器本机查看数据
当余数是 0 数据存储到dn1,192.168.4.10
当余数是 1 数据存储到dn2,192.168.4.20
当余数是 2 数据存储到dn3,192.168.4.30
[root@mysql10 ~]# mysql -uroot -pJY1987...zy2011 -e "select * from db1.hotnews"
mysql: [Warning] Using a password on the command line interface can be insecure.
+------+-------+---------+--------+
| id | title | comment | worker |
+------+-------+---------+--------+
| 3 | c | c | c |
| 108 | d | d | d |
| 0 | f | f | f |
+------+-------+---------+--------+
[root@mysql20 ~]# mysql -uroot -pJY1987...zy2011 -e "select * from db2.hotnews"
mysql: [Warning] Using a password on the command line interface can be insecure.
+------+-------+---------+--------+
| id | title | comment | worker |
+------+-------+---------+--------+
| 1 | a | a | a |
+------+-------+---------+--------+
[root@mysql30 ~]# mysql -uroot -pJY1987...zy2011 -e "select * from db3.hotnews"
mysql: [Warning] Using a password on the command line interface can be insecure.
+------+-------+---------+--------+
| id | title | comment | worker |
+------+-------+---------+--------+
| 2 | b | b | b |
+------+-------+---------+--------+
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- huatuo9.cn 版权所有 赣ICP备2023008801号-1
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务