三、Mycat高级特性
3.1 Mycat读写分离概述
什么是读写分离
读写分离,基本的原理是让主数据库处理事务性增、改、删操作,而从数据库处理查询操作。
为什么使用读写分离
从集中到分布,最基本的一个需求不是数据存储的瓶颈,而是在于 计算的瓶颈,即 SQL 查询的瓶颈,我们知道,正常情况下,Insert SQL 就是几十个毫秒的时间内写入完成,而系 统中的大多数 Select SQL 则要几秒到几分钟才能有结果,很多复杂的 SQL,其消耗服务器 CPU 的能力超强,不亚于死循环的威力。高峰期,复杂的查询可能导致服务器瘫痪。
读写分离方案
MyCat的读写分离是建立在MySQL主从复制基础之上实现的,所以必须先搭建MySQL的主从复制。数据库读写分离对于⼤型系统或者访问量很⾼的互联网应用来说,是必不可少的⼀个重要功能。
注意:
Mycat实现的读写分离和自动切换机制,需要MySQL的主从复制机制配合。
Mysql 主从复制的常用拓扑结构
一主一从
注意:
最基础的复制结构,用来分担之前单台数据库服务器的压力,可以进行读写分离。
一主多从
注意:
一台 Slave 承受不住读请求压力时,可以添加多台,进行负载均衡,分散读压力。
双主复制
注意:
双主结构就是用来解决这个问题的,互相将对方作为自己的 Master,自己作为对方的 Slave 来进行复制,但对外来讲,还是一个主和一个从。
级联复制
注意: 级联结构就是通过减少直接从属于 Master 的 Slave 数量,减轻 Master 的压力,分散复制请求,从而提高整体的复制效率。
双主级联
注意:
Mysql 的复制结构有很多种方式,复制的最大问题是数据延时,选择复制结构时需要根据自己的具体情况,并评估好目标结构的延时对系统的影响。
3.2 搭建读写分离
检查主从复制是否开启
mysql> show slave status \G;
修改mycat配置文件schema.xml,添加dataNode属性
<schema name="TESTDB" checkSQLschema="false" dataNode="db_node" sqlMaxLimit="100"> </schema>
参数:
- schema:逻辑库 name :逻辑库名称
- sqlMaxLimit:一次取多少条数据
- table:逻辑表
- dataNode:数据节点 对应 datanode标签
- rule:分片规则 对应 rule.xml
- primaryKey: 分片主键 可缓存
分片配置
<dataNode name="db_node" dataHost="db_host" database="hi_db" />
参数:
- name:分片名字
- dataHost:分片主机
- database:分片数据库,该数据库是真实存在的数据库
配置读写分离
<dataHost name="db_host" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> #写库(主节点) <writeHost host="hostM1" url="192.168.66.100:3306" user="root" password="123456"> #读库(从节点) <readHost host="hostS2" url="192.168.66.102:3306" user="root" password="123456" /> </writeHost> </dataHost>
参数:
- dataHost:数据主机(节点主机)
- dbType:数据库驱动native:MySQL JDBC: oracle SQLServer
- switchType: 是否主动读 1
Balance参数设置:
- balance=“0”, 所有读操作都发送到当前可⽤的writeHost上。
- balance=“1”,所有读操作都随机的发送到readHost。
- balance=“2”,所有读操作都随机的在writeHost、readhost上分发
WriteType参数设置:
- writeType=“0”, 所有写操作都发送到可⽤的writeHost上。
- writeType=“1”,所有写操作都随机的发送到readHost。
- writeType=“2”,所有写操作都随机的在writeHost、readhost分上发。
witchType参数设置:
- switchType="1", 主从自动切换
- switchType="2",从机延时超过slaveThreshold值时切换为主读
这里的hi_db实际上在主库和从库中都会存在,因为主从复制的原因,当我们在master中创建数据库或者表的时候,从库中就会将主库中的数据库和数据表复制到从库中。
启动Mycat
mycat restart
连接到mycat
mysql -uroot -p123456 -h 192.168.66.100 -P 8066
注意:这里的-p密码是mycat的密码,-P 8066是mycatCRUD的端口。
查看逻辑数据库TESTDB
mysql> show databases; +----------+ | DATABASE | +----------+ | TESTDB | +----------+ 1 row in set (0.00 sec)
查看逻辑数据库中的表
mysql> use TESTDB; 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_hi_db | +-----------------+ | hi_tb | +-----------------+ 1 row in set (0.00 sec mysql> select * from hi_tb; +------+------+ | id | name | +------+------+ | 1 | zj | +------+------+ 1 row in set (0.02 sec)
验证读写分离
#查看主机的名称(写库) [root@localhost /]# uname -n localhost.localdomain #mycat插入数据 mysql> insert into hi_tb values(2,@@hostname); Query OK, 1 row affected (0.01 sec) mysql> select * from hi_tb; +------+-----------------------+ | id | name | +------+-----------------------+ | 1 | zj | | 2 | localhost.localdomain | +------+-----------------------+ 2 rows in set (0.00 sec)
3.3 MySQL双主双从原理
一主一从
注意: 是最基础的复制结构,用来分担之前单台数据库服务器的压 力,可以进行读写分离。
一主多从
问题: 一台 Slave 承受不住读请求压力时,可以添加多台,进行负载 均衡,分散读压力。
如何解决
介绍: 互相将对方作为自己的 Master,自己作为对方的 Slave 来进行 复制,但对外来讲,还是一个主和一个从。
3.4 通过Docker搭建双主双从
环境准备
编号 | 角色 | IP地址 | 端口 | 机器名 |
1 | Master1 | 192.168.66.100 | 3350 | node-1 |
2 | Slave1 | 192.168.66.100 | 3360 | node-2 |
3 | Master2 | 192.168.66.100 | 3370 | node-3 |
4 | Slave2 | 192.168.66.100 | 3380 | node-4 |
创建docker容器
#启动第一台 docker run -d -p 3350:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=master1 mysql:5.7 #启动第二台 docker run -d -p 3360:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=slave1 mysql:5.7 #启动第三台 docker run -d -p 3370:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=master2 mysql:5.7 #启动第四台 docker run -d -p 3380:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=slave2 mysql:5.7
docker容器安装vim
#软件库更新 apt-get update #安装vim apt-get install -y vim
修改容器内MySQL配置文件
1、修改master1配置文件开启binlog日志
#进入master1配置文件 vim /etc/mysql/mysql.conf.d/mysqld.cnf [mysqld] #主服务器唯一ID server-id=1 #启用二进制日志 log-bin=mysql-bin # 设置不要复制的数据库(可设置多个) binlog-ignore-db=mysql binlog-ignore-db=information_schema #设置logbin格式 binlog_format=STATEMENT # 在作为从数据库的时候,有写入操作也要更新二进制日志文件 log-slave-updates #指自增字段的起始值,其默认值是1,取值范围是1 .. 65535 auto-increment-increment=2 # 指字段一次递增多少,他的取值范围是1 .. 65535 auto-increment-offset=1
2、修改master2配置文件
[mysqld] #主服务器唯一ID server-id=3 #启用二进制日志 log-bin=mysql-bin # 设置不要复制的数据库(可设置多个) binlog-ignore-db=mysql binlog-ignore-db=information_schema #设置需要复制的数据库 binlog-do-db=需要复制的主数据库名字 #设置logbin格式 binlog_format=STATEMENT # 在作为从数据库的时候,有写入操作也要更新二进制日志文件 log-slave-updates #指自增字段的起始值,其默认值是1,取值范围是1 .. 65535 auto-increment-increment=2 #指字段一次递增多少,他的取值范围是1 .. 65535 auto-increment-offset=2
3、修改slave1配置文件
[mysqld] #从服务器唯一ID server-id=2 #启用中继日志 relay-log=mysql-relay
4、修改slave2配置文件
[mysqld] #从服务器唯一ID server-id=4 #启用中继日志 relay-log=mysql-relay
双主双从重启服务
systemctl restart mysql
配置数据库
1、分别在两个主库中执行创建从库连接账号命令
GRANT replication SLAVE ON *.* TO 'slave' @'%' IDENTIFIED BY '123456';
2、查看两个主库的master状态
mysql> show master status;
两个从库连接到主库
1、slave1连接到master1
mysql> change master to master_host='192.168.66.100', master_user='slave', master_port=3350, master_password='123456', master_log_file='mysql-bin.000001', master_log_pos=438;
参数:
- master_host:这里的ip就是主机mysql所在服务器对应的ip
- master_user:就是在第一步配置的账号
- master_port:mysql的端口
- master_password:配置的密码
- master_log_file:file参数
- master_log_pos:Position参数
2、slave2连接到master2
mysql> change master to master_host='192.168.66.100', master_user='slave', master_port=3370, master_password='123456', master_log_file='mysql-bin.000001', master_log_pos=438;
两个从库启动复制功能
mysql>start slave;
查看连接状态
mysql>show slave status \G;
两个主库再互相成为对方的从库
# 在master1上执行 mysql> change master to master_host='192.168.66.100', master_user='slave', master_port=3370, master_password='123456', master_log_file='mysql-bin.000001', master_log_pos=438; #开启主从复制 mysql> start slave; #查看链接信息 show slave status \G; #在master2上执行 mysql> change master to master_host='192.168.66.100', master_user='slave', master_port=3350, master_password='123456', master_log_file='mysql-bin.000001', master_log_pos=438; #开启主从复制 mysql> start slave; #查看连接信息 show slave status \G;
双主双从配置MyCat
vim schema.xml
<dataNode name="db_node" dataHost="db_host" database="test" /> <dataHost name="db_host" maxCon="1000" minCon="10" balance="1" 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.140.128:3306" user="root" password="123456"> <!-- can have multi read hosts --> <readHost host="hostS1" url="192.168.140.127:3306" user="root" password="123456" /> </writeHost> <writeHost host="hostM2" url="192.168.140.126:3306" user="root" password="123456"> <!-- can have multi read hosts --> <readHost host="hostS2" url="192.168.140.125:3306" user="root" password="123456" /> </writeHost> </dataHost>
重新启动mycat
mycat restart
注意:
- writeType="0":所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个riteHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties.
- writeType="1":所有写操作都随机的发送到配置的 writeHost,1.5 以后废弃不推荐。
- switchType="-1" :表示不自动切换 mysql 实例
- switchType="1" :默认值,自动切换