《Mycat核心技术》第17章:实现MySQL的读写分离

server/2025/2/25 2:43:16/

作者:冰河
星球:http://m6z.cn/6aeFbs
博客:https://binghe.gitcode.host
文章汇总:https://binghe.gitcode.host/md/all/all.html
星球项目地址:https://binghe.gitcode.host/md/zsxq/introduce.html

沉淀,成长,突破,帮助他人,成就自我。

  • 本章难度:★★☆☆☆
  • 本章重点:介绍Myca实现MySQL的读写分离案例,掌握Mycat在实际案例场景中的应用,能够结合自身实际项目将Mycat灵活应用到自身实际项目中。

大家好,我是冰河~~

今天给大家介绍《Mycat核心技术》的第17章:给大家简单介绍下Mycat实现MySQL的读写分离的案例,好了,开始今天的内容。

一、服务规划

在MySQL中间件出现之前,对于MySQL主从集群,如果要实现其读写分离,一般是在程序端实现,这样就带来一个问题,即数据库和程序的耦合度太高,如果我数据库的地址发生改变了,那么我程序端也要进行相应的修改,如果数据库不小心挂掉了,则同时也意味着程序的不可用,而这对很多应用来说,并不能接受。

引入MySQL中间件能很好的对程序端和数据库进行解耦,这样,程序端只需关注数据库中间件的地址,而无需知晓底层数据库是如何提供服务。

作为当前炙手可热的MySQL中间件,MyCAT实现MySQL主从集群的读写分离自是应有之义,其配置也相当简单。

在这里,我用三个实例组成MySQL主从集群,来验证MyCAT的读写分离功能,其实,一主一从就可以满足,之所以用三个,是为了验证MyCAT的分片功能。

集群组成如下:

角色主机名主机IP
mastermysql-server1192.168.244.145
slavemysql-server2192.168.244.146
slavemysql-server3192.168.244.144

在这里,还是使用Travelrecord表进行测试。

首先编辑MyCAT的配置文件schema.xml,关于dataHost的配置信息如下:

<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="-1"  slaveThreshold="100"><heartbeat>select user()</heartbeat><!-- can have multi write hosts --><writeHost host="hostM1" url="localhost:3306" user="root" password="123456"></writeHost><writeHost host="hostS1" url="192.168.244.146:3306" user="root" password="123456"/><writeHost host="hostS2" url="192.168.244.144:3306" user="root" password="123456"/>
</dataHost>

这里面,有两个参数需要注意,balance和 switchType。

其中,balance指的负载均衡类型,目前的取值有4种:

  • balance=“0”, 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。
  • balance=“1”,全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。
  • balance=“2”,所有读操作都随机的在writeHost、readhost上分发。
  • balance=“3”,所有读请求随机的分发到wiriterHost对应的readhost执行,writerHost不负担读压力

switchType指的是切换的模式,目前的取值也有4种:

  • switchType=‘-1’ 表示不自动切换
  • switchType=‘1’ 默认值,表示自动切换
  • switchType=‘2’ 基于MySQL主从同步的状态决定是否切换,心跳语句为 show slave status
  • switchType='3’基于MySQL galary cluster的切换机制(适合集群)(1.4.1),心跳语句为 show status like ‘wsrep%’。

因此,该配置文件中的balance="1"意味着作为stand by writeHost的hostS1和hostS2将参与select语句的负载均衡,这就实现了主从的读写分离,switchType='-1’意味着当主挂掉的时候,不进行自动切换,即hostS1和hostS2并不会被提升为主,仍只提供读的功能。这就避免了将数据读进slave的可能性,毕竟,单纯的MySQL主从集群并不允许将数据读进slave中,除非配置的是双master。

二、验证读写分离

下面来验证一下,创建Travelrecord表

create table travelrecord (id bigintnotnullprimarykey,user_idvarchar(100),traveldate DATE, fee decimal,days int);

插入数据

mysql>insertinto travelrecord(id,user_id,traveldate,fee,days)  values(1,@@hostname,20160101,100,10);
Query OK, 1 row affected, 1 warning (0.02 sec)mysql>insertinto travelrecord(id,user_id,traveldate,fee,days)  values(5000001,@@hostname,20160102,100,10);
Query OK, 1 row affected, 1 warning (0.01 sec)

在这里,用了一个取巧的方法,即对user_id插入了当前实例的主机名,这样可直观的观察读写是否分离以及MyCAT的分片功能。能这样做的原因在于我当前的MySQL版本-5.6.26默认是基于statement的复制,如果是基于row的复制,则这个方法将不可取。
查询数据

mysql>select * from travelrecord;
+---------+---------------+------------+------+------+| id      |user_id| traveldate | fee  | days |+---------+---------------+------------+------+------+|1| mysql-server2 |2016-01-01|100|10||5000001| mysql-server3 |2017-02-02|100|10|+---------+---------------+------------+------+------+2 rows inset (0.01 sec)mysql>select * from travelrecord;
+---------+---------------+------------+------+------+| id      |user_id| traveldate | fee  | days |+---------+---------------+------------+------+------+|5000001| mysql-server3 |2016-01-02|100|10||1| mysql-server2 |2017-02-01|100|10|+---------+---------------+------------+------+------+2 rows inset (0.02 sec)mysql>select * from travelrecord;
+---------+---------------+------------+------+------+| id      |user_id| traveldate | fee  | days |+---------+---------------+------------+------+------+|5000001| mysql-server3 |2016-01-02|100|10||1| mysql-server3 |2017-02-01|100|10|+---------+---------------+------------+------+------+2 rows inset (0.01 sec)mysql>select * from travelrecord;
+---------+---------------+------------+------+------+| id      |user_id| traveldate | fee  | days |+---------+---------------+------------+------+------+|5000001| mysql-server3 |2016-01-02|100|10||1| mysql-server3 |2017-02-01|100|10|+---------+---------------+------------+------+------+2 rows inset (0.01 sec)mysql>select * from travelrecord;
+---------+---------------+------------+------+------+| id      |user_id| traveldate | fee  | days |+---------+---------------+------------+------+------+|1| mysql-server2 |2016-01-01|100|10||5000001| mysql-server2 |2017-02-02|100|10|+---------+---------------+------------+------+------+

从上面的输出结果,可以得出以下两点:

(1)该配置已实现读写分离,读出来的数据没有master节点的。

(2)MyCAT的随机分发不是基于statement的,即一个select语句查询其中一个节点,另外一个select语句查询另外一个节点。它分发针对的是片的,同一个select语句的结果是有不同dataNode返回的。

不仅如此,从MyCAT日志中也可以获取读写分离的相关信息,当然,前提是MyCAT的日志级别是debug。日志相关信息如下:

在这里插入图片描述

三、验证mater挂了,slave还能提供读的功能

对于MySQL主从集群,我们的需求是master挂了,slave还能提供读的功能。

下面来测试一下

首先,人为的关闭主库

[root@mysql-server1 ~]# /etc/init.d/mysqld stop

登录MyCAT

[root@mysql-server1 ~]# mysql -utest -ptest -h127.0.0.1 -P8066 -DTESTDB

插入数据

mysql>insertinto travelrecord(id,user_id,traveldate,fee,days)  values(10000001,@@hostname,20170213,100,10);
ERROR 1184 (HY000): Connection refused
mysql>select*from travelrecord;
+---------+---------------+------------+------+------+| id      |user_id| traveldate | fee  | days |+---------+---------------+------------+------+------+|1| mysql-server2 |2017-02-01|100|10||5000001| mysql-server3 |2017-02-02|100|10|+---------+---------------+------------+------+------+2 rows inset (0.02 sec)

可见无法插入数据,但不影响读取数据。

至此,MyCAT实现MySQL的读写分离部署测试完毕。

四、总结

其实,刚开始配置的是readHost节点,配置如下:

<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql" dbDriver="native" switchType="-1"  slaveThreshold="100"><heartbeat>select user()</heartbeat><!-- can have multi write hosts --><writeHost host="hostM1" url="localhost:3306" user="root" password="123456"><!-- can have multi read hosts --><readHost host="hostS1" url="192.168.244.146:3306" user="root" password="123456"/></writeHost>
</dataHost>

但这种方式有个问题,即master挂了以后,slave也不能提供服务,而这违反了MySQL主从集群的初衷。

如果开启了事务模式,即set autocommit=0,则事务内的读走的是master节点,而不是从节点。

好了,今天就到这儿吧,我是冰河,我们下期见~~


http://www.ppmy.cn/server/170460.html

相关文章

Qt开发④Qt常用控件_上_QWdget属性+按钮类控件

目录 1. 控件概述和发展 2. QWidget 核心属性 2.1 核心属性概览 2.2 enabled 是否可用 2.3 geometry 位置尺寸 2.4 windowTitle 标题 2.5 windowIcon 图标 2.6 windowOpacity 不透明度 2.7 cursor 光标 2.8 font 字体 2.9 toolTip 鼠标悬停提示 2.10 focusPolicy 焦…

1688代采下单API接口使用指南:实现商品采集与自动化下单

在电商领域&#xff0c;1688平台作为阿里巴巴旗下的批发采购平台&#xff0c;为众多商家提供了丰富的货源选择。为了提升采购效率&#xff0c;许多商家选择通过API接口实现商品采集与自动化下单。本文将详细介绍如何使用1688代采下单API接口&#xff0c;帮助开发者快速上手并实…

c++入门-------命名空间、缺省参数、函数重载

C系列 文章目录 C系列前言一、命名空间二、缺省参数2.1、缺省参数概念2.2、 缺省参数分类2.2.1、全缺省参数2.2.2、半缺省参数 2.3、缺省参数的特点 三、函数重载3.1、函数重载概念3.2、构成函数重载的条件3.2.1、参数类型不同3.2.2、参数个数不同3.2.3、参数类型顺序不同 前言…

PTA:使用指针方式求一个给定的m×n矩阵各行元素之和

本题要求编写程序&#xff0c;使用指针方式求一个给定的mn矩阵各行元素之和。&#xff08;例如&#xff1a;scanf("%d", *(matrix i) j); // 使用指针方式访问二维数组元素&#xff09; 输入格式: 输入第一行给出两个正整数m和n&#xff08;1<m<6, 1<n&…

MacOS安装Emacs

个人博客地址&#xff1a;MacOS安装Emacs | 一张假钞的真实世界 在MacOS X上可以使用Homebrew 安装Emacs&#xff1a; $ brew install emacs --with-cocoa 或者用MacPorts&#xff1a; $ sudo port install emacs-app OSX Emacs 网站提供了通用的二进制包。 前两种方法安装…

【蓝桥杯单片机】第十三届省赛第二场

一、真题 二、模块构建 1.编写初始化函数(init.c) void Cls_Peripheral(void); 关闭led led对应的锁存器由Y4C控制关闭蜂鸣器和继电器 2.编写LED函数&#xff08;led.c&#xff09; void Led_Disp(unsigned char ucLed); 将ucLed取反的值赋给P0 开启锁存器 关闭锁存…

消息中间件

1. Apache Kafka 核心特性 优点&#xff1a; 高吞吐量&#xff08;百万级TPS&#xff09;、低延迟&#xff08;毫秒级&#xff09;。分布式架构&#xff0c;支持水平扩展和高容错性。持久化存储&#xff08;基于磁盘的日志结构&#xff09;&#xff0c;支持流式数据处理。 缺…

iStatistica Pro for Mac v7.0 系统监控工具 支持M、Intel芯片

iStatistica Pro 应用介绍 iStatistica Pro v7.0 是一款 macOS 上的系统监控工具&#xff0c;专为帮助用户实时监控和分析电脑性能而设计。它提供了一个简洁、直观的界面&#xff0c;让用户轻松查看他们的 Mac 的各类硬件和软件状态。iStatistica Pro 让你随时了解 CPU、内存、…