一、简介
java语言编写的MySQL数据库网络协议的开源中间件。活跃的、性能好的开源数据库中间件。基于阿里开源数据库中间件Coobar框架来编写的,站在巨人肩膀,性能良好。基于心跳的自动故障切换,支持读写分离。支持数据的多片(横向分表)自动路由与聚合,支持sum,count,max等常用的聚合函数,支持跨库分页。支持全局序列号,解决分布式下的主键生成问题。
二、原理
Mycat 的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的 SQL 语句,首先对 SQL 语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此 SQL 发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
基于过滤,拦截的技术或者框架 :Filter Springmvc-Intercepter Gateway Zuul 等
三、读写分离概念和好处
3.1 概念:
把读(select)和写(insert,update,delete)分别在不同的数据库上执行,一般来读多写少。
3.2 好处:
一般项目在线运行时,都是读多写少(逛淘宝,逛京东。。。),写都不会是数据库的瓶颈,一般几毫秒可能就完成了。但是读操作往往会多表联查,联查表中如果说有数据量大的表,查询速度会很慢,成为数据库瓶颈,使用读写分离,让读进行负载均衡,让多台mysql参与读操作,来缓解瓶颈,提高项目响应速度。
四、读写分离配置及测试
4.1 基于base克隆mycat服务器,安装mycat,配置环境变量
vim /etc/sysconfig/network-scripts/ifcfg-ens33
vim /etc/hostname
使用xshell连接
检车当前环境是否有jdk:
java -version
echo $JAVA_HOME
上传压缩包,解压:
tar -xzvf /usr/local/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/
配置环境变量:
vim /etc/profile
修改内容:
export MYCAT_HOME=/usr/mycat
export PATH=$PATH:$JAVA_HOME/bin:$MYCAT_HOME/bin
让配置生效:
source /etc/profile
测试:
echo $MYCAT_HOME
4.2 配置server.xml文件
4.2.1 作用:
server.xml 几乎保存了所有 mycat 需要的系统配置信息(全局配置)。server.xml 中的标签本就不多,这个标签主要用于定义登录 mycat 的用户和权限。
4.2.3 配置:
vim /usr/mycat/conf/server.xml
:32
<!--mycat服务端口号-->
<property name="serverPort">8066</property>
:84
<property name="schemas">caicai</property>
:99
<property name="schemas">caicai</property>
1
4.2.4 配置schema.xml文件
Schema.xml 作为 MyCat 中重要的配置文件之一,管理着 MyCat 的逻辑库、表、分片规则、DataNode 以 及 DataSource。弄懂这些配置,是正确使用 MyCat 的前提。
schema 标签用于定义 MyCat 实例中的逻辑库,MyCat 可以有多个逻辑库,每个逻辑库都有自己的相关配置。可以使用 schema 标签来划分这些不同的逻辑库。
dataNode 标签定义了 MyCat 中的数据节点,也就是我们通常说所的数据分片。一个 dataNode 标签就是一个独立的数据分片。
DataHost作为 Schema.xml 中最后的一个标签,该标签在 mycat 逻辑库中也是作为最底层的标签存在,直接定义了具 体的数据库实例、读写分离配置和心跳语句。
DataHost的 balance属性:
负载均衡类型,目前的取值有 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 不负担读压力,注意 balance=3 只在 1.4 及其以后版本有,1.3 没有。
writeType 属性:
1. writeType="0", 所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个 writeHost,重新启动后以切换后的为准,切换记录在配置文件中:dnindex.properties .
2. writeType="1",所有写操作都随机的发送到配置的 writeHost,1.5 以后废弃不推荐。s
switchType 属性:
-1 表示不自动切换
1 默认值,自动切换
2 基于 MySQL 主从同步的状态决定是否切换,心跳语句为 show slave status
3 基于 MySQL galary cluster 的切换机制(适合集群)(1.4.1)
心跳语句为 show status like ‘wsrep%’
vim /usr/mycat/conf/schema.xml
:6 27dd
:10 2dd
:23 2dd
:18 5yy
:22 p
逻辑数据库和上文配置的一直,真实数据库和Navicat里面的数据库一致
4.2.5 配置日志文件
为了方便查看后面执行的语句在哪台服务器上执行,配置日志文件打印语句执行情况。
vim /usr/mycat/conf/log4j2.xml
:25 info -> debug
4.2.6读写分离测试
先要启动4台mysql并且启动mysqld服务,创建数据库db_mytest,在该库中创建表tb_student。
启动mycat
mycat start
测试是否启动成功:
jps
使用navicat连接mycattest:
4.2.7 执行操作:
测试读写分离
执行写操作
insert into tb_student(id,name,age) values(1,'aa',20);
insert into tb_student(id,name,age) values(2,'bb',20);
insert into tb_student(id,name,age) values(3,'cc',20);
update tb_student set name = 'bbbb' where id=2;
delete from tb_student where id=3;
# 执行读操作 查询操作
select * from tb_student;
查看日志,查看上面执行语句,在哪台服务器执行:
写操作:
添加 : grep insert /usr/mycat/logs/wrapper.log
修改: grep update /usr/mycat/logs/wrapper.log
删除: grep delete /usr/mycat/logs/wrapper.log
读操作:grep select /usr/mycat/logs/wrapper.log
结论:M1(mysql1)写 M2(mysql2),S1(mysql3),S2(mysql4)都是读,读负载均衡
4.2.8 自动容错测试
让Mysql1宕机:
service mysqld stop
-- M1宕机 继续测试
写操作
insert into tb_student(id,name,age) values(4,'dd',20);
insert into tb_student(id,name,age) values(5,'ee',20);
insert into tb_student(id,name,age) values(8,'gg',20);
update tb_student set name = 'gggg' where id=8;
delete from tb_student where id=4;
读操作
select * from tb_student;
让M1恢复
insert into tb_student(id,name,age) values(7,'gg',20);
update tb_student set name = 'gggg' where id=7;
执行读操作 查询操作
select * from tb_student;
结论: M1宕机 切换到M2, M2写,S2读 S1不参与读。
M1恢复正常 M2写 M1,S1,S2负载均衡读。