Mycat
1. 概述
mycat通过配置之后,是否就能解决分库分表和读写分离问题呢?
mycat配合数据库本身的复制功能,可以解决读写分离的问题
但是针对分库分表的问题,并不能完美解决
mycat支持两张表的联查,但是多于两张表的联查并不支持
所以在数据库设计之后,就需要分析哪些表放进一个数据库中,哪些没有关联的数据库的单表放进另外一个数据库中
其实,很多数据库中间件关于分库分表之后的查询问题,都是需要自己实现的,而且基本上都不支持连表查询
mycat在业界已经是属于一款很优秀的产品
所以需要数据库工程师合理设计数据库结构来避免发生这种问题
mycat除了支持mysql,还支持哪些数据库或平台?
官方介绍mycat支持mysql,SQL server,Oracle,DB2,PostgreSQL等
官方推荐使用在mysql
mycat除了可以运行在Java平台上,还可以运行在.net,PHP平台上
好处: 可以不用修改原有的代码
数据库的分库分表是物理切割,通过mycat实现逻辑连接
mycat通过命令启动后,你只需要将数据库的连接切换到mycat连接地址即可
写法: jdbc:mysql://mycat服务器ip:8066
把jdbc:mysql://localhost:3306切换到 jdbc:mysql://mycat服务器:8066
如果mycat启动失败了,怎么办?
第一时间打开log目录,查看里面的日志文件.有两个日志文件wrapper.log和mycat.log
wrapper.log: 程序启动时的日志
mycat.log: 脚本执行的日志,SQL脚本执行报错后的具体报错内容,历史日志会根据时间生成目录记录
一般情况下,启动失败,都是配置错误
2. 导读
在系统开发中,数据库是非常重要的一个点.
如SQL优化,代码优化,数据库结构本身优化,主从复制,热备,分库分表,读写分离等都是在系统开发中迟早需要面对的技术问题
mycat就是一款优秀的分布式数据库中间件
3. 什么是Mycat
一个彻底开源的,面向企业应用开发的大数据库集群
支持事务、ACID、可以替代MySQL的加强版数据库
一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
一个新颖的数据库中间件产品
4. 关键特征
支持SQL92标准
支持SQL Server,Oracle,DB2,Mysql,PostgreSQL等DB常见的SQL语法
遵从mysql原生协议,跨语言,跨平台,跨数据库的通用服务中间件代理
基于心跳的自动故障切换,支持读写分离,支持mysql主从复制以及集群
基于NIO(非阻塞IO)技术实现,有效管理线程问题,可以解决高并发的相关问题.
支持数据库多片自动路由与聚合,支持sum,count,max等常用聚合函数
支持跨数据库分页操作
5. Mycat的架构
6.Mycat的下载安装
6.1准备工作
- 克隆前面的一个master
1.修改主机名
vim /etc/hostname
2.修改ip
vim /etc/sysconfig/network-scripts/ifcfg-ens33
- 上传及解压
cd /usr/local
mkdir mycat
cd mycat
把压缩包上传到mycat
解压,解压即安装
-
目录介绍
-
配置文件介绍
-
mycat架构
mycat本质是一个代理,在mycat后面连接的是物理数据库,与nginx类似
对于使用者来说,访问的都是mycat服务器或mycat集群,不会接触到后端的数据库
mycat一般作为主数据库的中间件,一般情况下是和代码保持一种弱关联的关系,所以不用修改原有代码
使用mycat后,与连接数据库的方式不变,默认端口号为8066
连接方式和普通数据库连接方式一样
6.2 搭建mycat的分库分表
- 准备三台服务器mycat,master,slave
mycat 虚拟的数据库,作为代理服务器使用的
master 物理数据库1
slave 物理数据库2
- 在master和slave创建数据库ZKL_TABLE(已是主从复制环境)
配置主从复制
在master创建数据库表dept和user
在slave创建student,并把user删除
表功能:
dept在这里充当负载均衡.可以操作master和slave两个数据库
user表只能操作master数据库
student表只能操作slave数据库
让dept表实现负载功能,哪个数据库执行的速度快就加载谁
- 配置server.xml
<!--配置mycat连接信息
user 新增用户配置 指的是用户配置节点,可以配置多个user
password 连接mycat的密码
schema 连接的逻辑数据库,此处的数据库必须用大写,
如果有多个数据库中间用逗号隔开,
该数据库名需要与后面配置的schema.xml文件的schema配置产生一一映射
readOnly 是否只读
-->
<user name="root">
<property name="password">123456</property>
<property name="schemas">ZKL_TABLE</property>
<property name="readOnly">false</property>
</user>
- schema.xml
只留头约束,其他都删除
<!--
配置mycat的物理数据库和逻辑表
schema 的name需要与server.xml的schemas保持一致
如果server.xml的schemas有多个数据库,那么这里需要配置多个schema
-->
<schema name="ZKL_TABLE" checkSQLschema="false" sqlMaxLimit="100">
<table name="user" dataNode="dn01"/>
<table name="student" dataNode="dn02"/>
<table name="dept" dataNode="dn01,dn02" primaryKey="d_id" autoIncrement="true" rule="mod-long"/>
</schema>
<dataNode name="dn01" dataHost="master" database="ZKL_TABLE"/>
<dataNode name="dn02" dataHost="slave01" database="ZKL_TABLE"/>
<!--配置物理数据库 真实的数据库-->
<dataHost name="master" maxCon="10000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
<!--心跳检查机制-->
<heartbeat>select user();</heartbeat>
<!--指定哪个数据库处理dataNode请求-->
<writehost host="master域名" url="192.168.88.100:3306" user="admin" password="123456"></writehost>
</dataHost>
<dataHost name="slave01" maxCon="10000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
<!--心跳检查机制-->
<heartbeat>select user();</heartbeat>
<!--指定哪个数据库处理dataNode请求-->
<writehost host="slave01域名" url="192.168.88.101:3306" user="admin" password="123456"></writehost>
</dataHost>
<!--
注意事项
schema配置尽量放在一起
dataNode尽量放在一起
dataHost尽量放在一起
-->
参数介绍
- schema 配置数据库的设置,此数据库为逻辑数据库(虚拟的),name值需要和server.xml文件的schema保持一致
schema属性介绍
name 逻辑数据库名
checkSqlschema 数据库的前缀配置
sqlMaxLimit select查询时默认的limit,避免查询全表
table属性介绍
name 表明
dataNode 表存储在哪个数据库节点上
primaryKey 注解字段名
autoIncrement 是否自增
rule 分库分表的规则,mod-long平均分配- dataNode 分库信息,进行分库的相关配置
- dataHost 配置物理数据库(真实的),是真正存储数据的地方
- rule.xml
修改下面的两处
<tableRule name="mod-long">
<rule>
<columns>d_id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes 节点数量 -->
<property name="count">2</property>
</function>
测试
- 启动
cd /usr/local/mycat/bin
./mycat start
2.查看mycat的启动日志wrapper.log
cd …
cd logs
cat wrapper.log
读写分离
- 配置schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="ZKL_TABLE" checkSQLschema="false" sqlMaxLimit="100">
<table name="user" dataNode="dn01"/>
<table name="student" dataNode="dn02"/>
<table name="dept" dataNode="dn01,dn02" primaryKey="d_id" autoIncrement="true" rule="mod-long"/>
</schema>
<dataNode name="dn01" dataHost="master" database="ZKL_TABLE"/>
<dataNode name="dn02" dataHost="slave01" database="ZKL_TABLE"/>
<dataHost name="master" maxCon="10000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user();</heartbeat>
<writehost host="192.168.88.100" url="192.168.88.100:3306" user="admin" password="123456">
<readHost host="slave01" url="192.168.88.101:3306" user="admin" password="123456"></readHost>
</writehost>
</dataHost>
<dataHost name="slave01" maxCon="10000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native">
<!--心跳检查机制-->
<heartbeat>select user();</heartbeat>
<!--指定哪个数据库处理dataNode请求-->
<writehost host="192.168.88.101" url="192.168.88.100:3306" user="admin" password="123456">
<readHost host="slave01" url="192.168.88.101:3306" user="admin" password="123456"></readHost>
</writehost>
</dataHost>
</mycat:schema>
- 重启mycat
./mycat restart
停止
./mycat stop
查看状态