分库分表
将存放在一个数据库中的数据,按照特定方式进行拆分,分散到多个数据库中,已达到分散单台设备负载的效果
垂直分割(纵向切分) | 水平分割(横向切分) |
---|---|
将单个表,拆分成多个表,分散到不同的数据库 将单数据库的多个表进行分类,按照业务类别分散到不同的数据库上 |
按照表中的某个字段的某种规则,把表中的许多记录按行切分,分到多个数据库中 |
常用软件mycat(基于阿里Cobar研发的开源软件)
基于java的分布式数据库系统中间层,适合数据大量写入,并为高并发环境的分布式访问提供解决方案
支持JDBC形式链接,MySQL,Oracle,Sqlserver,Mongodb等
提供数据读写分离,分片服务,可以实现数据库的高可用
分片规则 | 1.枚举法 sharding-by-intfile 2.固定分片rule1 3范围约定auto-sharding-long 4.求模法mod-long 5.日期列分区法sharding-by-date |
6.通配取模sharding-by-pattern 7.ASCII码求模通配sharding-by-prefixpattern 8.编码指定sharding-by-substring 9.字符串拆分hash解析sharding-by-stringhash 10.一致性hash sharding-by-murmur |
---|
工作过程
mysql收到SQL查询--解析查询涉及的表--查看表的定义,如果有规则,获取字段的值,并匹配分片函数,或得列表--将SQL发往分片执行--手机和处理结果数据,返回客户端
配置mycat
client 192.168.4.50 |
mycat服务器 192.168.4.56 |
mysql服务器 192.168.4.54 |
mysql服务器 192.168.4.55 |
装环境(56主机安装JDK,mycat服务软件包,54/55为mysql服务器)
[root@mysql56 ~]# 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
[root@mysql56 ~]# yum -y install java-1.8.0-openjdk-devel
[root@mysql56 ~]# java -version
openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-b12)
OpenJDK 64-Bit Server VM (build 25.131-b12, mixed mode)
[root@mysql56 ~]# tar -zxvf Mycat-server-1.4-beta-20150604171601-linux.tar.gz
[root@mysql56 ~]# mv mycat /usr/local/
[root@mysql56 ~]# ls /usr/local/mycat/
bin catlet conf lib logs version.txt
//bin--mycat命令,如启动,停止 catlet--扩展功能 conf--配置文件 lib--mycat使用的jar包
log--mycat启动和运行日志 wrapper.log--mycat服务启动日志(运行才会有) mycat.log--记录SQL脚本执行的报错内容(运行才会有)
[root@mysql56 conf]# ls *.xml
ehcache.xml log4j.xml router.xml rule.xml schema.xml server.xml
//rule.xml 定义mycat分片规则 server.xml 设置连mycat的账号信息 schema.xml 配置mycat的真实库表
[root@mysql54 mysql]# systemctl restart mysqld
[root@mysql55 mysql]# systemctl restart mysqld
修改配置文件server.xml schema.xml
[root@mysql56 conf]# vim /usr/local/mycat/conf/server.xml
</system>
34 <user name="admin"> //连mycat用户名
35 <property name="password">123456</property> //对应密码
36 <property name="schemas">TESTDB</property>
[root@mysql56 conf]# vim /usr/local/mycat/conf/schema.xml
...
5 <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100"> //schema name名字要和server.xml指定的名字一致
7 <table name="travelrecord" dataNode="dn1,dn2" rule="auto-sharding-long" /> //删除所有datanode节点(包括后面的)里的dn3,因为只有两台数据服务器
...
37 <dataNode name="dn1" dataHost="localhost1" database="db1" />
38 <dataNode name="dn2" dataHost="localhost2" database="db2" /> //datahost数据库主机 database主机对应数据库
...
46 <writeHost host="hostM1" url="192.168.4.54:3306" user="root"
47 password="123456"> //定义url password要符合数据库主机权限
48 <!-- can have multi read hosts -->
49
50 </writeHost>
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1"
slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="192.168.4.54:3306" user="root"
password="123456">
<!-- can have multi read hosts -->
</writeHost>
<!-- <writeHost host="hostM1" url="localhost:3316" user="root"
password="123456"/> -->
</dataHost> //把<datahost name>..</datahost>复制一份 有多少数据库服务器复制多少 并更改对应name url host
在54和55上建立mycat对应库和用户,并在56上测试
[root@mysql54 ~]# mysql -uroot -p123456
mysql> create database db1;
Query OK, 1 row affected (0.00 sec)
mysql> grant all on *.* to root@"%" identified by "123456";
[root@mysql55 ~]# mysql -uroot -p123456
mysql> create database db2;
Query OK, 1 row affected (0.00 sec)
mysql> grant all on *.* to root@"%" identified by "123456";
[root@mysql56 conf]# mysql -uroot -h192.168.4.54 -p123456 //在56上验证用户对54/55的链接
mysql>exit
[root@mysql56 conf]# mysql -uroot -h192.168.4.55 -p123456
mysql>
修改数据库服务器不去分库名及表名字母大小写
[root@mysql54 ~]# vim /etc/my.cnf //55上同操作
[mysqld]
...
lower_case_table_names=1
[root@mysql54 ~]# systemctl restart mysqld
启动mycat服务
[root@mysql56 conf]# /usr/local/mycat/bin/mycat status //查看状态
Mycat-server is not running.
[root@mysql56 conf]# /usr/local/mycat/bin/mycat start //启动
Starting Mycat-server...
[root@mysql56 conf]# /usr/local/mycat/bin/mycat status
Mycat-server is running (10799).
[root@mysql56 conf]# netstat -pntul | grep :8066 //还要再看端口是否启动
tcp6 0 0 :::8066 :::* LISTEN 10801/java
[root@mysql56 conf]# ps -C java
PID TTY TIME CMD
10801 ? 00:00:01 java
[root@mysql56 conf]# ls /usr/local/mycat/logs/ //日志文件
mycat.log mycat.pid wrapper.log
[root@mysql56 conf]# kill -9 10801 //结束进程
[root@mysql56 conf]# netstat -pntul | grep :8066
[root@mysql56 conf]#
验证分片,并在54,和55上查看
[root@mysql50 ~]# mysql -h192.168.4.56 -P8066 -uadmin -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(
-> ID int primary key auto_increment,
-> sharding_id int,
-> name char(15),
-> age tinyint unsigned default 28
-> );
Query OK, 0 rows affected (0.54 sec)
mysql> desc employee ;
+-------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------------+------+-----+---------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| sharding_id | int(11) | YES | | NULL | |
| name | char(15) | YES | | NULL | |
| age | tinyint(3) unsigned | YES | | 28 | |
+-------------+---------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> insert into employee(sharding_id,name) values(10000,"bob");
Query OK, 1 row affected (0.04 sec)
mysql> insert into employee(sharding_id,name) values(10010,"tom");
Query OK, 1 row affected (0.05 sec)
mysql> select * from db1.employee;
+----+-------------+------+------+
| ID | sharding_id | name | age |
+----+-------------+------+------+
| 1 | 10000 | bob | 28 |
+----+-------------+------+------+
1 row in set (0.00 sec)
mysql> select * from db2.employee;
+----+-------------+------+------+
| ID | sharding_id | name | age |
+----+-------------+------+------+
| 1 | 10010 | tom | 28 |
+----+-------------+------+------+
1 row in set (0.00 sec)