【Mycat2实战】三、Mycat实现读写分离

1. 无聊的理论知识

什么是读写分离

读写分离,基本的原理是让主数据库处理事务性增、改、删操作, 而从数据库处理查询操作。

为什么使用读写分离

从集中到分布,最基本的一个需求不是数据存储的瓶颈,而是在于计算的瓶颈,即 SQL 查询的瓶颈,我们知道,正常情况下,Insert SQL 就是几十个毫秒的时间内写入完成,而系 统中的大多数 Select SQL 则要几秒到几分钟才能有结果,很多复杂的 SQL,其消耗服器 CPU 的能力超强,不亚于死循环的威力。

读写分离方案

MyCat的读写分离是建立在MySQL主从复制基础之上实现的,所以必须先搭建MySQL的主从复制。数据库读写分离对于⼤型系统或者 访问量很⾼的互联网应用来说,是必不可少的⼀个重要功能。

注意: Mycat实现的读写分离和自动切换机制,需要MySQL的主从复制机制配合。

读写分离存在的问题

主从数据延迟,导致业务数据无法保证强一致性

Mysql 主从复制的常用拓扑结构

一主一从 最基础的复制结构,用来分担之前单台数据库服务器的压力, 可以进行读写分离。

一主多从 一台 Slave 承受不住读请求压力时,可以添加多台,进行负载均衡,分散读压力。

双主复制 双主结构就是用来解决这个问题的,互相将对方作为自己的 Master,自己作为对方的 Slave 来进行复制,但对外来讲,还是一个主和一个从。

级联复制 级联结构就是通过减少直接从属于 Master 的 Slave 数量,减轻 Master 的压力,分散复制请求,从而提高整体的复制效率。

双主级联 Mysql 的复制结构有很多种方式,复制的最大问题是数据延时,选择复制结构时需要根据自己的具体情况,并评估好目标结构的延时对系统的影响。

2. Mycat搭建读写分离

本文以一主一从的读写分离方案搭建进行演示。

mycat是直接接管我们的请求,然后分发到不同的数据库中,我们程序也是直接连接mycat,而不是数据库了。

2.1 准备工作

在配置之前,我们需要准备两个数据库,一主一从,并且已经完成了主从同步的配置,测试用的数据库、表确保都已经存在,同时创建好mycat要用的账户(主库、从库都需要配置)。

Mysql主从同步同步搭建过程参考文章包教包会:Mysql主从复制搭建,这里就不再赘述了。

因为已经主从同步,创建语句只需要在master库执行即可

创建测试数据库语句:

sql 复制代码
CREATE DATABASE IF NOT EXISTS `test-xxf`;

创建测试表语句,当然这里也可以不创建,利用Mycat也可以进行创建表的操作。

sql 复制代码
CREATE TABLE `xxf_user` (
	`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
	`user_name` VARCHAR(30) NULL DEFAULT NULL COMMENT '用户姓名',
	`email` VARCHAR(50) NULL DEFAULT NULL COMMENT '用户邮箱',
	`phone` VARCHAR(11) NULL DEFAULT NULL COMMENT '手机号码',
	`sex` CHAR(1) NULL DEFAULT NULL COMMENT '用户性别',
	PRIMARY KEY (`id`) USING BTREE
) COMMENT='笑小枫-用户信息表' COLLATE='utf8_general_ci' ENGINE=InnoDB;

创建Mycat的账号,如果开启了全部操作的主从库同步,在主库创建则自动会同步到从库。

sql 复制代码
CREATE USER 'mycat'@'%' IDENTIFIED BY '123456'; 
-- 必须要有的权限 mysql8才有的
GRANT XA_RECOVER_ADMIN ON *.* TO 'mycat'@'%';
-- 权限根据需求来给,这里直接给的全部权限
GRANT ALL PRIVILEGES ON *.* TO 'mycat'@'%' ;
flush PRIVILEGES;

2.2 Mycat配置

Mycat安装部署一文中已经配置了prototypeDs.datasource.json的数据库连接。这里无需改动。

json 复制代码
{
        "dbType":"mysql",
        "idleTimeout":60000,
        "initSqls":[],
        "initSqlsGetConnection":true,
        "instanceType":"READ_WRITE",
        "maxCon":1000,
        "maxConnectTimeout":3000,
        "maxRetryCount":5,
        "minCon":1,
        "name":"prototypeDs",
        "password":"123456",
        "type":"JDBC",
        "url":"jdbc:mysql://localhost:3306/mysql?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
        "user":"mycat",
        "weight":0
}

3.3 添加主数据源

进入mycat目录下的conf/datasources目录,复制 prototypeDs.datasource.json 并将名称设为master.datasource.json

shell 复制代码
cp prototypeDs.datasource.json master.datasource.json

操作完后,如下图所示:

修改master.datasource.json

shell 复制代码
vim master.datasource.json

主要修改数据源成jdbc:mysql://localhost:3306/test-xxf、name属性为master,如果用户名密码发生变化,则需要一并修改,然后保存退出。

json 复制代码
{
        "dbType":"mysql",
        "idleTimeout":60000,
        "initSqls":[],
        "initSqlsGetConnection":true,
        "instanceType":"READ_WRITE",
        "maxCon":1000,
        "maxConnectTimeout":3000,
        "maxRetryCount":5,
        "minCon":1,
        "name":"master",
        "password":"123456",
        "type":"JDBC",
        "url":"jdbc:mysql://localhost:3306/test-xxf?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
        "user":"mycat",
        "weight":0
}

如果有多个主节点就再配置一份叫mater02.datasource.json

3.4 添加从数据源

同主数据源配置一样,复制master.datasource.json设置为slave.datasource.json,然后进行编辑

shell 复制代码
cp master.datasource.json slave.datasource.json

vim slave.datasource.json

主要修改数据源成从库连接 jdbc:mysql://localhost:3307/test-xxf、name属性为slave读写模式instanceType改成只读模式 READ,如果用户名密码发生变化,则需要一并修改,然后保存退出。

json 复制代码
{
        "dbType":"mysql",
        "idleTimeout":60000,
        "initSqls":[],
        "initSqlsGetConnection":true,
        "instanceType":"READ",
        "maxCon":1000,
        "maxConnectTimeout":3000,
        "maxRetryCount":5,
        "minCon":1,
        "name":"slave",
        "password":"123456",
        "type":"JDBC",
        "url":"jdbc:mysql://localhost:3307/test-xxf?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
        "user":"mycat",
        "weight":0
}

如果有多个从节点就再配置一份叫slave02.datasource.json

3.5 配置数据源集群

由于配置读写分离涉及到多个数据库,所以就要配置数据源集群。
cd conf/clusters

shell 复制代码
cp prototype.cluster.json master-slave.cluster.json

vim master-slave.cluster.json

主要配置主从数据源的名称,值就对应前边配置数据源(*.datasource.json)中所定义的值

修改name为(*.cluster.json)中所定义的值

json 复制代码
{
    // 集群类型:SINGLE_NODE(单节点)、MASTER_SLAVE(普通主从)、GARELA_CLUSTER(garela cluster/PXC集群)等
    "clusterType":"MASTER_SLAVE",
    "heartbeat":{
        "heartbeatTimeout":1000,
        "maxRetry":3,
        "minSwitchTimeInterval":300,
        "slaveThreshold":0
    },
    "masters":[
        // 主节点数据源名称
        "master"
       // "master02"
    ],
    "replicas":[
        // 从节点数据源名称
        "slave"
       // "slave02"
    ],
    "maxCon":200,
    // 集群名称。在后面配置物理库(schema)时会用到
    "name":"master-slave",
    "readBalanceType":"BALANCE_ALL",
    // NOT_SWITCH(不进行主从切换)、SWITCH(进行主从切换)
    "switchType":"NOT_SWITCH"
}

3.6 配置物理库 schemas和mycat数据源/集群的关联关系

上边的集群和数据源都配置好了,那么就差跟mycat关联起来了,让mycat知道我们配置好的目标库应该指向哪个物理库,创建一个新的master_slave.schema.json文件。

shell 复制代码
cd conf/schemas

vim master_slave.schema.json
json 复制代码
{
    // 物理库
    "schemaName": "test-xxf",
    // 指向集群,或者数据源
    "targetName": "master-slave",
    // 这里可以配置数据表相关的信息,在物理表已存在或需要启动时自动创建物理表时配置此项
    "normalTables": {}
}

至此读写分离配置完成,下边开始测试。

3. 测试Mycat读写分离

在mycat上执行命令,可以查看到Mycat的数据源

sql 复制代码
/*+ mycat:showDataSources{} */

连接mycat,在mycat里面执行sql。准备下面的sql语句,插入一条数据。

sql 复制代码
INSERT INTO `xxf_user` VALUES (1, '张三', 'zhangsan@xiaoxiaofeng.com', '18300000000', '1');

然后可以在master和slave里面都看到了插入的数据。

因为我们数据设置的是,主数据库向从数据库同步,所以写操作发生在master数据源,然后同步到slave数据库。

执行查询语句,可以看到刚刚插入的数据。

sql 复制代码
SELECT * FROM xxf_user;

为了更好的判断数据库读的是主库还是从库,我们手动修改从库 的user_name为张三slave,修改从库数据,不会往主库同步,日常使用中不要修改从库数据,不然会导致数据不一致。

可以看到,一会查询的是张三,一会是张三slave,证明两个库都会查询,权重的话,可以在datasources下的master和slave数据源文件下修改weight属性。

4. 总结一下吧

本文主要讲解了如何使用Mycat实现一主一从的读写分离。一主多从、双主复制、多主多从,文章也是简单的提了一下,小伙伴门感兴趣可以自己去尝试,就是配置多个主从的数据源。

如果在搭建的过程中有任何疑问,可以评论区留言或者关注微信公众号留言,博主看到会及时的给予解答。

5. 本系列文章

本系列文章持续更新中,包括Mycat搭建,读写分离,分库分表等,敬请期待。

后续更新完成统一维护链接,占个坑先...

相关推荐
only-lucky8 分钟前
C语言socket编程-补充
服务器·c语言·php
try2find22 分钟前
移动conda虚拟环境的安装目录
linux·运维·conda
长征coder31 分钟前
AWS MySQL 读写分离配置指南
mysql·云计算·aws
码农101号1 小时前
Linux中容器文件操作和数据卷使用以及目录挂载
linux·运维·服务器
PanZonghui1 小时前
Centos项目部署之Nginx 的安装与卸载
linux·nginx
ladymorgana1 小时前
【docker】修改 MySQL 密码后 Navicat 仍能用原密码连接
mysql·adb·docker
PanZonghui1 小时前
Centos项目部署之安装数据库MySQL8
linux·后端·mysql
PanZonghui1 小时前
Centos项目部署之运行SpringBoot打包后的jar文件
linux·spring boot
PanZonghui1 小时前
Centos项目部署之Java安装与配置
java·linux
程序员弘羽1 小时前
Linux进程管理:从基础到实战
linux·运维·服务器