mysql8.0使用MGR实现高可用与利用MySQL Router构建读写分离MGR集群

MGR是MySQL Group Replication的缩写,即MySQL组复制。

在以往,我们一般是利用MySQL的主从复制或半同步复制来提供高可用解决方案,但这存在以下几个比较严重的问题:

  1. 主从复制间容易发生复制延迟,尤其是在5.6以前的版本,以及当数据库实例中存在没有显式主键表时,很容易发生。

  2. 主从复制节点间的数据一致性无法自行实现最终一致性。

  3. 当主节点发生故障时,如果有多个从节点,无法自动从中选择合适的节点作为新的主节点。

  4. 如果采用(增强)半同步复制,那么当有个从节点因为负载较高、网络延迟或其他意外因素使得事务无法及时确认时,也会反过来影响主节点的事务提交。

MGR具备以下几个特点:

  1. 基于shared-nothing模式,所有节点都有一份完整数据,发生故障时可以直接切换。

  2. MGR提供了数据一致性保障,默认是最终一致性,可根据业务特征需要自行调整一致性级别。

  3. 支持在线添加、删除节点,节点管理更方便。

  4. 支持故障自动检测及自动切换,发生故障时能自动切换到新的主节点,再配合MySQL Router中间件,应用层无需干预或调整。

  5. 支持单节点、多节点写入两种模式,可根据架构或业务需要选择哪种方案,不过强烈建议选用单主模式。

安装MGR集群

系统为Rocky 8.10三台,IP地址分别为192.168.40.13{4..6}

cat >> /etc/hosts << EOF
192.168.40.134 134host
192.168.40.135 135host
192.168.40.136 136host
EOF

安装MySQL8

yum install mysql-server -y &> /dev/null

配置&启动

配置文件为vim /etc/my.cnf.d/mysql-server.cnf

配置内容和相关信息:(注:uuid可以在终端使用uuidgen直接生成然后复制过来即可)

#/etc/my.cnf*.d/mysql-server.cnf
[mysqld]
...
#开启GTID,必须开启
gtid_mode = ON
#强制GTID的一致性
enforce_gtid_consistency = ON
#binlog格式,MGR要求必须是ROW,不过就算不是MGR,也最好用
binlog_format = row
#server-id必须是唯一的
server-id = 133
#MGR使用乐观锁,所以官网建议隔离级别是RC,减少锁粒度
transaction_isolation = READ-COMMITTED
#因为集群会在故障恢复时互相检查binlog的数据,
#所以需要记录下集群内其他服务器发过来已经执行过的binlog,按GTID来区分是否执行过.
log-slave-updates = 1
#binlog校验规则,5.6之后的高版本是CRC32,低版本都是NONE,但是MGR要求使用NONE
binlog_checksum = NONE
#基于安全的考虑,MGR集群要求复制模式要改成slave记录记录到表中,不然就报错
master_info_repository = TABLE
#同上配套
relay_log_info_repository = TABLE
#组复制设置#记录事务的算法,官网建议设置该参数使用 XXHASH64 算法
transaction_write_set_extraction = XXHASH64
#相当于此GROUP的名字,是UUID值,不能和集群内其他GTID值的UUID混用,可用uuidgen来生成一个新的,
#主要是用来区分整个内网里边的各个不同的GROUP,而且也是这个group内的GTID值的UUID
loose-group_replication_group_name = '5dbabbe6-8050-49a0-9131-1de449167446'
#IP地址白名单,默认只添加127.0.0.1,不会允许来自外部主机的连接,按需安全设置
loose-group_replication_ip_whitelist = '127.0.0.1/8,192.168.40.0/24'
#是否随服务器启动而自动启动组复制,不建议直接启动,怕故障恢复时有扰乱数据准确性的特殊情况
loose-group_replication_start_on_boot = OFF
#本地MGR的IP地址和端口,host:port,是MGR的端口,不是数据库的端口
loose-group_replication_local_address = '192.168.40.150:33081'
#需要接受本MGR实例控制的服务器IP地址和端口,是MGR的端口,不是数据库的端口
loose-group_replication_group_seeds = '192.168.40.150:33081,192.168.40.133:33081,192.168.40.152:33081'
#开启引导模式,添加组成员,用于第一次搭建MGR或重建MGR的时候使用,只需要在集群内的其中一台开启,
loose-group_replication_bootstrap_group = OFF
#是否启动单主模式,如果启动,则本实例是主库,提供读写,其他实例仅提供读,如果为off就是多主模式了
loose-group_replication_single_primary_mode = ON
#多主模式下,强制检查每一个实例是否允许该操作,如果不是多主,可以关闭
#loose-group_replication_enforce_update_everywhere_checks = on

上面的配置在每个节点进行同样的配置,只需修改IP和server-id

然后查看密码:grep -i password /var/log/mysql/mysqld.log,发现里面是没有密码的

[root@localhost ~]# grep -i password /var/log/mysql/mysqld.log
2025-02-11T08:53:38.546214Z 6 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.

那我们直接登录,登录之后需要下载插件,使用命令:(终端)

mysql -e "install plugin group_replication soname 'group_replication.so'"

[root@localhost ~]# mysql -e "show plugins;" | grep "group_replication"
group_replication       ACTIVE  GROUP REPLICATION       group_replication.so    GPL

 以上就说明插件安装好了

接下来创建MGR服务专用账户,并准备配置MGR服务通道,明文创建用户的时候这个操作没必要记录binlog,每个mysql主机上面创建用户是为了后面可以开启多主模式

mysql> set session sql_log_bin=0;
mysql> create user 'test'@'%' identified with mysql_native_password by '@OPENlab123';
mysql> GRANT BACKUP_ADMIN, REPLICATION SLAVE ON *.* TO 'test'@'%';
#创建完用户后继续启用binlog记录
mysql> set session sql_log_bin=1;#配置MGR服务通道
#通道名字 group_replication_recovery 是固定的,不能修改
mysql> CHANGE MASTER TO MASTER_USER='test', MASTER_PASSWORD='@OPENlab123' FOR CHANNEL 'group_replication_recovery';

上面要在所有节点上面进行操作,接下来进入mysql配置

  • 当你首次启动Group Replication集群时,需要一个节点来初始化整个集群。这个节点被称为“引导节点”。

  • group_replication_bootstrap_group=ON 表示当前节点将作为引导节点,初始化一个新的集群。

  • 如果不设置为 ON,节点会尝试加入一个已经存在的集群,而此时集群尚未初始化,因此会报错。

所以启动命令为下:(后面设置为OFF,这一步是必要的,以确保后续加入的节点不会尝试初始化新的集群)

SET GLOBAL group_replication_bootstrap_group = ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group = OFF;

在mgr2\mgr3节点,进入mysql服务端,不需要SET GLOBAL group_replication_bootstrap_group = ON;

START GROUP_REPLICATION;

然后使用命令查看状态:SELECT * FROM performance_schema.replication_group_members;

 如果出现MEMBER_STATE都为ONLINE则表示成功启动,如果出现了RECOVERING字段,那么查看日志tail /var/log/mysql/mysqld.log,一般都是/etc/hosts文件配置问题,里面的主机名要和系统主机名一致

上图可知我的136host为primary其他为secondary,下面我们进行转为多主模式和切换单主主机

切换主节点

我们通过上图中的MEMBER_ID可以看到每台主机是不同的,我们使用命令进行切换:

这里切换为135host为主节点

select group_replication_set_as_primary('1db22c88-e8ee-11ef-b7ab-000c299b2989');

 这条命令可以在任何主机上执行,里面的那串数字就是MEMBER_ID,primary变为了135host

切换多主模式 

在任何主机上面执行命令:select group_replication_switch_to_multi_primary_mode();

 切换回单主模式

在任何主机上面执行命令:select group_replication_switch_to_single_primary_mode();

 添加新节点和删除节点

新增

首先,要先完成MySQL Server初始化,创建好MGR专用账户、设置好MGR服务通道等前置工作。步骤同上

接下来,直接执行命令 start group_replication 启动MGR服务即可,新增的节点会进入分布式恢复这个步骤,它会从已有节点中自动选择一个作为捐献者(donor),并自行决定是直接读取binlog进行恢复,还是利用Clone进行全量恢复。

为了降低对primary节点的影响,建议选择其他的Secondary节点

新增节点:IP 192.168.40.137 137host

mysql> set global clone_valid_donor_list='192.168.150.136:3306';

在这个节点先停掉mgr服务(如果你之前启用了的话),关闭super_read_only模式

stop group_replication;
set global super_read_only=0;
clone instance from 'test'@192.168.40.136:3306 identified by '@OPENlab123';

上面填写的端口值3306不是mgr服务的端口,全量复制完数据后,该节点会进行一次自动重启。之后执行start group_replication,就可以正常加入集群了。

删除

在命令行模式下,一个节点想退出MGR集群,直接执行 stop group_replication 即可,如果这个节点只是临时退出集群,后面还想加回集群,则执行 start group_replication 即可自动再加入。而如果是想彻底退出集群,则停止MGR服务后,执行 reset master; reset slave all; 重置所有复制(包含MGR)相关的信息就可以了。

重启MGR集群

正常情况下,MGR集群中的Primary节点退出时,剩下的节点会自动选出新的Primary节点。当最后一个节点也退出时,相当于整个MGR集群都关闭了。这时候任何一个节点启动MGR服务后,都不会自动成为Primary节点,需要在启动MGR服务前,先设置 group_replication_bootstrap_group=ON,使其成为引导节点,再启动MGR服务,它才会成为Primary节点,后续启动的其他节点也才能正常加入集群。可自行测试,这里不再做演示。参考上面的引导节点启动(启动完毕之后要group_replication_bootstrap_group=OFF关闭)

小结:

MGR和传统主从复制类似,在运行过程中主要关注各节点的运行状态,以及Secondary节点的事务是否有延迟。本文介绍如何监控MGR节点状态、事务状态等。

  • 表示各节点的状态,共有几种状态:ONLINE、RECOVERING、OFFLINE、ERROR、UNREACHABLE 等,下面分别介绍几种状态。

    • ONLINE,表示节点处于正常状态,可提供服务。

    • RECOVERING,表示节点正在进行分布式恢复,等待加入集群,这时候有可能正在从donor节点利用clone复制数据,或者传输binlog中。

    • OFFLINE,表示该节点当前处于离线状态。提醒,在正要加入或重加入集群时,可能也会有很短瞬间的状态显示为 OFFLINE。

    • ERROR,表示该节点当前处于错误状态,无法成为集群的一员。当节点正在进行分布式恢复或应用事务时,也是有可能处于这个状态的。当节点处于ERROR状态时,是无法参与集群事务裁决的。节点正在加入或重加入集群时,在完成兼容性检查成为正式MGR节点前,可能也会显示为ERROR状态。

    • UNREACHABLE,当组通信消息收发超时时,故障检测机制会将本节点标记为怀疑状态,怀疑其可能无法和其他节点连接,例如当某个节点意外断开连接时。当在某个节点上看到其他节点处于 UNREACHABLE 状态时,有可能意味着此时部分节点发生了网络分区,也就是多个节点分裂成两个或多个子集,子集内的节点可以互通,但子集间无法互通。

利用MySQL Router构建读写分离MGR集群

这里注重介绍利用MYSQL Router实现读写分离,读负载均衡和故障自动转移

建议把MySQL Router部署在应用服务器上,每个应用服务器都部署一套,这样应用程序可以直接连接本机IP,连接的效率更高,而且后端数据库发生变化时,程序端也无需修改IP配置。

部署MySQL Router

安装包去官网上面找对应和自己MySQL版本相同的安装(建议),安装选择mysql-router版本的

安装:rpm -ivh mysql-router-community-8.0.36-1.el8.x86_64.rpm

安装之后直接启动即可:systemctl enable --now mysqlrouter.service(开机自启)

[root@135host ~]# ps -ef | grep -v grep | grep mysqlrouter
mysqlro+   27361       1  0 12:23 ?        00:00:00 /usr/bin/mysqlrouter

上面可以看到已经是正常启动了(本人资源有限,就在安装的有MGR上的主机上将就安装)

mysqlrouter的初始化自动生成的配置文件是:/etc/mysqlrouter/mysqlrouter.conf

写入以下内容

cat >> /etc/mysqlrouter/mysqlrouter.conf    <<  EOF
[routing:write]
bind_address = 192.168.40.135#本地的IP地址
bind_port = 8001#自定义一个端口号用于监听读写
mode = read-write
destinations = 192.168.40.136:3306#目标MRG集群的primary主机
[routing:blanace]
bind_address = 192.168.40.135
bind_port = 8002#自定义一个端口用于监听读
mode = read-only
destinations = 192.168.40.135:3306,192.168.40.134:3306
EOF[root@135host ~]systemctl restart mysqlrouter.service#重启

确认分离效果:(创建用户只能在primary节点上面创建)

mysql> create user 'admin'@'%' identified with mysql_native_password by '@OPENlab123';
Query OK, 0 rows affected (0.09 sec)mysql> grant all on *.* to admin@'%';
Query OK, 0 rows affected (0.02 sec)

我们先使用命令在mysql终端中:

mysql> select MEMBER_ID,MEMBER_ROLE from performance_schema.replication_group_members;
+--------------------------------------+-------------+
| MEMBER_ID                            | MEMBER_ROLE |
+--------------------------------------+-------------+
| 165f4dc6-e8ee-11ef-bd10-000c29481d69 | PRIMARY     |
| 1db22c88-e8ee-11ef-b7ab-000c299b2989 | SECONDARY   |
| a9389006-e8ed-11ef-a2f2-000c29017dd6 | SECONDARY   |
+--------------------------------------+-------------+
3 rows in set (0.00 sec)

然后在可以远程登录安装的有MySQL Router的主机:如果登录的MEMBER_ID为PEIMARY的话则表明,写分离成功

mysql -uadmin -p@OPENlab123 -h192.168.40.135 -P8001
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 53
Server version: 8.0.36 Source distributionCopyright (c) 2000, 2024, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> select @@server_uuid;
+--------------------------------------+
| @@server_uuid                        |
+--------------------------------------+
| 165f4dc6-e8ee-11ef-bd10-000c29481d69 |
+--------------------------------------+
1 row in set (0.01 sec)

经验证连接到了PRIMARY节点上,而换8002端口,开两个线程连接的话,一个会到134,一个会到135

mysql> select @@server_uuid;
+--------------------------------------+
| @@server_uuid                        |
+--------------------------------------+
| 1db22c88-e8ee-11ef-b7ab-000c299b2989 |
+--------------------------------------+
1 row in set (0.00 sec)
mysql> select @@server_uuid;
+--------------------------------------+
| @@server_uuid                        |
+--------------------------------------+
| a9389006-e8ed-11ef-a2f2-000c29017dd6 |
+--------------------------------------+
1 row in set (0.01 sec)

总结:

本文介绍了如何利用MySQL Router实现读写分离、读负载均衡,以及故障自动转移,利用MySQL Router可以提升应用端的透明性,后端数据库发生一些变化时,应用端无需跟着频繁变更。

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

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

相关文章

【IC】AI处理器核心--第二部分 用于处理 DNN 的硬件设计

第 II 部分 用于处理 DNN 的硬件设计 第 3 章 关键指标和设计目标 在过去的几年里&#xff0c;对 DNN 的高效处理进行了大量研究。因此&#xff0c;讨论在比较和评估不同设计和拟议技术的优缺点时应考虑的关键指标非常重要&#xff0c;这些指标应纳入设计考虑中。虽然效率通常…

Flutter Gradle 命令式插件正式移除,你迁移旧版 Gradle 配置了吗?

在 Flutter 3.29 版本里官方正式移除了 Flutter Gradle Apply 插件&#xff0c;其实该插件自 3.19 起已被弃用&#xff0c;同时 Flutter 团队后续也打算把 Flutter Gradle 从 Groovy 转换为 Kotlin&#xff0c;并将其迁移到使用 AGP&#xff08;Android Gradle Plugin&#xff…

C++类和对象进阶:运算符重载深度详解

C类和对象进阶&#xff1a;运算符重载 前言引入运算符重载定义语法注意事项重载为全局函数重载为成员函数运算符重载的本质 默认赋值运算符重载(默认成员函数)编译器自己生成的赋值运算符重载函数需要自己实现的场景总结默认赋值运算符重载 拷贝构造函数和赋值重载的区分验证 总…

three.js 使用geojson ,实现中国地图区域,边缘流动效果

three.js 使用geojson &#xff0c;实现中国地图区域&#xff0c;边缘流动效果 在线链接&#xff1a;https://threehub.cn/#/codeMirror?navigationThreeJS&classifyexpand&idgeoBorder 国内站点预览&#xff1a;http://threehub.cn github地址: https://github.co…

PortSwigger——WebSockets vulnerabilities

文章目录 一、WebSockets二、Lab: Manipulating WebSocket messages to exploit vulnerabilities三、Lab: Manipulating the WebSocket handshake to exploit vulnerabilities四、Using cross-site WebSockets to exploit vulnerabilities4.1 跨站WebSocket劫持&#xff08;cro…

【数据结构初阶第十节】队列(详解+附源码)

好久不见。。。别不开心了&#xff0c;听听喜欢的歌吧 必须有为成功付出代价的决心&#xff0c;然后想办法付出这个代价。云边有个稻草人-CSDN博客 目录 一、概念和结构 二、队列的实现 Queue.h Queue.c test.c Relaxing Time&#xff01; ————————————《有没…

AVL树:高效平衡的二叉搜索树

&#x1f31f; 快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。&#x1f31f; 引言&#x1f914; 在数据结构的奇妙世界里&#xff0c;二叉搜索树&#xff08;BST&#xff09;原本是查找数据的好帮手。想象一下…

Qt Designer菜鸟使用教程(实现一个本地英文翻译软件)

1 安装Qt Designer 安装这个包的时候会自带安装 Qt Designer, 安装目录为python的安装根目录的 Lib/site-packages/qt5_applications/Qt/bin 目录下。 pip install pyqt5-tools2 新建窗体 2.1 新建主窗体 创建之后如下图&#xff1a; 设置主窗口大小&#xff1a; 设置窗…

机械学习基础-5.分类-数据建模与机械智能课程自留

data modeling and machine intelligence - CLASSIFICATION 为什么我们不将回归技术用于分类&#xff1f;贝叶斯分类器&#xff08;The Bayes Classifier&#xff09;逻辑回归&#xff08;Logistic Regression&#xff09;对逻辑回归的更多直观理解逻辑 /sigmoid 函数的导数我们…

C++ 网络编程

1. socket Socket 是一种用于网络通信的编程接口&#xff0c;它提供了一种类似于文件描述符的接口&#xff0c;允许不同计算机之间的进程进行通信。Socket 可以工作在多种协议上&#xff0c;最常用的是 TCP/IP 和 UDP/IP 协议 1.1 UDP 1.1.1 概念 UDP&#xff08;用户数据报协…

C/C++内存管理

目录 前言 1、C/C内存划分 2、C语言中的动态内存管理方式 3、C内存管理方式 3.1操作内置类型 3.2操作自定义类型 3.3为什么对应的new和delete必须搭配使用&#xff08;了解&#xff09; 4、operator new与operator delete函数 5、new和delete的实现原理 5.1内置类型 5…

微软开源GraphRAG的使用教程-使用自定义数据测试GraphRAG

微软在今年4月份的时候提出了GraphRAG的概念&#xff0c;然后在上周开源了GraphRAG,Github链接见https://github.com/microsoft/graphrag,截止当前&#xff0c;已有6900Star。 安装教程 官方推荐使用Python3.10-3.12版本&#xff0c;我使用Python3.10版本安装时&#xff0c;在…

RK3568平台开发系列讲解(调试篇)网卡队列均衡负载

🚀返回专栏总目录 文章目录 一、RPS 的介绍1. RPS 的工作原理2. RPS 配置3. 启用和调优 RPS4. RPS 优势二、下行测试iperf测试沉淀、分享、成长,让自己和他人都能有所收获!😄 RPS(Receive Packet Steering) 是一种用于提高网络接收性能的技术,通常用于多核处理器系统中…

RagFlow + Docker Desktop + Ollama + DeepSeek-R1本地部署自己的本地AI大模型工具

前期准备 首先&#xff0c;我们需要下载 Ollama 以及配置相关环境。 Ollama 的 GitHub仓库 &#xff08;https://github.com/ollama/ollama&#xff09;中提供了详细的说明&#xff0c;简单总结如下: Step1&#xff1a;下载 Ollama 下载&#xff08;https://ollama.com/dow…

变分边界详解

起因 当时看VAE论文时有这么一段&#xff0c;但是看完直接一头雾水&#xff0c;这都那跟哪&#xff0c;第一个公式咋做的变换就变出那么一堆。网上搜了很多博客都语焉不详&#xff0c;只好自己来写一篇&#xff0c;希望能解答后来人的疑惑。 公式1 参考文章&#xff1a;证据…

云消息队列 ApsaraMQ Serverless 演进:高弹性低成本、更稳定更安全、智能化免运维

如今&#xff0c;消息队列已成为分布式架构中不可或缺的关键服务&#xff0c;为电商、物联网、游戏和教育等行业&#xff0c;提供了异步解耦、集成、高性能和高可靠的核心价值。 过去一年&#xff0c;我们发布了云消息队列 ApsaraMQ 全系列产品 Serverless 化&#xff0c;面向…

【蓝桥杯嵌入式】8_IIC通信-eeprom读写

全部代码网盘自取 链接&#xff1a;https://pan.baidu.com/s/1PX2NCQxnADxYBQx5CsOgPA?pwd3ii2 提取码&#xff1a;3ii2 1、电路图 这个电路允许通过I2C总线与EEPROM(M24C02-WMN6TP)和数字电位器(MCP4017T-104ELT)进行通信。EEPROM用于存储数据&#xff0c;而数字电位器可以用…

DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件

1 DeepSeek处理自有业务的案例&#xff1a;让AI给你写一份小众编辑器(EverEdit)的语法着色文件 1.1 背景 AI能力再强&#xff0c;如果不能在企业的自有业务上产生助益&#xff0c;那基本也是一无是处。将企业的自有业务上传到线上训练&#xff0c;那是脑子进水的做法&#xff…

Java常用设计模式面试题总结(内容详细,简单易懂)

设计模式的分类 创建型模式&#xff1a;通过隐藏对象创建的细节&#xff0c;避免直接使用 new 关键字实例化对象&#xff0c;从而使程序在判断和创建对象时更具灵活性。常见的模式包括&#xff1a; 工厂模式抽象工厂模式单例模式建造者模式原型模式 结构型模式&#xff1a;通…

使用HX搭建UNI-APP云开发项目(适合新手小白与想学云开发的宝子)

什么是uni-app云开发 uni-app云开发是uni-app提供的一套后端服务,它可以帮助开发者快速搭建起一个完整的后端服务,包括数据库、云函数、存储等。开发者只需要关注前端页面的开发,后端服务由uni-app云开发提供。 uni-app云开发的优势: 快速搭建后端服务:uni-app云开发提供了…