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

1. 无聊的理论知识

image-20231114093853568

什么是读写分离

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

为什么使用读写分离

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

读写分离方案

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

image-20231114094002230

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

读写分离存在的问题

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

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

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

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

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

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

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

2. Mycat搭建读写分离

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

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

2.1 准备工作

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

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

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

创建测试数据库语句:

CREATE DATABASE IF NOT EXISTS `test-xxf`;

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

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;

image-20231114100624317

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

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的数据库连接。这里无需改动。

{"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

cp prototypeDs.datasource.json master.datasource.json

操作完后,如下图所示:

image-20231114103840720

修改master.datasource.json

vim master.datasource.json

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

{"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,然后进行编辑

cp master.datasource.json slave.datasource.jsonvim slave.datasource.json

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

{"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

cp prototype.cluster.json master-slave.cluster.jsonvim master-slave.cluster.json

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

修改name为(*.cluster.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文件。

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

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

3. 测试Mycat读写分离

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

/*+ mycat:showDataSources{} */

image-20231114150717407

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

INSERT INTO `xxf_user` VALUES (1, '张三', 'zhangsan@xiaoxiaofeng.com', '18300000000', '1');

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

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

image-20231114141050107

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

SELECT * FROM xxf_user;

image-20231114142355747

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

image-20231114142740576

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

image-20231114145745559

4. 总结一下吧

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

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

5. 本系列文章

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/144015.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6.11.面图层(Polygon)

愿你出走半生,归来仍是少年&#xff01; 通过面图层可实现一个面的绘制&#xff0c;该面可包含多个孔洞。 1.构造 Polygon()Polygon(MapView mapView) 2. 顶点管理 voidsetPoints(List<GeoPoint> points)voidaddPoint(GeoPoint p)List<GeoPoint>getPoints() 通…

Python算法——树的直径

Python中的树的直径算法详解 树的直径是树中任意两个节点之间最长路径的长度。在本文中&#xff0c;我们将深入讨论树的直径问题以及如何通过深度优先搜索&#xff08;DFS&#xff09;算法来解决。我们将提供Python代码实现&#xff0c;并详细说明算法的原理和步骤。 树的直径…

java实现插入排序

图解 以下是Java实现插入排序的代码&#xff1a; public class InsertionSort {public static void main(String[] args) {int[] arr {5, 2, 4, 6, 1, 3};insertionSort(arr);System.out.println(Arrays.toString(arr)); // output: [1, 2, 3, 4, 5, 6]}public static void i…

线程安全问题及其解决

文章目录 一. 线程安全问题1.1 线程不安全的例子1.2 线程不安全的原因1.2.1 随即调度, 抢占式执行1.2.2 修改共享数据1.2.3 修改操作非原子性1.2.4 内存可见性1.2.5 指令重排序1.2.6 总结 二. 线程安全问题的解决2.1 synchronized(解决前三个问题)2.1.1 synchronized 的锁是什么…

247:vue+openlayers 根据坐标显示多边形(3857投影),计算出最大幅宽

第247个 点击查看专栏目录 本示例是演示如何在vue+openlayers项目中根据坐标显示多边形(3857投影),计算出最大幅宽。这里先通过Polygon来显示出多边形,利用getExtent() 获取3857坐标下的最大最小x,y值,通过ransformExtent转换坐标为4326, 通过turf的turf.distance和计算…

社区论坛小程序系统源码+自定义设置+活动奖励 自带流量主 带完整的搭建教程

大家好啊&#xff0c;又到了罗峰来给大家分享好用的源码的时间了。今天罗峰要给大家分享的是一款社区论坛小程序系统。社区论坛已经成为人们交流、学习、分享的重要平台。然而&#xff0c;传统的社区论坛往往功能单一、缺乏个性化设置&#xff0c;无法满足用户多样化的需求。而…

Apache Log4j2漏洞

目录 漏洞复现 漏洞原理 MessagePatternConverter.format() StrSubstitutor.resolveVariable() Interpolator.lookup() JndiLookup.lookup() JndiManager.lookup(

聊聊logback的MDCFilter

序 本文主要研究一下logback的MDCFilter MatchingFilter ch/qos/logback/classic/turbo/MatchingFilter.java public abstract class MatchingFilter extends TurboFilter {protected FilterReply onMatch FilterReply.NEUTRAL;protected FilterReply onMismatch FilterR…

rabbitmq 集群搭建

RabbitMQ集群介绍 RabbitMQ集群是一组RabbitMQ节点&#xff08;broker&#xff09;的集合&#xff0c;它们一起工作以提供高可用性和可伸缩性服务。 RabbitMQ集群中的节点可以在同一物理服务器或不同的物理服务器上运行。 RabbitMQ集群的工作原理是&#xff0c;每个节点在一个…

C++编写的多线程自动爬虫程序

以下是一个使用C编写的爬虫程序&#xff0c;用于爬取Python进行多线程跑数据的内容。本示例使用了Python的requests库来发送HTTP请求&#xff0c;并使用cheeseboy的爬虫ipIP库来设置爬虫ip信息。以下是详细代码和步骤&#xff1a; #include <iostream> #include <stri…

StyleGAN:彻底改变生成对抗网络的艺术

一、介绍 多年来&#xff0c;人工智能领域取得了显着的进步&#xff0c;其中最令人兴奋的领域之一是生成模型的发展。这些模型旨在生成与人类创作没有区别的内容&#xff0c;例如图像和文本。其中&#xff0c;StyleGAN&#xff08;即风格生成对抗网络&#xff09;因其创建高度逼…

12-使用vue2实现todolist待办事项

个人名片&#xff1a; &#x1f60a;作者简介&#xff1a;一名大二在校生 &#x1f921; 个人主页&#xff1a;坠入暮云间x &#x1f43c;座右铭&#xff1a;懒惰受到的惩罚不仅仅是自己的失败&#xff0c;还有别人的成功。 &#x1f385;**学习目标: 坚持每一次的学习打卡 文章…

C语言实现杨辉三角

杨辉三角是一个经典的数学图形&#xff0c;可以用C语言来实现&#xff0c;实现代码如下&#xff1a; #include <stdio.h>int main() {int i, j, n;int a[10][10];printf("请输入要打印的行数: ");scanf("%d", &n);// 初始化第一行和对角线for (…

【Spring Boot】035-Spring Boot 整合 MyBatis Plus

【Spring Boot】035-Spring Boot 整合 MyBatis Plus 【Spring Boot】010-Spring Boot整合Mybatis https://blog.csdn.net/qq_29689343/article/details/108621835 文章目录 【Spring Boot】035-Spring Boot 整合 MyBatis Plus一、MyBatis Plus 概述1、简介2、特性3、结构图4、相…

LeetCode - 27. 移除元素 (C语言,快慢指针,配图)

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 思路一&#xff1a;新开辟一个数组&#xff0c;空间复杂度O(N) 因为本题要求是空间复杂度O(1),所以这里只是列出思路1的思路和配图&#xff0c;并没有具体的实现代码&#xff0c;想必这对大家一定很简单…

使用postman测试

第一步&#xff1a; 第二步&#xff1a; 第三步&#xff1a;添加请求 第四步&#xff1a;填写请求 代码实现自动关联的位置&#xff1a; 为相关联的接口设置环境&#xff1a; 使用设置的环境变量&#xff1a; 参数化实现测试&#xff1a;测试脚本中仅测试数据不一样&#xff…

Promise 重写 (第一部分)

学习关键语句&#xff1a; promise 重写 写在前面 重新学习了怎么重写 promise &#xff0c; 我觉得最重要的就是要有思路&#xff0c;不然有些 A 规范是完全想不到的 开始 重写函数的过程中, 最重要的是有思路 我们从哪里获取重写思路? 从正常的代码中 我们先看正常的代码…

2023数维杯数学建模C题思路+代码+论文

目录 1.C题思路模型&#xff1a;比赛开始后&#xff0c;第一时间更新&#xff0c;获取见文末名片 2.竞赛注意事项&#xff1a;包括比赛流程&#xff0c;任务分配&#xff0c;时间把控&#xff0c;论文润色&#xff0c;已经发布在文末名片中 3.常用国赛数学建模算法 3.1 分…

『GitHub项目圈选02』一款可实现视频自动翻译配音为其他语言的开源项目

&#x1f525;&#x1f525;&#x1f525;本周GitHub项目圈选****: 主要包含视频翻译、正则填字游戏、敏感词检测、聊天机器人框架、AI 换脸、分布式数据集成平台等热点项目。 1、pyvideotrans pyvideotrans 是一个视频翻译工具&#xff0c;可将一种语言的视频翻译为另一种语…

学习c#的第十三天

目录 C# 多态性 静态多态性 函数重载 运算符重载 动态多态性 virtual 和 abstract 抽象方法和虚方法的区别 重载(overload)和重写(override) 隐藏方法 C# 多态性 多态是同一个行为具有多个不同表现形式或形态的能力。 多态性意味着有多重形式。在面向对象编程范式中…