mysql基于mycat实现读写分离

mycat数据库代理中间件

Mycat是一个开源的分布式数据库系统,是一个实现了MySQL协议的服务器,前端用户可以把它看作是一个数据库代理(类似于Mysql Proxy),用MySQL客户端工具和命令行访问,而其后端可以用MySQL原生协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里
后端可以支持MySQL、SQLServer、Oracle、DB2、PostgreSQL等主流数据库,也支持MongoDB这种NoSQL方式的存储

mycat特点:

  • 支持SQL92标准
  • 遵守MySQL 原生协议,跨语言,跨平台,跨数据库的通用中间件代理
  • 基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster集群
  • 支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster
  • 基于Nio实现,有效管理线程,高并发问题
  • 支持数据的多片自动路由与聚合,支持sum,count,max等常用的聚合函数,支持跨库分页
  • 支持单库内部任意join,支持跨库2表join,甚至基于caltlet的多表join
  • 支持通过全局表,ER关系的分片策略,实现了高效的多表join查询
  • 支持多租户方案
  • 支持分布式事务(弱xa)
  • 支持全局序列号,解决分布式下的主键生成问题
  • 分片规则丰富,插件化开发,易于扩展
  • 强大的web,命令行监控
  • 支持前端作为mysq通用代理,后端JDBC方式支持Oracle、DB2、SQL Server 、 mongodb
  • 支持密码加密
  • 支持服务降级
  • 支持IP白名单
  • 支持SQL黑名单、sql注入攻击拦截
  • 支持分表(1.6)
  • 集群基于ZooKeeper管理,在线升级,扩容,智能优化,大数据处理(2.0开发版)

mycat原理:

请求到达时,把sql语句拦截,首先对SQL语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户

mycat使用场景:

Mycat适用场景

  • 单纯的读写分离,此时配置最为简单,支持读写分离,主从切换
  • 分表分库,对于超过1000万的表进行分片,最大支持1000亿的单表分片
  • 多租户应用,每个应用一个库,但应用程序只连接Mycat,从而不改造程序本身,实现多租户化
  • 报表系统,借助于Mycat的分表能力,处理大规模报表的统计
  • 替代Hbase,分析大数据
  • 作为海量数据实时查询的一种简单有效方案,比如100亿条频繁查询的记录需要在3秒内查询出来结果,除了基于主键的查询,还可能存在范围查询或其他属性查询,此时Mycat可能是最简单有效的选择
  • Mycat长期路线图
  • 强化分布式数据库中间件的方面的功能,使之具备丰富的插件、强大的数据库智能优化功能、全面的系统监控能力、以及方便的数据运维工具,实现在线数据扩容、迁移等高级功能
  • 进一步挺进大数据计算领域,深度结合Spark Stream和Storm等分布式实时流引擎,能够完成快速的巨表关联、排序、分组聚合等 OLAP方向的能力,并集成一些热门常用的实时分析算法,让工程师以及DBA们更容易用Mycat实现一些高级数据分析处理功能

Mycat不适合场景:

  • 设计使用Mycat时有非分片字段查询,请慎重使用Mycat,可以考虑放弃!
  • 设计使用Mycat时有分页排序,请慎重使用Mycat,可以考虑放弃!
  • 设计使用Mycat时如果要进行表JOIN操作,要确保两个表的关联字段具有相同的数据分布,否则请
  • 慎重使用Mycat,可以考虑放弃!
  • 设计使用Mycat时如果有分布式事务,得先看是否得保证事务得强一致性,否则请慎重使用Mycat,可以考虑放弃!

mycat高可用搭配:

在生产环境中, Mycat节点最好使用双节点, 即双机热备环境, 防止Mycat这一层出现单点故障

  • Keepalived + Mycat + Mysql
  • Keepalived + LVS + Mycat + Mysql
  • Keepalived + Haproxy + Mycat + Mysql

使用mycat:

依赖于jdk
github下载:https://github.com/MyCATApache/Mycat-Server
下载地址: http://dl.mycat.org.cn/ #以前可用,博主现在写本文时似乎不可用

mycat程序:

端口:8066
默认用户: root
默认密码: 123456

mycat [子命令]
	console
	start
	stop 
	restart
	status 
	dump

mycat安装目录结构:

目录 说明
bin mycat命令,启动、重启、停止等
catlet catlet为Mycat的一个扩展功能
conf Mycat 配置信息,重点关注
lib Mycat引用的jar包,Mycat是java开发的
logs 日志文件,包括Mycat启动的日志和运行的日志
version.txt mycat版本说明

logs目录内容:

  • wrapper.log mycat启动日志
  • mycat.log mycat详细工作日志

常用的配置文件:

  • server.xml : Mycat软件本身相关的配置文件,设置账号、参数等
  • schema.xml : Mycat对应的物理数据库和数据库表的配置,读写分离、高可用、分布式策略定制、节点控制
  • rule.xml : Mycat分片(分库分表)规则配置文件,记录分片规则列表、使用方法等

server.xml文件解读:

存放Mycat软件本身相关的配置文件,比如:连接Mycat的用户,密码,数据库名称等

标签段 说明
<user> 配置用户的选项,登录mycat用户,与mysql无关。下面几个都是子标签段
password 密码
schemas 数据库名,和schema.xml中的配置关联,多个用逗号分开,例如:db1,db2
privileges 配置用户针对表的增删改查的权限
readOnly 逻辑库的权限。false关闭只读(默认),true开启

注意:

  • server.xml文件里登录mycat的用户名和密码可以任意定义,这个账号和密码是为客户机登录mycat时使用的账号信息(只是登录mycat的账户,与mysql无关)
  • 逻辑库名(也就是登录mycat后显示的库名,切换这个库之后,显示的就是代理的真实mysql数据库的表)要在schema.xml里面也定义,否则会导致mycat服务启动失败(mycat这里显示一个库,虚拟出来的,要关联mysql的真实库)
  • 如果定义多个标签,即设置多个连接mycat的用户名和密码,那么就需要在schema.xml文件中定义多个对应的库

schema.xml文件解读:

最主要的配置项,此文件关联mysql读写分离策略,读写分离、分库分表策略、分片节点都是在此文件中配置的
MyCat作为中间件,它只是一个代理,本身并不进行数据存储,需要连接后端的MySQL物理服务器,此文件就是用来连接MySQL服务器的

标签段 说明
schema 数据库设置,此数据库为逻辑数据库,name与server.xml中schema对应
dataNode 分片信息,也就是分库相关配置
dataHost 唯一性。真正存储数据的数据库,定义读、写主机
writeHost 属于datahost标签,写数据库定义
readOnly 属于writehost标签,读数据库定义
schema标签子参数:
name 与server.xml中的schema对应
checkSQLschema 数据库前缀相关设置,这里设false,默认true
qlMaxLimit 查询时默认的limit,避免查询全表
randomDataNode 为随机分页
table标签子参数:
name 表名,物理数据库中表名
dataNode 表存储到哪些节点,多个节点用逗号分隔。节点为下文dataNode设置的name
primaryKey 主键字段名,自动生成主键时需要设置
autoIncrement 是否自增
rule 分片规则名,具体规则下文rule详细介绍
dataNode标签子参数:
name 节点名,与table中dataNode对应
datahost 物理数据库名,与datahost中name对应
database 对应mysql中的数据库
dataHost标签子参数:
name 物理数据库名,与dataNode中dataHost对应
balance 均衡负载模式
writeType 写入方式
dbType 真实数据库是哪个
heartbeat 心跳检测语句,注意语句结尾的分号要加
maxCon 指定每个实例连接池的最大连接
minCon 每个读写实例连接池的最小连接

balance参数的配置选项:

0 关闭读写分离,所有读都发往可用的writeHost
1 一般用此模式,读请求随机分发到当前writeHost对应的readHost和standby的writeHost上。即全部的readHost与stand by writeHost参与select语句的负载均衡。简单的说,当双主双从模式(M1 ->S1 , M2->S2),正常情况下, M2,S1, S2 都参与 select语句的负载均衡
2 读请求随机分发到当前dataHost内所有的writeHost和readHost上。即所有读操作都随机的在writeHost、 readhost 上分发
3 读请求随机分发到当前writeHost对应的readHost上执行, writerHost不负担读压力,注意 balance=3 只在 1.4 及其以后版本有,1.3 没有
writeHost和readHost 标签使用:
  • 这两个标签都指定后端数据库的相关配置给mycat,用于实例化后端连接池。有从属关系,前者配置在:dataHost,后者配置在:writeHost
  • 在一个dataHost内可以定义多个writeHost和readHost。但是,如果writeHost指定的后端数据库宕机,那么这个writeHost绑定的所有readHost都将不可用。另一方面,由于这个writeHost宕机系统会自动的检测到,并切换到备用的writeHost上去

mycat实现mysql读写分离:

先搭建主从复制,再做读写分离
image

1)B主机创建master
yum install -y mariadb-server

vim /etc/my.cnf
[mysqld]
server-id=1
log-bin

systemctl restart mariadb

mysql -e 'grant replication slave,replication client on *.* to copy@"%" identified by "123456"'
2)C主机创建slave
yum install -y mariadb-server

vim /etc/my.cnf
[mysqld]
server-id=2
log-bin

systemctl restart mariadb

mysql
->CHANGE MASTER TO
   MASTER_HOST='2.2.2.12',
   MASTER_USER='copy',
   MASTER_PASSWORD='123456',
   MASTER_PORT=3306,
   MASTER_USE_GTID=current_pos;
  start slave;
3)A主机安装mycat、数据库客户端
yum install -y mariadb java-1.8.0-openjdk
tar xf mycat-xxx.gz -C /data ;cd /data/mycat
echo 'PATH=/data/mycat/bin:$PATH' > /etc/profile.d/mycat.sh &&. /etc/profile.d/mycat.sh

#启动mycat
mycat start
tail logs/wrapper.log		#有successfull为成功

#测试登录mycat
mysql -uroot -p123456 -h2.2.2.32 -P8066		#mycat安装后自带的默认账号密码,连接的虚拟库
->show databases;
4)A主机修改mycat的配置
修改mycat连接信息: server.xml

也就是用于登录mycat的账户信息,TESTDB就是mycat程序虚拟的数据库,关联mysql真实数据库后,访问TESTDB就能看到mysql的库

#找到<user name="root" defaultAccount="true">
vim /data/mycat/conf/server.xml
<user name="root" defaultAccount="true">
  <property name="password">123456</property>
  #虚拟数据库定义,对应schema,xml的配置(默认TESTDB)
  <property name="schemas">TESTDB</property>
修改读写分离策略: schema.xml

懒得修改的话,可以直接把配置文件清空,把我的配置模板直接复制进去

vim /data/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>
  #database等于mysql中的真实数据库
  <dataNode name="dn1" dataHost="localhost1" database="hj" />
  <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" 
   writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
     <heartbeat>select user()</heartbeat>
     <writeHost host="host1" url="2.2.2.12:3306" user="root" password="123456">
	   #读主机必须嵌套在写主机标签内,因为读和写是从属关系
       <readHost host="host2" url="2.2.2.22:3306" user="root" password="123456" />
     </writeHost>
  </dataHost>
</mycat:schema>	

#mycat重启
mycat restart
5)在master库中授权mycat可以root登录

从库不用创建,因为会同步该用户

#schema.xml的写、读定义什么用户就授权什么
mysql -e 'grant all on *.* to root@"%" identified by "123456" with grant option'
6)在mycat主机上测试,是否使用了读写分离

可用通用日志查看sql结果,判断sql调度到哪个节点执行,master、slave都要开启

#在master上开启通用日志,并监测
mysql
->show variables like 'general_log';
  set global general_log=1; \q

tail -f /var/lib/mysql/主机名.log

#在slave上开启通用日志,并监测
mysql
->show variables like 'general_log';
  set global general_log=1; \q

tail -f /var/lib/mysql/主机名.log

#在mycat主机上测试
mysql -uroot -p123456 -h2.2.2.32 -P8066 
->use TESTDB
  insert t1 values('8','789');
  select * from t1;
  select @@server_id;
  select @@hostname;

插入数据时,master节点的通用日志中记录
image

查询数据时,没有在master执行,而是在slave节点返回的数据
image

posted @ 2022-02-11 20:46  suyanhj  阅读(188)  评论(0编辑  收藏  举报