简介
MyCat
MyCat是一个开源的分布式数据库系统,是一个实现了MySQL协议的服务器,前端用户使用MySQL客户端工具和命令行对数据库进行访问,而其后端可以用MySQL原生协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信
MyCat的核心功能是分表分库,即将一个大表水平分割为多个小表,存储在后端不同的MySQL服务器中
工作原理
Mycat的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:如分
片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户
读写分离(Read/Write Splitting)
让一部分数据库服务器处理事务性增、改、删操作(INSERT、UPDATE、DELETE),另一部分数据库服务器处理SELECT查询操作
分库分表
当数据库达到一定规模后(比如说大几千万以上),对库和表进行切分是必须要考虑的,一般来说我们首先要进行垂直切分,即按业务分割,比如说用户相关、订单相关、统计相关等等都可以单独成库,然后进行水平切分进一步分散数据
前期准备
准备四台Centos7虚拟机,关闭防火墙和selinux,配置IP地址和hostname,同步系统时间,配置IP地址和Hostname映射
hostname | ip |
---|---|
mid | 192.168.29.133 |
node1 | 192.168.29.132 |
node2 | 192.168.29.138 |
node3 | 192.168.29.131 |
其中mid机器安装mycat中间件,其余node结点机器安装MySQL
MySQL配置
#在三个node结点创建mydb库和mycat_test用户用于测试
mysql>create database mydb charset utf8;
mysql>grant all privileges on mydb.* to 'mycat_test'@'192.168.29.%' identified by 'your_password';
mysql>flush privileges;
#在node1,node2的mydb库中创建test表
mysql>use mydb;
mysql>create table test(id int primary key);
#准备少量数据
mysql> select * from test;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
5 rows in set (0.01 sec)
#在node2,node3的mydb库中创建test1表
mysql>use mydb;
mysql>create table test1(id int primary key,name varchar(20) not null);
#准备少量数据
mysql> select * from test1;
+----+------+
| id | name |
+----+------+
| 1 | Jack |
| 2 | Tom |
+----+------+
2 rows in set (0.00 sec)
部署mycat
安装openjdk
[root@mid ~]# yum install java -y
#从mycat官网中下载mycat压缩包并解压
[root@mid ~]# tar -xvf Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz -C /usr/local/mycat
#配置Mycat启动管理文件
[root@mid ~]# vi /usr/lib/systemd/system/mycat.service
[Unit]
Description=mycat
After=syslog.target network.target
[Service]
Type=forking
Environment=CATALINA_HOME=/usr/local/mycat
Environment=CATALINA_BASE=/usr/local/mycat
ExecStart=/usr/local/mycat/bin/mycat start
ExecStop=/usr/local/mycat/bin/mycat stop
User=root
Group=root
[Install]
WantedBy=multi-user.target
#更新启动管理文件
[root@mid ~]# systemctl daemon-reload
#mycat部署完成
读写分离,分库分表配置
server.xml配置文件
[root@mid ~]# vi /usr/local/mycat/conf/server.xml
123456
TESTDB
TESTDB
配置schema.xml文件
[root@mid ~]# cat /usr/local/mycat/conf/schema.xml
#对应server.xml中的name="schemas"属性的值
#分表,对应后台数据库中的表,表名要保持一致
#分表对应的数据结点,database属性对应后台数据库的数据库
#根据数据结点进行对应配置,name要对应dataNode属性中的dataHost
select user()
#配置写结点
#配置读结点
select user()
启动mycat服务
[root@mid ~]# systemctl start mycat.service
#查看启动情况
[root@mid ~]# netstat -tnlp |egrep '8066|9066'
tcp6 0 0 :::8066 :::* LISTEN 3794/java
tcp6 0 0 :::9066 :::* LISTEN 3794/java
#服务启动成功
测试验证
测试在宿主机进行
#连接数据库
>mysql -u root -P 8066 -h 192.168.29.133 -p
#查看数据库情况
mysql> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB |
+----------+
1 row in set (0.06 sec)
mysql> use TESTDB;
Database changed
mysql> show tables;
+------------------+
| Tables in TESTDB |
+------------------+
| test |
| test1 |
+------------------+
2 rows in set (0.00 sec)
测试test表读写分离
#查看数据
mysql> select * from test;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
5 rows in set (0.03 sec)
#插入数据
mysql> insert into test values(6);
mysql> insert into test values(7);
#再次查看数据
mysql> select * from test;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
5 rows in set (0.03 sec)
#在node1上查看数据
mysql> mysql> select * ft;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
+----+
7 rows in set (0.01 sec)
#在node2上查看数据
mysql> mysql> select * ft;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
5 rows in set (0.00 sec)
#可见添加的数据写入node1中,而读取数据时从node2中读取
测试test1表读写分离
#查看数据
mysql> select * from test1;
+----+------+
| id | name |
+----+------+
| 1 | Jack |
| 2 | Tom |
+----+------+
2 rows in set (0.00 sec)
#插入数据
mysql> insert into test1 values(3,'Jerry');
#再次查看数据
mysql> select * from test1;
+----+------+
| id | name |
+----+------+
| 1 | Jack |
| 2 | Tom |
+----+------+
2 rows in set (0.01 sec)
#node2上查看数据
mysql> select * from test1;
+----+-------+
| id | name |
+----+-------+
| 1 | Jack |
| 2 | Tom |
| 3 | Jerry |
+----+-------+
3 rows in set (0.00 sec)
#node3上查看数据
mysql> select * from test1;
+----+------+
| id | name |
+----+------+
| 1 | Jack |
| 2 | Tom |
+----+------+
2 rows in set (0.00 sec)
#可见添加的数据写入node1中,而读取数据时从node2中读取
以上两项测试与mycat中配置写结点和读结点相符,实现了读写分离和分库分表的部署