1.什么是mycat
mycat是Java语言开发的目前比较主流的数据库中间件之一,是mycat团队在阿里开源的 Cobar 产品基础上而研发的,也一直在维护。mycat实现了 MySQL 协议的服务器,前端用户可以把它看作是一个数据库代理,用 MySQL 客户端工具和命令行访问,而其后端可以用 MySQL 原生协议与多个 MySQL 服务器通信,也可以用 JDBC 协议与大多数主流数据库服务器通信。
mycat不单只可以做MySQL的代理,它的后端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL 等主流数据库,也支持 MongoDB 这种新型NoSQL 方式的存储,未来还会支持更多类型的存储。
2.mycat的实现原理
mycat主要是通过对SQL的拦截,然后经过一定规则的分片解析、路由分析、读写分离分析、缓存分析等,然后将SQL发给后端真实的数据块,并将返回的结果做适当处理返回给客户端。
3.mycat的应用场景
- 数据库读写分离,此时配置最为简单,支持读写分离,主从切换
- 数据库分库分表,这也是mycat的核心功能之一,可以解决数据库分库分表之后的数据插入和查询问题
- 多租户应用,每个应用一个数据库,但程序只需连接mycat,程序不改变,实现多租户化
- 海量数据的存储及实时查询,使用mycat是一种简单有效的方案
- 替代Hbase,分析大数据
mycat的介绍及使用 - 简书 (jianshu.com)
4.mycat安装
安装包下载地址:http://dl.mycat.org.cn/
mycat有windows版和Linux版,这里只说Linux的安装
PS:使用mycat前必须安装Java的JDK环境,so easy,这里不讲了,一定记得提前安装!!!
4.1 将压缩包上传到Linux指定的目录下并且解压
这里说一下,mycat可以跟存在在主从库的主机上,也可以独立存在在一台虚拟机上。我这里在独立的虚拟机上。
这里我们要实现的是读写分离(一主一从)
解压mycat
版本使用的是1.6.7.4稳定版
解压命令:
tar -zxvf Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz
4.2 修改配置文件
1、主要是修改如下3个配置文件
①schema.xml:定义逻辑库,表、分片节点等内容
②rule.xml:定义分片规则
③server.xml:定义用户以及系统相关变量,如端口等
2. 修改配置文件schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!--schema定义逻辑库的标签,配置逻辑库 name:表示逻辑库的名称 dataNode表示逻辑库关联的节点名称 -->
<schema name="testdb" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1">
</schema>
<!-- dataNode表示定义数据节点的标签 name:节点名称,必须和上面schema的dataNode值保持一致 dataHost关联的主机名称
database=表示真实数据库的名称-->
<dataNode name="dn1" dataHost="localhost1" database="demo_03" />
<!-- 定义真是服务所在的地址 name:表示数据主机的名称 -->
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<!--按照心跳机制来判断真实的数据库是否正常运行 -->
<heartbeat>select user()</heartbeat>
<!-- 配置主节点的信息 host随便起-->
<writeHost host="hostM1" url="192.168.19.151:3306" user="root"
password="123456">
<!-- 配置从节点的信息 可以配置多个-->
<readHost host="hostS1" url="192.168.19.153:3306" user="root" password="123456"></readHost>
</writeHost>
<!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> -->
</dataHost>
</mycat:schema>
这里我配置了一个写主机(192.168.19.151)和一个读从机(192.168.19.153),实现读写分离
这里的demo_03是我们mysql中的数据库名称
主要分schema、dataNode、dataHost三个主要配置.
3、修改配置文件server.xml
修改用户信息,与MySQL区分,如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<!-- 设置mycat账号 -->
<user name="mycat">
<!-- 设置mycat密码 -->
<property name="password">123456</property>
<!-- 连接的逻辑库 需要和schema.xml中的name一致 -->
<property name="schemas">testdb</property>
</user>
</mycat:server>
其中mycat、user为访问mycat的用户,TESTDB为mycat虚拟的数据库,供上层应用访问。
4.3 验证数据库访问情况
Mycat 作为数据库中间件要和数据库部署在不同机器上,所以要验证远程访问情况。mysql -uroot -pxxxxxx -h 192.168.19.151 -P 3306 mysql -uroot -pxxxxxx -h 192.168.19.153 -P 3306
#如远程访问报错,请建对应用户
grant all privileges on . to root@'%' identified by '123456'
4、启动程序
1、 控制台启动 :去 mycat/bin 目录下执行 ./mycat console
2 、后台启动 :去 mycat/bin 目录下 ./mycat start
为了能第一时间看到启动日志,方便定位问题,我们选择1控制台启动。
4.5 登录
1、登录后台管理窗口
此登录方式用于管理维护 Mycat
mysql -umycat -pxxxxxx -P 8066 -h 192.168.19.152
mysql -umycat -P8066 -h192.168.19.152 -p --default_auth=mysql_native_password
这里mysql8.0版本会有问题 显示密码错误
参考(3条消息) mycat配置mysql8 --菜鸟小回_菜鸟小回的博客-CSDN博客_mycat mysql8
此时schema.xml:
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <!--schema定义逻辑库的标签,配置逻辑库 name:表示逻辑库的名称 dataNode表示逻辑库关联的节点名称 --> <schema name="testdb" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1"> </schema> <!-- dataNode表示定义数据节点的标签 name:节点名称,必须和上面schema的dataNode值保持一致 dataHost关联的主机名称 database=表示真实数据库的名称--> <dataNode name="dn1" dataHost="localhost1" database="demo02" /> <!-- 定义真是服务所在的地址 name:表示数据主机的名称 --> <dataHost name="localhost1" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100"> <!--按照心跳机制来判断真实的数据库是否正常运行 --> <heartbeat>select user()</heartbeat> <!-- 配置主节点的信息 host随便起--> <writeHost host="hostM1" url="jdbc:mysql://192.168.19.151:3306?useSSL=false&serverTimezone=UTC" user="root" password="123456"> <!-- 配置从节点的信息 可以配置多个--> <readHost host="hostS1" url="jdbc:mysql://192.168.19.153:3306?useSSL=false&serverTimezone=UTC" user="root" password="123456"></readHost> </writeHost> <!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> --> </dataHost> </mycat:schema>
或
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <!--schema定义逻辑库的标签,配置逻辑库 name:表示逻辑库的名称 dataNode表示逻辑库关联的节点名称 --> <schema name="testdb" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1"> </schema> <!-- dataNode表示定义数据节点的标签 name:节点名称,必须和上面schema的dataNode值保持一致 dataHost关联的主机名称 database=表示真实数据库的名称--> <dataNode name="dn1" dataHost="localhost1" database="demo02" /> <!-- 定义真是服务所在的地址 name:表示数据主机的名称 --> <dataHost name="localhost1" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <!--按照心跳机制来判断真实的数据库是否正常运行 --> <heartbeat>select user()</heartbeat> <!-- 配置主节点的信息 host随便起--> <writeHost host="hostM1" url="192.168.19.151:3306" user="root" password="123456"> <!-- 配置从节点的信息 可以配置多个--> <readHost host="hostS1" url="192.168.19.153:3306" user="root" password="123456"></readHost> </writeHost> <!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> --> </dataHost> </mycat:schema>
server.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mycat:server SYSTEM "server.dtd"> <mycat:server xmlns:mycat="http://io.mycat/"> <system> <property name="useHandshakeV10">1</property> <property name="defaultSqlParser">druidparser</property> </system> <!-- 设置mycat账号 --> <user name="mycat"> <!-- 设置mycat密码 --> <property name="password">123456</property> <!-- 连接的逻辑库 需要和schema.xml中的name一致 --> <property name="schemas">testdb</property> </user> </mycat:server>
如果没有mysql命令,执行yum install -y mysql安装
使用命令查看逻辑库:
2、登录数据窗口
此登录方式用于通过 Mycat 查询数据,我们选择这种方式访问 Mycatmysql -umycat -pxxxx -P 8066 -h 192.168.56.20
4.6 测试
1.创建一个springboot项目
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.wzh</groupId>
<artifactId>mycat</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mycat</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<mysql.version>8.0.30</mysql.version>
</properties>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.编写实体类
package com.wzh.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @ProjectName: mycat
* @Package: com.wzh.entity
* @ClassName: User
* @Author: 王振华
* @Description:
* @Date: 2022/9/18 19:33
* @Version: 1.0
*/
@TableName("tb_user")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
}
3.编写mapper接口
package com.wzh.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wzh.entity.User;
import org.apache.ibatis.annotations.Mapper;
/**
* @ProjectName: mycat
* @Package: com.wzh.mapper
* @ClassName: UserMapper
* @Author: 王振华
* @Description:
* @Date: 2022/9/18 19:35
* @Version: 1.0
*/
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
4.测试
package com.wzh;
import com.wzh.entity.User;
import com.wzh.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class MycatApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
void contextLoads() {
User user = userMapper.selectById(1);
System.out.println(user);
}
@Test
void insert() {
int i = userMapper.insert(new User(3l, "李四"));
System.out.println(i);
}
}
但是每次结果都是从主机上读出来的
我们可以修改schema.xml配置文件的balance 改为3,从而实现读写分离