目录
MyCat
Mycat原理
Mycat和MySQL的区别
Mycat的常用配置文件
?Mycat日志
mycat 实现读写分离实验过程:
1.环境准备
2.初始化环境
主从复制
mycat服务器配置
(192.168.159.104)
安装Java
安装mycat
mycat 配置
/apps/mycat/conf/server.xml
修改 mycat 配置文件
master服务器上授权
客户机连接mycat
测试读写分离
MyCat
MyCat是目前最流行的分布式数据库中间插件,是一个开源的分布式数据库系统,是一个实现了MySQL协议的服务器,前端用户可以把它看作是一个数据库代理,用MySQL客户端工具和命令行访问,而其后端可以用MySQL原生协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。
MyCat发展到目前的版本,已经不是一个单纯的MySQL代理了,它的后端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储,未来还会支持更多类型的存储。而在最终用户看来,无论是那种存储方式,在MyCat里,都是一个传统的数据库表,支持标准的SQL语句进行数据的操作,这样一来,对前端业务系统来说,可以大幅降低开发难度,提升开发速度。
Mycat原理
Mycat的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
?上述图片里,应用程序不再直接访问数据库,而是访问Mycat,由Mycat与数据库交互,数据库数据返回给Mycat,Mycat再返回给应用程序。三个Database才是真正的数据库,又称为三个节点,也称为三个分片。
Mycat和MySQL的区别
我们可以把上层看作是对下层的抽象,例如操作系统是对各类计算机硬件的抽象。那么我们什么时候需要抽象?假如只有一种硬件的时候,我们需要开发一个操作系统吗?再比如一个项目只需要一个人完成的时候不需要leader,但是当需要几十人完成时,就应该有一个管理者,发挥沟通协调等作用,而这个管理者对于他的上层来说就是对项目组的抽象。同样的,当我们的应用只需要一台数据库服务器的时候我们并不需要Mycat,而如果你需要分库甚至分表,这时候应用要面对很多个数据库的时候,这个时候就需要对数据库层做一个抽象,来管理这些数据库,而最上面的应用只需要面对一个数据库层的抽象或者说数据库中间件就好了,这就是Mycat的核心作用。所以可以这样理解:数据库是对底层存储文件的抽象,而Mycat是对数据库的抽象。
Mycat的常用配置文件
Mycat的配置文件都在conf目录里面,这里介绍几个常用的文件:
-
server.xml :Mycat软件本身相关的配置文件,设置账号、参数等 -
schema.xml:Mycat对应的物理数据库和数据库表的配置,读写分离、高可用、分布式策略定制、节点控制 -
rule.xml:Mycat分片(分库分表)规则配置文件,记录分片规则列表、使用方法等
?Mycat日志
Mycat的日志文件都在logs目录里面
-
wrapper.log :mycat启动日志 -
mycat.log :mycat详细工作日志
mycat 实现读写分离实验过程:
1.环境准备
mycat服务器上不能装mysql
master服务器 | 192.168.159.101 |
---|
slave1服务器 | 192.168.159.102 | mycat服务器 | 192.168.159.104 | 客户机 | 192.168.159.105 |
2.初始化环境
#每台服务器上都初始化,关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
主从复制
主mysql服务器配置(192.168.159.101)
修改配置文件
[root@localhost ~]#vim /etc/my.cnf
#服务器id不能和从服务器一样
server-id = 1
#开启二进制日志
log-bin=master-bin
#二进制日志格式
binlog_format=MIXED
#开启从服务器同步
log-slave-updates=true
server-id = 1
log-bin=master-bin
binlog_format=MIXED
log-slave-updates=true
重启服务
[root@localhost ~]#systemctl restart mysqld
进入数据库授权,查看二进制文件及节点号
[root@localhost ~]#mysql -uroot -p
#建立一个myslave用户,并且允许192.168.59.%这个网段的地址来登录,密码是123456,一会儿要在slave上使用这个账号
grant replication slave on *.* to 'myslave'@'192.168.159.%' identified by '123456';
#刷新一下
flush privileges;
#查看主服务器的bin-log日志文件名称和position点
show master status;
从mysql服务器配置(192.168.159.102)
修改配置文件
[root@localhost ~]#vim /etc/my.cnf
#修改,服务器id不能和主服务器一样
server-id = 2
#添加,开启中继日志,从主服务器上同步日志文件记录到本地
relay-log=relay-log-bin
#添加,定义中继日志文件的位置和名称,一般和relay-log在同一目录
relay-log-index=slave-relay-bin.index
server-id = 2
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
重启服务
[root@localhost ~]#systemctl restart mysqld
进入数据库,设置连接主库信息,并开启slave服务
[root@localhost ~]#mysql -uroot -p
#不知道连接主库信息格式可以用help change master to 查看,下面的master_log_file是在配置Master的时候的File字段, master_log_pos是在配置Master的Position 字段。一定要一一对应
change master to
master_host='192.168.159.101',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=604;
#开启slave
start slave;
#查看从库状态信息,Slave_IO_Running和Slave_SQL_Running状态必须是yes
show slave status \G;
?验证主从复制
#在主服务器上下载hellodb库文件,source后加绝对路径
[root@localhost ~]#mysql -uroot -p
#下载hellodb库文件
source /opt/hellodb.sql
show databases;
#在从库中查看库文件hellodb是否已经同步
show databases;
mycat服务器配置
(192.168.159.104)
安装Java
#yum安装java
[root@localhost ~]#yum install java -y
#确认安装成功
[root@localhost ~]#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)
安装mycat
切换至opt目录,下载mycat安装包
[root@localhost ~]#cd /opt
[root@localhost ~]#wget http://dl.mycat.org.cn/1.6.7.6/20210303094759/Mycat-server-1.6.7.6-release-20210303094759-linux.tar.gz
创建/apps文件夹,并解压mycat包至/apps下
[root@localhost ~]#mkdir /apps
[root@localhost ~]#tar zxvf Mycat-server-1.6.7.6-release-20210303094759-linux.tar.gz -C /apps/
设置变量环境
[root@localhost ~]#echo 'PATH=/apps/mycat/bin:$PATH' > /etc/profile.d/mycat.sh
[root@localhost ~]#source /etc/profile.d/mycat.sh
启动mycat,查看日志文件,最后可以看到启动成功
[root@localhost ~]#mycat start
#注意内存小于2G 起不来
Starting Mycat-server...
[root@localhost ~]#tail -f /apps/mycat/logs/wrapper.log
#启动成功日志末尾会出现successfully
mycat 配置
/apps/mycat/conf/server.xml
[root@localhost ~]#vim /apps/mycat/conf/server.xml
#去掉44行行注释,对应的在51行行末注释,删除50行行末注释,5 * 60 * 1000L; //连接空> 闲检查
#修改45行端口号为3306
45 <property name="serverPort">3306</property>
#配置Mycat的连接信息(账号密码),在110 和111行,修改
?
?
110 <user name="root" defaultAccount="true">
111 <property name="password">123456</property>
112 <property name="schemas">TESTDB</property>
113 <property name="defaultSchema">TESTDB</property>
116 <!-- 表级 DML 权限设置 -->
117 <!--
118 <privileges check="false">
119 <schema name="TESTDB" dml="0110" >
120 <table name="tb01" dml="0000"></table>
121 <table name="tb02" dml="1111"></table>
122 </schema>
123 </privileges>
124 -->
127 <user name="user">
128 <property name="password">user</property>
129 <property name="schemas">TESTDB</property>
130 <property name="readOnly">true</property>
131 <property name="defaultSchema">TESTDB</property>
user 用户配置节点
name 逻辑用户名,客户端登录MyCAT的用户名,也就是客户端用来连接Mycat的用户名。
password 客户端登录MyCAT的密码
schemas 数据库名,这里会和schema.xml中的配置关联,可配置多个,多个用逗号分开,例如:db1,db2
privileges 配置用户针对表的增删改查的权限
readOnly mycat 逻辑库所具有的权限。true为只读,false为读写都有,默认为false
##注意
1.#server.xml文件里登录mycat的用户名和密码可以任意定义,这个账号和密码是为客户机登录mycat时使用的账号信息
2.#逻辑库名(如上面的TESTDB,也就是登录mycat后显示的库名,切换这个库之后,显示的就是代理的真实mysql数据库的表)要在schema.xml里面也定义,否则会导致mycat服务启动失败!这里只定义了一个标签,所以把多余的都注释了。如果定义多个标签,即设置多个连接mycat的用户名和密码,那么就需要在schema.xml文件中定义多个对应的库!
修改 mycat 配置文件
vim??/apps/mycat/conf/schema.xml
schema.xml是最主要的配置项,此文件关联mysql读写分离策略,读写分离、分库分表策略、分片节点都是在此文件中配置的.MyCat作为中间件,它只是一个代理,本身并不进行数据存储,需要连接后端的MySQL物理服务器,此文件就是用来连接MySQL服务器的。
[root@localhost ~]#vim /apps/mycat/conf/schema.xml
#删除所有内容,重新写入以下
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
#schema标签:数据库设置,此数据库为逻辑数据库,name与server.xml中schema对应。
#name:逻辑数据库名,与server.xml中的schema对应;
#checkSQLschema: 数据库前缀相关设置,这里为false;
#sqlMaxLimit: select时默认的limit,避免查询全表,否则可能会遇到查询量特别大的情况造成卡 死;
#dataNode:表存储到哪些节点,多个节点用逗号分隔。节点为下文dataNode设置的name
</schema>
<dataNode name="dn1" dataHost="localhost1" database="hellodb" />
#dataNode标签: 定义mycat中的数据节点,也是通常说的数据分片,也就是分库相关配置
#name: 定义数据节点的名字,与table中dataNode对应
#datahost: 物理数据库名,与datahost中name对应,该属性用于定义该分片属于哪个数据库实例
#database: 物理数据库中数据库名,该属性用于定义该分片属性哪个具体数据库实例上的具体库
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
#dataHost标签: 物理数据库,真正存储数据的数据库
#name: 物理数据库名,与dataNode中dataHost对应
#maxCon属性指定每个读写实例连接池的最大连接。也就是说,标签内嵌套的writeHost、readHost标 签都会使用这个属性的值来实例化出连接池的最大连接数
#minCon属性指定每个读写实例连接池的最小连接,初始化连接池的大小
#balance: 均衡负载的方式
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
#writeType: 写入方式
#dbType: 数据库类型
#dbDriver指定连接后端数据库使用的 Driver,目前可选的值有 native 和 JDBC。用 native 的话,因为这个值执行的是二进制的 mysql 协议,所以可以使用 mysql 和maridb。其他类型的数据库则需要使用 JDBC 驱动来支持。
#switchType: “-1” 表示不自动切换; “1” 默认值,自动切换; “2” 基于 MySQL主从同步的状态决定是否切换心跳语句为 show slave status; “3” 基于 MySQL galary cluster 的切换机制(适合集群)(1.4.1)心跳语句为 show status like ‘wsrep%’.
<heartbeat>select user()</heartbeat>
#heartbeat: 心跳检测语句,注意语句结尾的分号要加
<writeHost host="host1" url="192.168.159.101:3306" user="root" password="123456">
#host:用于标识不同实例,一般 writeHost 我们使用*M1,readHost 我们用*S1。
#url:后端实例连接地址。Native:地址:端口 JDBC:jdbc的url
#user:后端存储实例需要的用户名字
#password:后端存储实例需要的密码
<readHost host="host2" url="192.168.159.102:3306" user="root" password="123456"/>
</writeHost>
</dataHost>
</mycat:schema>
#schema.xml文件中有三点需要注意:balance="1",writeType="0" ,switchType="1"
#schema.xml中的balance的取值决定了负载均衡对非事务内的读操作的处理。balance 属性负载均衡类型,目前的取值有 4 种:
##balance="0":不开启读写分离机制,所有读操作都发送到当前可用的writeHost上,即读请求仅 发送到writeHost上
##balance="1":一般用此模式,读请求随机分发到当前writeHost对应的readHost和standby的writeHost上。即全部的readHost与stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1 ->S1 , M2->S2,并且 M1 与 M2 互为主备),正常情况下, M2,S1, S2 都参与 select 语句的负载均衡
##balance="2":读请求随机分发到当前dataHost内所有的writeHost和readHost上。即所有读操作都随机的在writeHost、 readhost 上分发
##balance="3":读请求随机分发到当前writeHost对应的readHost上。即所有读请求随机的分发wiriterHost 对应的 readhost 执行, writerHost 不负担读压力,注意 balance=3 只在 1.4 及其以后版本有,1.3 没有
###writeHost和readHost标签,这两个标签都指定后端数据库的相关配置给mycat,用于实例化后端连接池。唯一不同的是:writeHost指定写实例、readHost指定读实例,组着这些读写实例来满足系统的要求。在一个dataHost内可以定义多个writeHost和eadHost。但是,如果writeHost指定的后端数据库宕机,那么这个writeHost绑定的所有readHost都将不可用。另一方面,由于这个writeHost宕机系统会自动的检测到,并切换到备用的writeHost上去
#PS:Mycat主从分离只是在读的时候做了处理,写入数据的时候,只会写入到writehost,需要通过mycat的主从复制将数据复制到readhost
?
master服务器上授权
[root@localhost ~]#mysql -uroot -p
#授权
GRANT ALL ON *.* TO 'root'@'192.168.159.%' IDENTIFIED BY '123456';
#查看创建成功
use mysql;
select user,host from user;
?
客户机连接mycat
在mycat服务器上,重启mycat服务,查看启动日志,文末出现successfully
[root@localhost ~]#mycat restart
[root@localhost ~]#tail -f /apps/mycat/logs/wrapper.log
查看3306端口,可以监听到主从服务器(192.168.159.101、192.168.159.102)
[root@localhost ~]# ss -antp|grep 3306
在客户机上登录mycat,这时可以不加端口直接进入数据库了
[root@localhost ~]#mysql -uroot -p123456 -h 192.168.159.101
#看是否能查到表
show databases;
use TESTDB ;
show tables;
查看当前的查询来自哪台服务器,可以看到查询功能来自id为2的从服务器
select @@server_id;
?
?
?
测试读写分离
在主从服务器上都打开通用日志
[root@localhost ~]#mysql -uroot -p
#打开通用日志
set global general_log=1;
#查看通用查询日志是否开启
show variables like 'general%';
set global general_log=1;
show variables like 'general%';
在主从服务器上实时查看通用日志
[root@localhost ~]#tail -f /usr/local/mysql/data/localhost.log
在客户机上的表中插入数据,并查看主从服务器实时日志,可以看到只有主服务器上有日志变化显示
[root@localhost ~]#mysql -uroot -p123456 -h 192.168.159.101
insert into teachers values(10,'Xiao Ming',46,'F');
?
在客户端做读写动作 在主 从服务器查看?
验证实验结果?
?
|