文章目录
- 18.1 MySQL 读写分离概述
- 18.1.1 工作原理
- 18.1.2 为什么要读写分离
- 18.1.3 实现方式
- 18.2 什么是 MyCat
- 18.3 MyCat 安装与配置
- 1. 下载与解压
- 2. 创建用户并修改权限
- 3. 目录说明
- 4. Java 环境要求
- 18.4 MyCat 启动与配置
- 1. 配置环境变量
- 2. 配置 hosts(多节点集群)
- 3. 配置 Mycat
- 3.1 配置 server
- 3.2 schema 配置
- 3.2.1 首先 备份
- 3.2.2 更改配置
- 4. 启动 MyCat
- 在这里插入图片描述
- 18.5 配置 MySQL 主从
- 1. 安装 MySQL 5.7
- 2. 配置主库(master)
- 3. 配置从库(slave)
- 4. 测试读写分离
- 总结
18.1 MySQL 读写分离概述
18.1.1 工作原理
- 主库负责写操作:
INSERT
、UPDATE
、DELETE
- 从库负责读操作:
SELECT
- 主从复制保证从库数据与主库同步
- 数据内部交换过程:主库写入 → 二进制日志 → 从库同步
18.1.2 为什么要读写分离
- 单台服务器性能瓶颈,需分担负载
- 主从分工,缓解锁争用(X锁和S锁)
- 从库可使用 MyISAM,提高查询性能
- 增加冗余,提高可用性
18.1.3 实现方式
- 应用程序层实现
- 优点:易部署,对访问压力中等的系统性能良好
- 缺点:代码耦合、难以支持高级功能、大型系统不适用
- 中间件层实现
- 优点:架构灵活、透明化分库分表、可做 failover 和监控
- 常用中间件:
- Cobar:阿里B2B的分布式系统,已停更
- MyCat:Cobar二次开发,社区活跃
- OneProxy:商业收费,高并发稳定
- Vitess:YouTube使用,架构复杂
- Kingshard、Atlas、MaxScale、MySQL Router等
18.2 什么是 MyCat
- 开源企业级数据库中间件
- 支持事务、ACID
- 替代 MySQL 集群或 Oracle 集群
- 融合内存缓存、NoSQL、大数据技术(HDFS)
- 可视为企业级数据库中间件,实现分库分表、读写分离
18.3 MyCat 安装与配置
1. 下载与解压
#官方网站
http://www.mycat.org.cn/
#github
https://github.com/MyCATApache/Mycat-download下载地址
wget https://github.com/MyCATApache/Mycat-download/blob/master/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gztar -xf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/local/
cd /usr/local/mycat
2. 创建用户并修改权限
useradd mycat
passwd mycat
chown -R mycat.mycat /usr/local/mycat
3. 目录说明
bin/
:可执行文件和 shell 脚本conf/
:配置文件server.xml
:服务器参数、用户授权schema.xml
:逻辑库和数据分片配置rule.xml
:分片规则
lib/
:依赖 JAR 文件logs/
:日志文件(配置在log4j.xml
)
4. Java 环境要求
- JDK 1.7 及以上(可做可不做)
tar xf jdk-8u191-linux-x64.tar.gz -C /usr/java/
vim /etc/profile.d/java.sh
export JAVA_HOME=/usr/java/jdk1.8.0_191
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=$JAVA_HOME/jre/lib/ext:$JAVA_HOME/lib/tools.jar
source /etc/profile.d/java.sh
java -version
18.4 MyCat 启动与配置
1. 配置环境变量
vim /etc/profile.d/mycat.sh
#!/bin/bash
export MYCAT_HOME=/usr/local/mycat
export PATH=$MYCAT_HOME/bin:$PATH
source /etc/profile.d/mycat.sh
2. 配置 hosts(多节点集群)
这里使用的是上一篇博文的主从mysql
192.168.10.14 slave1
192.168.10.15 slave2
192.168.10.16 master
3. 配置 Mycat
cp /usr/local/mycat/conf/server.xml /usr/local/mycat/conf/server.xml.bakvim /usr/local/mycat/conf/server.xml
3.1 配置 server
后边标1的都是需要重点关注需要更改,ha为自己的逻辑库,可以自拟
<user name="mycat"> 1<property name="password">123456</property> 1<property name="schemas">ha</property> 1<!-- 表级 DML 权限设置 --><!-- <privileges check="false"><schema name="TESTDB" dml="0110" ><table name="tb01" dml="0000"></table><table name="tb02" dml="1111"></table></schema></privileges> --></user><user name="user"><property name="password">user</property><property name="schemas">ha</property> 1<property name="readOnly">true</property></user>
3.2 schema 配置
3.2.1 首先 备份
cp /usr/local/mycat/conf/schema.xml /usr/local/mycat/conf/schema.xml.bak
3.2.2 更改配置
#直接复制
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">
<schema name="ha" checkSQLschema="false" sqlMaxLimit="100" dataNode='dn1'>
</schema>
<dataNode name="dn1" dataHost="dthost" database="ha"/>
<dataHost name="dthost" maxCon="500" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType=" -1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="master" url="192.168.10.16:3306" user="mycat" password="123456">
</writeHost>
<writeHost host="slave1" url="192.168.10.14:3306" user="mycat" password="123456" />
</dataHost>
</mycat:schema>==============================================================================
使用这个即可,直接删除复制粘贴<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/"><!-- 定义逻辑库 schema --><schema name="ha" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"></schema><!-- 数据节点 --><dataNode name="dn1" dataHost="dthost" database="ha"/><!-- 数据主机组 --><dataHost name="dthost" maxCon="500" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100"><!-- 心跳语句 --><heartbeat>select 1</heartbeat><!-- 主库 (写) --><writeHost host="master" url="192.168.10.16:3306" user="mycat" password="123456"><!-- 从库 (读) --><readHost host="slave1" url="192.168.10.14:3306" user="mycat" password="123456"/><readHost host="slave2" url="192.168.10.15:3306" user="mycat" password="123456"/></writeHost></dataHost>
</mycat:schema>
① 重要参数说明:
上文中的两个ha不是一个东西,第一个ha是自己拟定的逻辑库名,后面那个才是mysql数据库集群中的真实数据库名。
-
balance
:读负载均衡方式(0-3)负载均衡类型,目前的取值有 4 种: 1.balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上;2.balance="1",全部的 readHost 与stand by writeHost 参与 select 语句的负载均衡,简单的说,当 双主双从模式(M1->S1,M2->S2,并且 M1 与 M2 互为主备),正常情况下,M2、S1、S2 都参与 select 语句的负载均衡;3.balance="2",所有读操作都随机的在 writeHost、readhost 上分发;4.balance="3",所有读请求随机的分发到 wiriterHost 对应的readhost 执行,writerHost 不负担读压力。注意:writerHost 不负担读压writeType
-
switchType
:写节点切换策略(-1表示不自动切换)switchType 指的是切换的模式,目前的取值也有 4 种:1.switchType='-1' 表示不自动切换;2.switchType='1' 默认值,表示自动切换;3.switchType='2' 基于MySQL 主从同步的状态决定是否切换,心跳语句为 show slave status;4.switchType='3'基于 MySQL galary cluster 的切换机制(适合集群)(1.4.1),心跳语句为 show status like 'wsrep%'。
-
writeType
:写节点策略(0表示主写,挂了切换到备)1、writeType=”0”, 所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个 writeHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties . 2、writeType=”1”,所有写操作都随机的发送到配置的 writeHost,1.5 以后废弃不推荐。默认 0 就好了!
② 参数说明:
-
Mycat schema 配置的 XML 根节点
<mycat:schema xmlns:mycat="http://org.opencloudb/">
-
schema 节点
<schema name="ha" checkSQLschema="false" sqlMaxLimit="100" dataNode='dn1'> </schema># name="ha":定义 schema 名称为 ha,客户端通过 use ha 来访问。 ## checkSQLschema="false":关闭 SQL schema 检查,加快解析。 ### sqlMaxLimit="100":单条 SQL 返回最大 100 行。 #### dataNode='dn1':指定使用的数据节点为 dn1。
-
dataNode 节点
<dataNode name="dn1" dataHost="dthost" database="ha"/>#name="dn1":定义数据节点的名字,这个名字需要是唯一的。##dataHost="dthost":绑定到名为 dthost 的 dataHost。 (该属性用于定义该分片属于哪个数据库实例)###database="ha":访问的物理数据库名为 ha。 (该属性用于定义该分片属性哪个具体数据库实例上的具体库)
-
dataHost 节点
<dataHost name="dthost" maxCon="500" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100">maxCon / minCon:连接池最大/最小连接数。balance="1":负载均衡策略,1 表示轮询。writeType="0":写策略,只写到第一个可用节点。dbType="mysql":数据库类型 MySQL。dbDriver="native":使用原生驱动。switchType="-1":切换策略,-1 表示自动。slaveThreshold="100":从库延迟阈值(行数或毫秒,取决于版本)
-
心跳检测
<heartbeat>select user()</heartbeat> #用来检测数据库连接是否活跃
-
writeHost 节点
<writeHost host="slave1" url="192.168.10.14:3306" user="mycat" password="123456"/> <writeHost host="slave2" url="192.168.10.15:3306" user="mycat" password="123456"/>配置两个写节点(主库)。writeType="0" 表示只写第一个 writeHost(slave1)。第二个 writeHost 在此配置下不会被写入使用。
数据流向 schema → dataNode → dataHost → writeHost 的结构,
4. 启动 MyCat
cd /usr/local/mycat/bin
./mycat start
cat /usr/local/mycat/logs/wrapper.log
18.5 配置 MySQL 主从
1. 安装 MySQL 5.7
mysql -umycat -p123456 -h127.0.0.1 -P8066
2. 配置主库(master)
# /etc/my.cnf
validate-password=OFF
server-id=1
log-bin=mysql-bin-master
binlog-do-db=ha
binlog-ignore-db=mysql
配完要重启数据库,但是重启会导致主从数据有问题
mysql> create database ha;
mysql> use ha;
mysql> create table test(id int, name varchar(20));
mysql> insert into test values(1,'man');
mysql> grant all privileges on *.* to 'mycat'@'%' identified by '123456';
mysql> flush privileges;================================================
简易版 可直接使用这个mysql> grant all privileges on *.* to 'mycat'@'%' identified by '123456';
mysql> flush privileges;
mysql> create database ha;
mysql> use ha;
mysql> create table test(id int, name varchar(20));
3. 配置从库(slave)
# /etc/my.cnf
server-id=2
validate-password=OFF
mysql> grant all on *.* to mycat@'%' identified by '123456';
mysql> stop slave;
mysql> change master to master_host='192.168.10.14', master_user='slave', master_password='123456';
mysql> start slave;
mysql> show slave status\G# /etc/my.cnf
server-id=3
validate-password=OFF
mysql> grant all on *.* to mycat@'%' identified by '123456';
mysql> stop slave;
mysql> change master to master_host='192.168.10.15', master_user='slave', master_password='123456';
mysql> start slave;
mysql> show slave status\G之前配了主从就不用配主从了!只需要grant加权限就行了!!!只需要
mysql> grant all privileges on *.* to 'mycat'@'%' identified by '123456';
mysql> flush privileges;
4. 测试读写分离
#先安装数据库
yum install -y mariadb-server mariadb
systemctl start mariadb.service
在客户端服务器上测试
mysql -u mycat -p123456 -h 192.168.10.80 -P8066
//通过mycat服务器代理访问mysql ,在通过客户端连接mysql后写入的数据只有主服务会记录,然后同步给从--从服务器在主服务器上:
create database ha;
use ha;
create table test (id int(10),name varchar(10),address varchar(20));在两台从服务器上:
stop slave; #关闭同步
use ha;
//在slave1上:
insert into test values('1','zhangsan','this_is_slave1');//在slave2上:
insert into test values('2','lisi','this_is_slave2');//在主服务器上:
insert into test values('3','wangwu','this_is_master');//在客户端服务器上:
use ha;(这里是逻辑库,然后逻辑库区调用的真实库ha)
select * from test; //客户端会分别向slave1和slave2读取数据,显示的只有在两个从服务器上添加的数据,没有在主服务器上添加的数据
重复两遍查询可以看到slave1和slave2进行轮询查询,没有master出现,符合读写分离
insert into test values('4','qianqi','this_is_client'); //只有主服务器上有此数据//在两个从服务器上执行 start slave; 即可实现同步在主服务器上添加的数据
start slave;
select * from test; 然后再进行查询,发现是134,234进行轮询,实验成功
如果只能查到134或者234,检查四个虚拟机的防火墙和selinux
这里按理说应该使用第五台虚拟机当客户端进行测试,但是这里用的是mycat服务端兼客户端,所以ip直接写的80即本机ip,本质上就是客户端—》mycat-----》mysql集群,mycat之所以可以使用mysql命令是因为兼容协议,可以吧自己伪装成mysql,然后查询进入mycat,由mycat进行调度。
总结
mycat配置的核心就是server.xml和schema.xml,server中是配置的mycat这个服务的全局配置,也就是说客户端使用登陆的mycat用户名和密码(不是数据库中的用户名和密码!),schema中的是对逻辑库和物理库的映射等配置,在那里面是真实对应的数据库用户和密码。