mycat分表分库
目录
数据库分片
如何解决 并发访问压力,单表压力过大的问题?
mycat的介绍:
什么是分库分表?
通过某种特定条件,将存放在一个数据库 ( 主机 ) 中的数据,分散存放到多个数据库 ( 主机 ) 中。
已达到分散单台设备负载的效果,即分库分表。 数据的切分根据其切分规则的类型,分为 2 种切分模
式
垂直分割 ( 纵向 ) 和 水平分割 ( 横向 )
垂直分割
• 纵向切分
– 把单一的表,拆分成多个表,并分散到不同的数据库
( 主机 ) 上。
– 一个数据库由多个表构成,每个表对应不同的业务,
可以按照业务对表进行分类,将其分布到不同的数据
库 ( 主机 ) 上,实现专库专用,让不同的库 ( 主机 ) 分
担不同的业务。
水平分割
• 横向切分
– 按照表中某个字段的某种规则,把向表中写入的记录分散到多个库 ( 主机 ) 中。
– 简单来说,就是按照数据行切分,将表中的某些行存储到指定的数据库 ( 主机 ) 中。
软件介绍
Mycat 是基于 Java 的分布式数据库系统中间层,为
高并发下的分布式提供解决方案
– 支持 JDBC 形式连接
– 支持 MySQL 、 Oracle 、 Sqlserver 、 Mongodb 等
– 提供数据读写分离服务
– 可以实现数据库服务器的高可用
– 提供数据分片服务
– 基于阿里巴巴 Cobar 进行研发的开源软件
– 适合数据大量写入数据的存储需求
分片规则
• mycat 服务提供 10 种分片规则。
– 1 枚举法 sharding-by-intfile
– 2 固定分片 rule1
– 3 范围约定 auto-sharding-long
– 4 求模法 mod-long
– 5 日期列分区法 sharding-by-date
– 6 通配取模 sharding-by-pattern
– 7ASCII 码求模通配 sharding-by-prefixpattern
– 8 编程指定 sharding-by-substring
– 9 字符串拆分 hash 解析 sharding-by-stringhash
– 10 一致性 hash sharding-by-murmur
工作过程
当 Mycat 收到一个 SQL 时
– 会先解析这个 SQL 查找涉及到的表,然后看此表的定义
– 如果有分片规则,则获取到 SQL 里分片字段的值,并匹配分片函数,得到该 QL 对应的分片列表
– 然后将 SQL 发往这些分片去执行,最后收集和处理所有分片返回的结果数据,并输出到客户端
以 select * from Orders where prov=? 语句为例,查到 prov=wuhan ,
按照分片函数, wuhan 返回 dn1 ,于是 SQL 就发给了 MySQL1 ,去
取 DB1 上的查询结果,并返回给用户。
如果上述 SQL 改为 elect * from Orders where prov in
(‘wuhan’,‘beijing’) ,那么, SQL 就会发给 ySQL1 与 MySQL2 去执行,
然后结果集合并后输出给用户。但通常业务中我们的 SQL 会有 Order
By 以及 Limit 翻页语法,此时就涉及到结果集在 Mycat 端的二次处
理。
准备环境
192.168.4.51 mycat分片
192.168.4.52 dn1
192.168.4.53 dn2
192.168.4.54 客户端
配置过程
主机51和主机52的配置 (这里只写一台数据库)
[[email protected] ~]# tar -xaf mysql-5.7.17.tar
[[email protected] ~]# ls
mysql-community-client-5.7.17-1.el7.x86_64.rpm
mysql-community-common-5.7.17-1.el7.x86_64.rpm
mysql-community-devel-5.7.17-1.el7.x86_64.rpm
mysql-community-embedded-5.7.17-1.el7.x86_64.rpm
mysql-community-embedded-compat-5.7.17-1.el7.x86_64.rpm
mysql-community-embedded-devel-5.7.17-1.el7.x86_64.rpm
mysql-community-libs-5.7.17-1.el7.x86_64.rpm
mysql-community-libs-compat-5.7.17-1.el7.x86_64.rpm
mysql-community-minimal-debuginfo-5.7.17-1.el7.x86_64.rpm
mysql-community-server-5.7.17-1.el7.x86_64.rpm
mysql-community-test-5.7.17-1.el7.x86_64.rpm
[[email protected] ~]# yum install mysql-comm*
[[email protected] ~]# systemctl restart mysqld
[[email protected] ~]# cat /var/log/mysqld.log | grep password
2018-08-28T01:45:31.046087Z 1 [Note] A temporary password is generated for [email protected]: nz!4X3-OsSOe
[[email protected] ~]# vim /etc/my.cnf ----添加
[mysqld]
validate_password_policy=0
validate_password_length=6
[[email protected] ~]# systemctl restart mysqld
[[email protected] ~]# mysql -uroot -p'nz!4X3-OsSOe'
[[email protected] ~]# mysql -uroot -p'123456'
配置mycat服务器
[[email protected] ~]# rpm -qa | grep -i jdk
java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64
java-1.8.0-openjdk-headless-1.8.0.131-11.b12.el7.x86_64
copy-jdk-configs-2.2-3.el7.noarch
[[email protected] ~]# ls
Mycat-server-1.4-beta-20150604171601-linux.tar.gz
[[email protected] ~]# rpm -qa | grep -i jdk
java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64
java-1.8.0-openjdk-headless-1.8.0.131-11.b12.el7.x86_64
copy-jdk-configs-2.2-3.el7.noarch
[[email protected] ~]# tar -xaf Mycat-server-1.4-beta-20150604171601-linux.tar.gz
[[email protected] ~]# cd mycat/
[[email protected] mycat]# ls
bin catlet conf lib logs version.txt
[[email protected] ~]# mv mycat/ /usr/local/
2.工作目录
[[email protected] ~]# ls /usr/local/
bin etc games include lib lib64 libexec mycat sbin share src
3.修改配置文件
[[email protected] ~]# cd /usr/local/mycat/
[[email protected] mycat]# cd conf/
[[email protected] conf]# ls
autopartition-long.txt myid.properties sequence_time_conf.properties
auto-sharding-long.txt partition-hash-int.txt server.xml
auto-sharding-rang-mod.txt partition-range-mod.txt sharding-by-enum.txt
cacheservice.properties rule.xml wrapper.conf
ehcache.xml schema.xml zkconf
index_to_charset.properties sequence_conf.properties zkdownload
log4j2.xml sequence_db_conf.properties
migrateTables.properties sequence_distributed_conf.properties
[[email protected] conf]# cp server.xml server.xml.bak ---做备份
[[email protected] conf]# cp schema.xml schema.xml.bak ----做备份
[[email protected] conf]# vim rule.xml
[[email protected] conf]# cat /usr/local/mycat/conf/server.xml #定义连接客户端连接mycat服务使用的用户名和密码及逻辑库的名字
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://org.opencloudb/">
<system>
<property name="defaultSqlParser">druidparser</property>
<!-- <property name="useCompression">1</property>--> <!--1为开启mysql压缩协议-->
<!-- <property name="processorBufferChunk">40960</property> -->
<!--
<property name="processors">1</property>
<property name="processorExecutor">32</property>
-->
<!--默认是65535 64K 用于sql解析时最大文本长度 -->
<!--<property name="maxStringLiteralLength">65535</property>-->
<!--<property name="sequnceHandlerType">0</property>-->
<!--<property name="backSocketNoDelay">1</property>-->
<!--<property name="frontSocketNoDelay">1</property>-->
<!--<property name="processorExecutor">16</property>-->
<!--
<property name="mutiNodeLimitType">1</property> 0:开启小数量级(默认) ;1:开启亿级数据排序
<property name="mutiNodePatchSize">100</property> 亿级数量排序批量
<property name="processors">32</property> <property name="processorExecutor">32</property>
<property name="serverPort">8066</property> <property name="managerPort">9066</property>
<property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property>
<property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
</system>
<user name="test"> #连接mycat服务时使用的用户名 test
<property name="password">test</property> #使用test用户连接mycat用户时使用的密码
<property name="schemas">TESTDB</property> #连接上mycat服务后,可以看到的库名多个时,使用逗号分隔 (是逻辑上的库名)
</user>
<user name="user">
<property name="password">user</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property> #定义只读权限,使用定义的user用户连接mycat服务后只有读记录的权限
</user>
<!-- <cluster> <node name="cobar1"> <property name="host">127.0.0.1</property>
<property name="weight">1</property> </node> </cluster> -->
<!-- <quarantine> <host name="1.2.3.4"> <property name="user">test</property>
</host> </quarantine> -->
</mycat:server>
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[[email protected] conf]# cat /usr/local/mycat/conf/schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100"> #逻辑库名 要与server.xml定义的一样
<table name="travelrecord" dataNode="dn1,dn2" rule="auto-sharding-long" /> #定义分片的表
<table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2" /> #定义分片的表
<table name="goods" primaryKey="ID" type="global" dataNode="dn1,dn2" /> #定义分片的表
<table name="hotnews" primaryKey="ID" dataNode="dn1,dn2" rule="mod-long" /> #定义分片的表
<table name="employee" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile" /> #定义分片的表
<table name="customer" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile" /> #定义分片的表
</schema>
<dataNode name="dn1" dataHost="c1" database="db1" />
#定义分片使用的库,所在的物理主机 ,真正存储数据的db1库在物理主机c1上
<dataNode name="dn2" dataHost="c2" database="db2" />
#定义分片使用的库,所在的物理主机 ,真正存储数据的db2库在物理主机c2上
#指定c1名称主机对应的ip地址
<dataHost name="c1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" >
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="192.168.4.55:3306" user="admin"
password="123456"> #访问数据时 mycat服务连接数据库服务器时使用的用户名和密码
</writeHost>
</dataHost>
#指定c2名称主机对应的ip地址
<dataHost name="c2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="
[[email protected] ~]# cat /usr/local/mycat/conf/server.xml #定义连接客户端连接mycat服务使用的用户名和密码及逻辑库的名字
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://org.opencloudb/">
<system>
<property name="defaultSqlParser">druidparser</property>
<!-- <property name="useCompression">1</property>--> <!--1为开启mysql压缩协议-->
<!-- <property name="processorBufferChunk">40960</property> -->
<!--
<property name="processors">1</property>
<property name="processorExecutor">32</property>
-->
<!--默认是65535 64K 用于sql解析时最大文本长度 -->
<!--<property name="maxStringLiteralLength">65535</property>-->
<!--<property name="sequnceHandlerType">0</property>-->
<!--<property name="backSocketNoDelay">1</property>-->
<!--<property name="frontSocketNoDelay">1</property>-->
<!--<property name="processorExecutor">16</property>-->
<!--
<property name="mutiNodeLimitType">1</property> 0:开启小数量级(默认) ;1:开启亿级数据排序
<property name="mutiNodePatchSize">100</property> 亿级数量排序批量
<property name="processors">32</property> <property name="processorExecutor">32</property>
<property name="serverPort">8066</property> <property name="managerPort">9066</property>
<property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property>
<property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
</system>
<user name="test"> #连接mycat服务时使用的用户名 test
<property name="password">test</property> #使用test用户连接mycat用户时使用的密码
<property name="schemas">TESTDB</property> #连接上mycat服务后,可以看到的库名多个时,使用逗号分隔 (是逻辑上的库名)
</user>
<user name="user">
<property name="password">user</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property> #定义只读权限,使用定义的user用户连接mycat服务后只有读记录的权限
</user>
<!-- <cluster> <node name="cobar1"> <property name="host">127.0.0.1</property>
<property name="weight">1</property> </node> </cluster> -->
<!-- <quarantine> <host name="1.2.3.4"> <property name="user">test</property>
</host> </quarantine> -->
</mycat:server>
启动服务
[[email protected] conf]# sed -n '4,5p' /usr/local/mycat/conf/wrapper.conf
# Java Application
wrapper.java.command=java
[[email protected] conf]# which java
/usr/bin/java
[[email protected] conf]# echo "export PATH=/usr/local/mycat/bin" >> /etc/profile
[[email protected] conf]#source /etc/profile
[[email protected] conf]# mycat --help
Usage: /usr/local/mycat/bin/mycat { console | start | stop | restart | status | dump }
[[email protected] conf]# mycat start
Starting Mycat-server...
[[email protected] conf]# netstat -utnalp | grep :8066
tcp6 0 0 :::8066 :::* LISTEN 4524/java
测试MyCAT
[[email protected] ~]# mysql -h192.168.4.56 -P8066 -utest -ptest //客户端连接mycat服务器,存储数据
MySQL [(none)]> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB |
+----------+
1 row in set (0.00 sec)
MySQL [(none)]> use TESTDB;
MySQL [TESTDB]> show tables;
+------------------+
| Tables in TESTDB |
+------------------+
| company |
| customer |
| employee |
| goods |
| hotnews |
| travelrecord |
+------------------+
6 rows in set (0.00 sec)
MySQL [TESTDB]> MySQL [TESTDB]> create table employee( id int not null primary key, name varchar(100), sharding_id int not null );
MySQL [TESTDB]> MySQL [TESTDB]> insert into employee(id,name,sharding_id)values(1,"bob",10000),(2,"lucy",10010),(3,"alice",10000),(4,"jerry",10010);
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
mysql> select @@hostname;
+------------+
| @@hostname |
+------------+
| c1 |
+------------+
1 row in set (0.00 sec)
mysql> select * from employee;
Empty set (0.00 sec)
mysql> select * from employee;
+----+-------+-------------+
| id | name | sharding_id |
+----+-------+-------------+
| 1 | bob | 10000 |
| 3 | alice | 10000 |
+----+-------+-------------+
2 rows in set (0.00 sec)
++++++++++++++++++++++++++++++++++++++++++++++
mysql> select @@hostname;
+------------+
| @@hostname |
+------------+
| c2 |
+------------+
1 row in set (0.00 sec)
mysql> select * from employee;
Empty set (0.00 sec)
mysql> select * from employee;
+----+-------+-------------+
| id | name | sharding_id |
+----+-------+-------------+
| 2 | lucy | 10010 |
| 4 | jerry | 10010 |
+----+-------+-------------+
2 rows in set (0.00 sec)
主机52
[[email protected] ~]# mysql -uroot -p123456
mysql> use db1
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| employee |
+---------------+
1 row in set (0.00 sec)
mysql> select * from employee
-> ;
+----+-------+-------------+
| id | name | sharding_id |
+----+-------+-------------+
| 1 | bob | 10000 |
| 3 | alice | 10000 |
+----+-------+-------------+
2 rows in set (0.00 sec)
主机53
[[email protected] ~]# mysql -uroot -p123456
mysql> select * from employee;
ERROR 1046 (3D000): No database selected
mysql> use db2
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from employee ;
+----+-------+-------------+
| id | name | sharding_id |
+----+-------+-------------+
| 2 | lucy | 10010 |
| 4 | jerry | 10010 |
+----+-------+-------------+
2 rows in set (0.00 sec)