MyCat介绍
首先MyCat是什么简单的介绍下
一个彻底开源的,面向企业应用开发的大数据库集群
支持事务、ACID、可以替代MySQL的加强版数据库
一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
一个新颖的数据库中间件产品
以上为官方介绍
Mycat能干什么
读写分离
垂直拆分
水平拆分
实现分布式架构
数据库中间件概念
数据库中间件可以做到程序与数据库解耦操作 数据库是一类连接软件组件和应用的计算机软件,以便于软件各部件之间的沟通。例如nginx tomcat 等
原本程序与数据库的交流是这样:
数据库中间件与数据库和程序之间的关系
程序直接连接中间件 至于中间件连接谁 不需要知道 所有的配置都在中间件里面 程序只负责连接
Mycat读写分离搭建
已有环境:
Contos 7
PHP 7.2.31
Mysql Ver 8.0.21 for Linux
Nginx1.16
·
以上的搭建自行解决吧
首先先下载Mycat 官网地址 (我下载的版本是1.6.7.5)
Linux 复制下面 windows自行解决
wget http://dl.mycat.org.cn/1.6.7.5/2020-4-10/Mycat-server-1.6.7.5-release-20200410174409-linux.tar.gz
下载完后你会得到这样一个文件
解压:tar -zxvf Mycat-server-1.6.7.5-release-20200410174409-linux.tar.gz
将mycat目录扔到/usr/local/下放着
cp -r mycat /usr/local/
切换至/usr/local/mycat下
bin目录为mycat启动文件 (可执行文件)
conf 配置信息
logs 日志文件
进入conf
修改server.xml文件
//0为需要密码登陆、1为不需要密码登陆 ,默认为0,设置为1则需要指定默认账户
<property name="nonePasswordLogin">1</property>
//name填写的是你到时候登录Mycat的用户名
<user name="mycat" defaultAccount="true">
//这里是登录时候的密码
<property name="password">ldy123</property>
//mycat的逻辑库
<property name="schemas">ana</property>
//以上与实际数据库无关
</user>
//下面这个可以注释可以不注
<!-- <user name="user">
<property name="password">user</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
<property name="defaultSchema">TESTDB</property>
</user> -->
</mycat:server>
以上为要修改的地方
修改schema.xml文件
//只留下这么多 其他的全部删掉
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
//schema 为逻辑库 schema 里面的table全部删掉 读写分离不需要
//name="ana" 为server文件写的逻辑库名称
//sqlMaxLimit="100" 为查询最大返回条数
//dataNode=dn1 需要与下面的dataNode里面的 name 对应
<schema name="ana" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1">
</schema>
// dataNode name="dn1"没啥说的 上面逻辑库怎么配置就咋写
//dataHost 定义的名称
//database 为 MySql里面实际存在的库名称
<dataNode name="dn1" dataHost="host1" database="ana" />
//dataHost 为主机详细配置
//balance
//当balance=0 时,不开启读写分离,所有读操作都发生在当前的writeHost上
// 当balance=1 ,所有读操作都随机发送到当前的writeHost对应的readHost和备用的writeHost
//当balance=2,所有的读操作都随机发送到所有的writeHost,readHost上
//当balance=3 ,所有的读操作都只发送到writeHost的readHost上
//dbDriver 重点说下 两种方式native 和 jdbc Mysql8以下直接使用native 就好 如果你是mysql8 那么你需要去/etc/my.conf 修改MYSQL的密码方式 default_authentication_plugin=mysql_native_password
//heartbeat 他的作用是 监测MYSQL服务是否正常 检测心跳
//writeHost 写主机信息
//readHost 读主机信息
<dataHost name="host1" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="主机ID:3306" user="root"
password="密码">
<readHost host="hostS1" url="主机IP:3306" user="root" password ="密码" />
</writeHost>
</dataHost>
</mycat:schema>
以上完成了 还需要在两台主机上创建 实体库 例子中为ana
上面的搭建完后 还不能启动 MYCAT 先放一边 咱们先验证下两件事
第一件事是 上面的writeHost 和 readHost 是否支持远程访问 因为MYCATA是远程连接
命令如下mysql -uroot -p密码 -h 你的IP -P 3306测试下如果 无法连接需要去开启 数据库远程访问 自行百度配置吧
第二件事就是 既然读写分类 那 两台机器 数据需要保证一致 这时候就需要 主从复制
下面先看下主从复制原理
主从复制原理及配置
>这里 咱们写机器当作主 从机 只需要 实时更新 主log 文件 到从机
大概运行原理就是 主机每次操作都会有一份 Binary-log日志 里面记录的是 主机的 操作日志 从机通过远程帐号去访问 主机的日志 从而 执行相应的操作
知道原理了 剩下的就是实践
开始正题如何配置
先看主机上需要进行的操作
修改配置文件:vim /etc/my.cnf
//主服务器唯一ID
server-id=1
//启用二进制日志
log-bin=mysql-bin
//设置不要复制的数据库(可设置多个)
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
//设置需要复制的数据库
binlog-do-db=需要复制的主数据库名字
//设置logbin格式
binlog_format=STATEMENT //这个格式有三种 STATEMENT ROW MIXED 区别自行百度
修改完记得重启 mysql服务
从机配置如下
server-id=2
//启用中继日志
relay-log=mysql-relay
配置完记得重启mysql服务
刚才上面说了原理 需要从机 进行访问 如果 主机拒绝请求 就拿不到log文件了 无法更新 所以 需要在主机上配置 一个 相应的权限 不需要太高 只需要访问 日志就好
//在主机MySQL里执行授权命令 MYSQL5.7配置如下
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%' IDENTIFIED BY '123123';
//MYSQL8.0 就不是上面的命令了是下面的
CREATE USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123123';
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%';
在主机上执行
show master status;
记录上面的文件名称及 position
#执行完此步骤后不要再操作主服务器MySQL,防止主服务器状态值变化
进入从机从机配置
//复制主机的命令
CHANGE MASTER TO MASTER_HOST='主机的IP地址',
MASTER_USER='slave',
MASTER_PASSWORD='123123',
MASTER_LOG_FILE='mysql-bin.具体数字',MASTER_LOG_POS=具体值;
//启动从服务器复制功能
start slave;
//查看从服务器状态
show slave status\G;
完成上面的东西就可以 进入主机 测试了
启动mycat
进入mycat bin 目录 执行 ./mycat console
然后 执行mysql -umycat -p123123 -h 主机IP -P 8066
进行插入 看看两机是否同步
垂直拆分(将同模块的表放在一台服务器上)
修改 schema 配置文件
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="ana" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1">
<table name="customer" dataNode="dn2"></table> //这里填写你要拆分的表
</schema>
<dataNode name="dn1" dataHost="host1" database="orders" />//既然拆分 肯定是两台机器
<dataNode name="dn2" dataHost="host2" database="orders" />//新增DN2 这个是要拆分的数据库名称
<dataHost name="host1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="主机IP:3306" user="root"
password="密码">
</writeHost>
</dataHost> //这里去掉读主机
<dataHost name="host2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="主机IP:3306" user="root"
password="密码">
</writeHost>
</dataHost>
</mycat:schema>
新增两个 空白库 分别创建 orders库
启动mycat ./mycat console
在mycat 数据库里面随意插入 4张表 其中包含上面配置的customer表
这时候你会发现 DN1里面 没有 customer 只有其他3张表 而 DN2里面只有 customer 说明搭建成功
水平拆分
相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,
每个表中 包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就
是将表中的某些行切分 到一个数据库,而另外的某些行又切分到其他的数据库中
看下如何配置
修改配置文件 schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="ana" checkSQLschema="true" sqlMaxLimit="10000" dataNode="dn1">
<table name="ana_stock_list" dataNode="dn1,dn2" rule="mod_rule">//rule="mod_rule" 定义拆分规则 dataNode定义都拆分到哪个库里面
<childTable name="ana_stock_single_info" primaryKey="ssi_id" joinKey="s_id" parentKey="s_id" />
<childTable name="ana_stock_info" primaryKey="asi_id" joinKey="s_id" parentKey="s_id" />//childTable 存的是 与拆分表有关联需要JOIN的表会采用同样的拆分方式进行拆分 name表名 primaryKey当前表主键 joinKey关联字段 parentKey父级表主键
</table>
</schema>
<dataNode name="dn1" dataHost="host1" database="ana" />
<dataNode name="dn2" dataHost="host2" database="ana" />
<dataHost name="host1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="你的IP:3306" user="root"
password="密码">
</writeHost>
</dataHost>
<dataHost name="host2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="ip地址:3306" user="root"
password="密码">
</writeHost>
</dataHost>
</mycat:schema>
修改配置文件 rule.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
<tableRule name="mod_rule"> //上面 schema定义的 拆分规则名称
<rule>
<columns>s_id</columns> //按照 s_id进行拆分
<algorithm>mod-long</algorithm>//拆分规则 求余 mod-long这个是默认方法 感兴趣可以去下面看下规则 会有这个方法如何实现的代码
</rule>
</tableRule>
//后面内容省略
别忘了在两台数据库原本上面建表
重启 Mycat,让配置生效 然后对拆分表进行插入 查看效果
最后两个实体库 ID 按照 mod-long规则存储
Mycat与Mysql 和YII2框架 遇到的 坑总结如下
1.Mysql8.0 密码机制变了 需要重点关注下
2.YII2 配置mycat帐号密码之后 group by的时候 会生成
这种点 导致 Mycat 无法解析报错 目前我是 直接扔的 原生SQL 没有解决 也是一个BUG的存在
错误图片:
解决方式1:
解决方式2