当前位置: 首页 > news >正文

MySQL高可用之ProxySQL + MGR 实现读写分离实战

部署MGR

1、MGR 前置介绍

阿里云RDS集群方案用的就是MGR模式!

1.1、什么是 MGR

  • MGR(MySQL Group Replication)是MySQL 5.7.17版本诞生的,是MySQL自带的一个插件,可以灵活部署。
  • 保证数据一致性又可以自动切换,具备故障检测功能、支持多节点写入。
  • 集群是多个MySQL Server节点共同组成的分布式集群,每个Server都有完整的副本,它是基于ROW格式的二进制日志文件和GTID特性。

1.2、MGR 优点

  • 强一致性:基于原生复制及paxos协议的组复制技术,并以插件的方式提供,提供一致数据安全保证。
  • 高容错性:只要不是大多数节点坏掉就可以继续工作,有自动检测机制,当不同节点产生资源争用冲突时,不会出现错误,按照先到者优先原则进行处理,并且内置了自动化脑裂防护机制。
  • 高扩展性:节点的新增和移除都是自动的,新节点加入后,会自动从其他节点上同步状态,直到新节点和其他节点保持一致,如果某节点被移除了,其他节点自动更新组信息,自动维护新的组信息。
  • 灵活性:有单主模式和多主模式。单主模式下,会自动选主,所有更新操作都在主上进行;多主模式下,所有server都可以同时处理更新操作。工作中优先使用单主模式!

1.3、MGR 缺点

  • 仅支持InnoDB表,并且每张表一定要有一个主键,用于做write set的冲突检测。
  • 必须打开GTID特性,二进制日志格式必须设置为ROW,用于选主与write set;主从状态信息存于表中(–master-info-repository=TABLE 、–relay-log-inforepository=TABLE),–log-slave-updates打开。
  • MGR不支持大事务,事务大小最好不超过143MB,当事务过大,无法在5秒的时间内通过网络在组成员之间复制消息,则可能会怀疑成员失败了,然后将其驱逐出局。
  • 目前一个MGR集群最多支持9个节点。
  • 不支持外键于save point特性,无法做全局间的约束检测与部分事务回滚。
  • 二进制日志不支持Binlog Event Checksum。

1.4、MGR 适用场景

  • 金融交易、重要数据存储、对主从一致性要求高的场景。
  • 核心数据总量未过亿。
  • 读多写少,如:互联网电商。

2、MySQL MGR 搭建流程

2.1、环境准备

本次集群搭建,我使用3台阿里云ECS服务器(CentOS 7.9,2核2G,20G硬盘),每台服务器都分配公网IP,开放安全组:22(SSH)、3306(MySQL)、24901(MGR)。我的服务器配置如下:

Master服务器(hostname:n0):172.21.180.98
Slave服务器1(hostname:n1):172.21.180.99
Slave服务器2(hostname:n2):172.21.180.100

2.2、搭建流程

2.2.1、配置系统环境

将Hosts文件写入n0/n1/n2节点与内网IP对应关系,后面配置采用域名访问:

复制代码

# 3台服务器都执行
sudo cat > /etc/hosts <<-'EOF'
172.21.180.98 n0
172.21.180.99 n1
172.21.180.100 n2
EOF

复制代码

分别为三台服务器依次设置主机名称,三台服务器执行命令:

复制代码

# 第1台服务器
hostnamectl set-hostname n0# 第2台服务器
hostnamectl set-hostname n1# 第3台服务器
hostnamectl set-hostname n2

复制代码

2.2.2、安装 MySQL

下载 MySQL 官方YUM仓库源(这个并不是安装MySQL):

# 3台服务器都执行
cd /home/
wget --no-check-certificate https://repo.mysql.com/mysql80-community-release-el7-5.noarch.rpm
yum localinstall -y mysql80-community-release-el7-5.noarch.rpm

修改仓库配置,将下图中gpgcheck置为0:

vi /etc/yum.repos.d/mysql-community.repo

安装 MySQL 8.0.26:

# 3台服务器都执行
yum install -y mysql-community-server-8.0.26
2.2.3、配置启动 MySQL

主节点n0执行:直接CV就行,不要墨迹!

复制代码

# 修改 MySQL 配置
sudo cat >> /etc/my.cnf <<-'EOF'# 使用mysql_native_password密码策略,防止navicat连不上mysql8
default_authentication_plugin=mysql_native_password
# 设置MySQL插件目录:MGR基于插件,必须设置插件路径
plugin_dir=/usr/lib64/mysql/plugin
# 服务器编号,Master=1
server_id=1
# 开启binlog的GTID模式(MGR强制要求)
gtid_mode=ON
# 开启后MySQL只允许能够保障事务安全,并且能够被日志记录的SQL语句被执行
enforce_gtid_consistency=ON
# 关闭binlog校验(MGR强制要求)
binlog_checksum=NONE# 定义用于事务期间哈希写入提取的算法,组复制模式下必须设置为 XXHASH64。
transaction_write_set_extraction=XXHASH64
# 确定组复制恢复时是否应该应用 SSL,通常设置为“开”,但默认设置为“关”。
loose-group_replication_recovery_use_ssl=ON
# 服务器实例所在复制组名称,必须是有效的 UUID,所有节点必须相同。
loose-group_replication_group_name="bbbbbbbb-bbbb-cccc-dddd-eeeeeeeeeeee"
# 确定服务器是否应该在服务器启动期间启动组复制。
loose-group_replication_start_on_boot=OFF# 为复制组中其他的成员提供的网络地址,指定为“主机:端口”的格式化字符串。
# 很多人想当然认为端口应该是3306,起始不然,MGR需要开启新端口24901同步交换
# 所以这里不要写错,同时,前面我们配置了hosts文件做了主机名与IP的映射,这里直接写主机名即可
loose-group_replication_local_address="n0:24901"# 用于建立新成员到组的连接组成员列表。
# 这个列表指定为由分隔号间隔的组成员网络地址列表,类似 host1:port1、host2:port2 的格式。
# 同样采用n0~n2的主机名替代
loose-group_replication_group_seeds="n0:24901,n1:24901,n2:24901"# 配置此服务器为引导组,这个选项必须仅在一台服务器上设置,
# 并且仅当第一次启动组或者重新启动整个组时。成功引导组启动后,将此选项设置为关闭。
loose-group_replication_bootstrap_group=OFF
EOF

复制代码

从节点n1执行:直接CV就行,不要墨迹!

复制代码

sudo cat >> /etc/my.cnf <<-'EOF'
default_authentication_plugin=mysql_native_password
plugin_dir=/usr/lib64/mysql/plugin# 设置唯一的服务器编号
server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE# 这个参数决定primary节点到secondary节点的请求是否为基于 RSA 密钥对的密码交换所需的公钥
loose-group_replication_recovery_get_public_key=ON
loose-group_replication_recovery_use_ssl=ON
loose-group_replication_group_name="bbbbbbbb-bbbb-cccc-dddd-eeeeeeeeeeee"
loose-group_replication_start_on_boot=OFF# 设置本机地址n1:24901
loose-group_replication_local_address="n1:24901"
loose-group_replication_group_seeds="n0:24901,n1:24901,n2:24901"
loose-group_replication_bootstrap_group=OFF
EOF

复制代码

从节点n2执行:直接CV就行,不要墨迹!

复制代码

sudo cat >> /etc/my.cnf <<-'EOF'
default_authentication_plugin=mysql_native_password
plugin_dir=/usr/lib64/mysql/plugin#设置唯一的服务器编号
server_id=3
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE#这个参数决定primary节点到secondary节点的请求是否为基于 RSA 密钥对的密码交换所需的公钥
loose-group_replication_recovery_get_public_key=ON
loose-group_replication_recovery_use_ssl=ON
loose-group_replication_group_name="bbbbbbbb-bbbb-cccc-dddd-eeeeeeeeeeee"
loose-group_replication_start_on_boot=OFF#设置本机地址n2:24901
loose-group_replication_local_address="n2:24901"
loose-group_replication_group_seeds="n0:24901,n1:24901,n2:24901"
loose-group_replication_bootstrap_group=OFF
EOF

复制代码

三台服务器,依次启动 MySQL

# 3台服务器都执行
systemctl start mysqld
2.2.4、修改密码、设置主从同步

三台服务器,依次通过该命令,获取数据库连接密码:

# 获取数据库密码
grep 'temporary password' /var/log/mysqld.log

三台服务器,连接到数据库控制台中:

# 连接数据库
mysql -uroot -p'密码'

三台数据库控制台中,都执行下述命令(3台服务器都执行):

复制代码

# 修改root密码为asAS123456!
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'asAS123456!';
# 创建rpl_user账户,此账户用于实现主从数据同步
CREATE USER rpl_user@'%' IDENTIFIED BY 'asAS123456!';
# 赋予主从同步权限
GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';# 创建一个远程连接用户,这个用户用在Navcate、JDBC登录的时候,直接用root登录不好
create user 'remote'@'%' identified with mysql_native_password by 'asAS123456!';
# 为remote用户赋予所有数据库资源的访问权限,熟悉grant的小伙伴可以自己调整
grant all privileges on *.* to remote@'%';# 让刚才的修改生效
FLUSH PRIVILEGES;# 删除已产生的Binlog
# 一定要RESET MASTER,它会删除刚才已产生的Binlog
# 因为刚才Binglog包含创建用户这种高权限操作,用于主从同步的rpl_user账户是没有权限执行的
# 这就会导致RelayLog重放无法正确执行,导致从属服务器卡死在"RECEVERING"状态
# 利用RESET MASTER删除这些无法执行的binlog,就没问题了
RESET MASTER;

复制代码

2.2.5、安装 MGR 插件

在三台服务器的MySQL控制台中,安装MGR插件,执行命令:

# 3台服务器都执行
INSTALL PLUGIN group_replication SONAME 'group_replication.so';

在主服务器的MySQL控制台上,执行下述命令:

复制代码

# 注意:只在主服务器上运行
# 我们在 primary.cnf 配置文件中把 group_replication_bootstrap_group 参数设置成 OFF
# 在 primary 服务器启动时并不会直接启动复制组,通过下面的命令动态的开启复制组使我们的集群更安全
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;

复制代码

在两个从服务器MySQL控制台上,执行下述命令:

复制代码

# 指定主从账户与指定通信频道
CHANGE MASTER TO MASTER_USER="rpl_user", MASTER_PASSWORD="asAS123456!" FOR CHANNEL 'group_replication_recovery';# 开启组网数据同步
START GROUP_REPLICATION;

复制代码

当两个从节点都运行完毕后,运行下面SQL结果进行验证:

SELECT * FROM performance_schema.replication_group_members;

出现以下情况,每个节点都是ONLINE状态,说明集群搭建成功:

3、MySQL MGR 故障转移

上面已经将MySQL MGR集群搭建完毕,并且节点都是ONLINE状态。

3.1、主节点n0下线,重新选举

首先,在主服务器n0上执行停止mysql命令,如下:

systemctl stop mysqld;

此时,在从节点n1查看集群状态发现,n1被选举为主节点:

这是由于MGR集群选举策略为:

·优先低版本节点
·版本一样,优先权重大的节点
·版本与权重一样,按照 server uuid 的字母顺序选主

在n1从节点上,通过命令查看故障转移日志:

# 查看MySQL日志
tail -n 50 /var/log/mysqld.log

n1日志解析如下:

复制代码

# n0:3306(主节点n0)从组中被移除掉
[Warning] [MY-011499] [Repl] Plugin group_replication reported: 'Members removed from the group: n0:3306'# 重新选举新的 Primary 主节点
[System] [MY-011500] [Repl] Plugin group_replication reported: 'Primary server with address n0:3306 left the group. Electing new Primary.'# n1:3306(从节点n1)被选举为主节点,执行之前未完成的事务处理
[System] [MY-011507] [Repl] Plugin group_replication reported: 'A new primary with address n1:3306 was elected. The new primary will execute all previous group transactions before allowing writes.'# 组成员目前只剩 n1:3306, n2:3306
[System] [MY-011503] [Repl] Plugin group_replication reported: 'Group membership changed to n1:3306, n2:3306 on view 17172171443362674:4.'# 关闭 n1 节点的只读状态
[System] [MY-013731] [Repl] Plugin group_replication reported: 'The member action "mysql_disable_super_read_only_if_primary" for event "AFTER_PRIMARY_ELECTION" with priority "1" will be run.'# 设置 super_read_only=OFF
[System] [MY-011566] [Repl] Plugin group_replication reported: 'Setting super_read_only=OFF.'# 当前节点(n1)以主节点身份工作
[System] [MY-011510] [Repl] Plugin group_replication reported: 'This server is working as primary member.'

复制代码

在n2从节点上,通过命令查看故障转移日志:

# 查看MySQL日志
tail -n 50 /var/log/mysqld.log

n2日志解析如下:

复制代码

# n0:3306(主节点n0)从组中被移除掉
[Warning] [MY-011499] [Repl] Plugin group_replication reported: 'Members removed from the group: n0:3306'# 重新选举新的 Primary 主节点
[System] [MY-011500] [Repl] Plugin group_replication reported: 'Primary server with address n0:3306 left the group. Electing new Primary.'# n1:3306(从节点n1)被选举为主节点,执行之前未完成的事务处理
[System] [MY-011507] [Repl] Plugin group_replication reported: 'A new primary with address n1:3306 was elected. The new primary will execute all previous group transactions before allowing writes.'# 组成员目前只剩 n1:3306, n2:3306
[System] [MY-011503] [Repl] Plugin group_replication reported: 'Group membership changed to n1:3306, n2:3306 on view 17172171443362674:4.'# 当前节点(n2)作为主节点(n1)的从成员身份工作
[System] [MY-011511] [Repl] Plugin group_replication reported: 'This server is working as secondary member with primary member address n1:3306.'

复制代码

3.2、新主节点n1下线,集群不可用

当在新晋升的主节点n1上执行停止MySQL操作:

systemctl stop mysqld;

此时,在n2上通过命令查看发现,n1主节点尽管已经下线,但n2查看集群状态时还在显示,因为只有1个节点的情况下,少于n/2+1的规则,导致整体 MGR 集群失效,n2节点无法产生重新选举,同时n2的日志也不会有任何新内容产生:

SELECT * FROM performance_schema.replication_group_members;

3.3、恢复 MGR 集群

恢复流程很简单,先将三台服务器的MySQL各自重启:

# 3台服务器都执行
systemctl restart mysqld;

然后重复执行 2.2.5 章节流程即可恢复 MGR 集群。

4、单主模式和多主模式

4.1、模式介绍

4.1.1、单主模式

在单主模式下, 组复制具有自动选主功能,每次只有一个 server成员可以作为主节点。

单主模式 group 内只有一台节点可写可读,其他节点只可以读。对于group的部署,需要先跑起primary主节点,然后再跑起其他的节点,并把这些节点加进group。其他的节点就会自动同步primary节点上面的变化,然后将自己设置为只读模式。

当primary主节点意外宕机或者下线,在满足大多数节点存活的情况下,group内部发起选举,选出下一个可用的读节点,提升为primary节点。

4.1.2、多主模式

在多主模式下,所有的 MySQL 节点都可以同时接受读写操作。group内的所有节点都是primary主节点,同时可以进行读写操作,并且数据是最终一致的。

4.2、模式切换

之前我们搭建的 MySQL MGR 集群就是单主模式(默认),那么如何切换为多主模式呢?按照如下操作进行。

4.2.1、单主 ——> 多主

从 n0 ~ n2 停止组复制,开启多主模式(3个节点都执行):

复制代码

# 停止组复制
stop group_replication;# 是否启用单主模式,默认ON,OFF代表多主
set global group_replication_single_primary_mode=OFF;# 是否开启条件检查,因为多主的约束更为严格,不符合要求的直接拒绝
# 不支持外键的级联操作
# 不支持“串行化Serializable”
set global group_replication_enforce_update_everywhere_checks=ON;

复制代码

在 n0 主节点启用组复制:

# 只在 n0 上执行
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;

在 n1,n2 节点上启用组复制:

# 只在 n1, n2 上执行
START GROUP_REPLICATION;

此时,可以看到三台MySQL都是主节点:

SELECT * FROM performance_schema.replication_group_members;

4.2.2、多主 ——> 单主

从 n0 ~ n2 停止组复制,开启单主模式(3个节点都执行):

复制代码

# 停止组复制
stop group_replication;# 是否开启条件检查,因为多主的约束更为严格,不符合要求的直接拒绝
# 不支持外键的级联操作
# 不支持“串行化Serializable”
set global group_replication_enforce_update_everywhere_checks=OFF;# 是否启用单主模式,默认ON,OFF代表多主
set global group_replication_single_primary_mode=ON;

复制代码

在 n0 主节点启用组复制:

# 只在 n0 上执行
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;

在 n1,n2 节点上启用组复制:

# 只在 n1, n2 上执行
START GROUP_REPLICATION;

此时,可以看到三台MySQL变成了主从模式:

SELECT * FROM performance_schema.replication_group_members;

MGR部署参考:https://blog.csdn.net/weixin_46594796/article/details/139321738

部署ProxySQL 实现MGR读写分离

1、ProxySQL 介绍

1.1、ProxySQL 如何工作

ProxySQL 和 ShardingJDBC 类似竞品关系,国内使用 ShardingJDBC 更多,国外使用 ProxySQL 更多。
ProxySQL 主要能够提供:读写分离 + 故障转移
ShardingJDBC 主要能够提供:读写分离 + 分库分表
所以很多场景会考虑将 ProxySQL 和 ShardingJDBC + MySQL MGR 一起使用,通过 ProxySQL 提供读写分离 + 故障转移,通过 ShardingJDBC 提供分库分表(不需要再提供读写分离),非常优雅!

当我们搭建好了MGR集群,由于组复制的存在,保证每个节点的数据都是强一致的。不会出现主节点有数据,而从节点没有数据的情况。主节点可读可写,从节点只负责读操作,这是经典的MGR集群方案:

不过,试想这样一种情况,当主节点发生宕机,MGR集群虽然虽然可以自动进行故障转移,重新选举新的主节点,但是Java应用不能感知到数据库发生了宕机现象,依旧会把写操作发送给宕机的主节点,此时就会发生错误。

针对这种情况,ProxySQL就发挥出了作用,通过ProxySQL自动对MGR集群进行健康状态感知。

使用ProxySQL时,如果主服务器发生了宕机,会将写入请求转移到故障转移到新晋升的主节点上,并且提供了读写分离功能。

1.2、ProxySQL 工作原理

ProxySQL对于MGR集群节点,都新增了一个数据库用户,例如:monitor。ProxySQL通过monitor用户定时发送select查询请求,判断当前数据库节点是否可以,如果出现3次不能执行select查询,就认为该节点产生故障,就需要从集群中移除。

不过此时有个问题,就是ProxySQL如何判断哪个节点是主,哪个节点是从呢?ProxySQL要求每个MGR集群中的节点都在各自服务器上创建视图,作用是收集当前节点运行状态,判断当前节点是主是从。

当ProxySQL知道了主从之后,此时Java应用进行SQL操作,就会被ProxySQL进行路由分发了!

2、ProxySQL 安装

我这里使用一台阿里云ECS(2核2G),开放22、6032、6033端口号。

首先,下载ProxySQL安装包,进行安装操作:

复制代码

# 下载 ProxySQL 安装包(这里是通过oss直接下载的,也可以通过官方下载,不过很慢)
wget --no-check-certificate https://manongbiji.oss-cn-beijing.aliyuncs.com/ittailkshow/mgr/download/proxysql-2.2.0-1-centos7.x86_64.rpm# 安装 ProxySQL
cd /home/
yum localinstall -y proxysql-2.2.0-1-centos7.x86_64.rpm

复制代码

启动 ProxySQL 服务,可以发现启动完毕:

# 启动 ProxySQL
service proxysql start

安装MySQL YUM仓库源:

cd /home/
wget --no-check-certificate https://repo.mysql.com/mysql80-community-release-el7-5.noarch.rpm
yum localinstall -y mysql80-community-release-el7-5.noarch.rpm
sudo yum makecache fast

将 MySQL 8 下载地址调整为腾讯云镜像(否则下载速度KB维度):

# 修改配置
vim /etc/yum.repos.d/mysql-community.repo
# 将 mysql80-community 的 baseurl 内容替换如下
https://mirrors.cloud.tencent.com/mysql/yum/mysql-8.0-community-el7-x86_64/
# 将 mysql80-community 的 gpgcheck 内容替换为 0

配置好镜像后,安装好MySQL YUM源,就可以下载MySQL客户端了:

yum install -y mysql-community-client

3、ProxySQL + MGR 读写分离

3.1、读写分离配置

通过上述操作,前置准备已完成,此时链接上ProxySQL:

mysql -u admin -padmin -h 127.0.0.1 -P6032 --prompt='Admin> '

接着,将MGR集群节点配置到ProxySQL中,使用的是MGR节点的内网ip:

复制代码

# 我的MGR集群的三个节点内网IP分别是:172.21.180.98 | 172.21.180.99 | 172.21.180.100
insert into mysql_servers(hostgroup_id,hostname,port) values (10,'172.21.180.98',3306);
insert into mysql_servers(hostgroup_id,hostname,port) values (10,'172.21.180.99',3306);
insert into mysql_servers(hostgroup_id,hostname,port) values (10,'172.21.180.100',3306);# 启用上述配置 + 持久化保存
load mysql servers to runtime;
save mysql servers to disk;

复制代码

接下来这步需要在MGR主节点上进行,配置会通过主节点同步到其他从属节点:

复制代码

# 使用 sys 数据库
use sys;# MySQL降低密码强度
set global validate_password.policy=0;
set global validate_password.length=4;# 创建角色(monitor监听运行状态,proxysql是java应用连接账号)
CREATE USER 'monitor'@'%' IDENTIFIED BY "monitor@1025";
CREATE USER 'proxysql'@'%' IDENTIFIED BY "proxysql@1025";
GRANT ALL PRIVILEGES ON *.* TO 'monitor'@'%' ;
GRANT ALL PRIVILEGES ON *.* TO 'proxysql'@'%' ;
FLUSH PRIVILEGES;

复制代码

从这里使用Navicat进入sys数据库,连接到MGR主节点上,创建视图(一段一段执行,用Navicat是因为避免控制台出现ERROR):

# 创建函数
CREATE FUNCTION my_id() RETURNS TEXT(36) DETERMINISTIC NO SQL RETURN (SELECT @@global.server_uuid as my_id);

复制代码

# 函数:判断是否是主分区
CREATE FUNCTION gr_member_in_primary_partition()RETURNS VARCHAR(3)DETERMINISTICBEGINRETURN (SELECT IF( MEMBER_STATE='ONLINE' AND ((SELECT COUNT(*) FROMperformance_schema.replication_group_members WHERE MEMBER_STATE NOT IN ('ONLINE', 'RECOVERING')) >=((SELECT COUNT(*) FROM performance_schema.replication_group_members)/2) = 0),'YES', 'NO' ) FROM performance_schema.replication_group_members JOINperformance_schema.replication_group_member_stats USING(member_id) where member_id=my_id());
END

复制代码

复制代码

# 创建视图
CREATE VIEW gr_member_routing_candidate_status AS SELECT
sys.gr_member_in_primary_partition() as viable_candidate,
IF( (SELECT (SELECT GROUP_CONCAT(variable_value) FROM
performance_schema.global_variables WHERE variable_name IN ('read_only',
'super_read_only')) != 'OFF,OFF'), 'YES', 'NO') as read_only,
Count_Transactions_Remote_In_Applier_Queue as transactions_behind, Count_Transactions_in_queue as 'transactions_to_cert'
from performance_schema.replication_group_member_stats where member_id=my_id();

复制代码

此时,回到ProxySQL服务器控制台上,设置监控账号:

set mysql-monitor_username='monitor';
set mysql-monitor_password='monitor@1025';
insert into mysql_users(username,password,active,default_hostgroup,transaction_persistent) values('proxysql','proxysql@1025',1,10,1);

设置读写组:

复制代码

# 主负责写、从负责读,当MGR主库切换后,代理自动识别主从。
# ProxySQL代理每一个后端MGR集群时,都必须为这个MGR定义写组10、备写组20、读组30、离线组40,
# 注意:max_transactions_behind 是设置延迟大小,可以给大点,建议自己去开个并行复制。
insert into mysql_group_replication_hostgroups (writer_hostgroup,backup_writer_hostgroup,reader_hostgroup,
offline_hostgroup,active,max_writers,writer_is_also_reader,max_transactions_behind) values (10,20,30,40,1,1,0,100);

复制代码

启用规则:

复制代码

load mysql servers to runtime;
save mysql servers to disk;
load mysql users to runtime;
save mysql users to disk;
load mysql variables to runtime;
save mysql variables to disk;

复制代码

状态校验,编号为10是主节点,编号为30是从节点:

select hostgroup_id, hostname, port,status from runtime_mysql_servers;

进行读写分离配置:

# select for update走主节点,其他select走从节点
# 其他 insert update delete 走主节点
insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)
VALUES (1,1,'^SELECT.*FOR UPDATE$',10,1),(2,1,'^SELECT',30,1);
# 配置加载 + 持久化
load mysql query rules to runtime;
save mysql query rules to disk;

3.2、读写分离测试

这里注意,进行读写分离实战测试时,要连接ProxySQL 6033端口,6032是Admin,6033才是客户端(Java程序也连6033!):

复制代码

# 链接 ProxySQL 6033
mysql -uproxysql -pproxysql@1025 -h127.0.0.1 -P6033# 创建一个test数据库,查询一条数据,写一条数据
use test;
select * from test;
insert into test values(20);
select * from test for update;# 回到6032,查看路由日志
mysql -uadmin -padmin -h127.0.0.1 -P6032
select hostgroup,digest_text from stats_mysql_query_digest order by digest_text desc limit 10;

复制代码

可以看到,读写分离成功!

3.3、SpringBoot 整合

到这里说一下大家可能关注的点,就是ProxySQL + MySQL MGR`整合完毕后,如何通过SpringBoot进行整合,其实很简单。

只需要将SpringBoot的yml配置文件中配置连接到ProxySQL就可以了

复制代码

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://123.56.41.203:6033/quick_chat?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false&rewriteBatchedStatements=trueusername: proxysqlpassword: proxysql@1025

复制代码

如果运行期间出现以下错误,要么mysql驱动版本号不对,要么就是ProxySQL需要调整了:

proxysql Caused by: java.sql.SQLException: Unknown system variable 'query_cache_size'

如果要调整ProxySQL,请执行如下命令,即可解决上述问题:

复制代码

# 连接到Proxy 6032
mysql -uadmin -padmin -h127.0.0.1 -P6032# 解决 Unknown system variable 'query_cache_size' 问题
update global_variables set variable_value='8.0.4 (ProxySQL)' where variable_name='mysql-server_version';
load mysql variables to run;save mysql variables to disk;

复制代码

行业拓展

分享一个面向研发人群使用的前后端分离的低代码软件——JNPF。

基于 Java Boot/.Net Core双引擎,它适配国产化,支持主流数据库和操作系统,提供五十几种高频预制组件,内置了常用的后台管理系统使用场景和实用模版,通过简单的拖拉拽操作,开发者能够高效完成软件开发,提高开发效率,减少代码编写工作。

JNPF基于SpringBoot+Vue.js,提供了一个适合所有水平用户的低代码学习平台,无论是有经验的开发者还是编程新手,都可以在这里找到适合自己的学习路径。

此外,JNPF支持全源码交付,完全支持根据公司、项目需求、业务需求进行二次改造开发或内网部署,具备多角色门户、登录认证、组织管理、角色授权、表单设计、流程设计、页面配置、报表设计、门户配置、代码生成工具等开箱即用的在线服务。

 

相关文章:

MySQL高可用之ProxySQL + MGR 实现读写分离实战

部署MGR 1、MGR 前置介绍 阿里云RDS集群方案用的就是MGR模式&#xff01; 1.1、什么是 MGR MGR&#xff08;MySQL Group Replication&#xff09;是MySQL 5.7.17版本诞生的&#xff0c;是MySQL自带的一个插件&#xff0c;可以灵活部署。保证数据一致性又可以自动切换&#x…...

React TS中如何化简DOM事件的定义

概要 我们在做TS开发时候&#xff0c;总要面对各种类型的定义。React使用自己的Sythetic Event机制管理DOM事件&#xff0c;不同于原生的DOM事件定义&#xff0c;所以在TS中&#xff0c;事件的类型定义更加繁琐。 本文提供一中简化定义的方法&#xff0c;在使用中&#xff0c…...

BigemapPro蒙版使用技巧:精准导出地图范围

在地图制图过程中&#xff0c;我们常常会遇到需要按照特定边界裁剪地图&#xff0c;或者对指定范围以外的地图进行模糊处理等情况&#xff0c;这时"添加蒙版"功能就非常实用。 BigemapPro的蒙版功能&#xff0c;可满足用户按自定义形状裁剪地图、控制区域外显示效果&…...

CesiumEarth v1.15 更新

更新&#xff1a;​ CesiumEarth 更新至1.15.0版本&#xff0c;包含浏览器在线版、Desktop Windows版本、Desktop 安卓版本 界面优化&#xff1a;​ 项目列表已适配手机屏幕 功能​ 扩展模块更新 1、在底部工具栏区域&#xff0c;所有已生效&#xff08;已勾选&#xff0…...

SOC-ESP32S3部分:2-2-VSCode进行编译烧录

飞书文档https://x509p6c8to.feishu.cn/wiki/CTzVw8p4LiaetykurbTciA42nBf?fromScenespaceOverview 无论是使用Window搭建IDF开发环境&#xff0c;还是使用Linux Ubuntu搭建IDF开发环境&#xff0c;我们都建议使用VSCode进行代码编写和编译&#xff0c;VSCode界面友好&#x…...

机器学习 day05

文章目录 前言一、模型选择与调优1.交叉验证2.超参数搜索 前言 通过今天的学习&#xff0c;我掌握了机器学习中模型的选择与调优&#xff0c;包括交叉验证&#xff0c;超参数搜索的概念与基本用法。 一、模型选择与调优 模型的选择与调优有许多方法&#xff0c;这里主要介绍较…...

关于element-ui的table type=“expand“ 嵌套表格展开异常问题解决方案

也许是很久没用这个库了 今天找这个问题还花了一会儿时间 也是蛮简单的一个问题 排查过程就不说了 直接说结果吧 记录一下 发现问题 展开第一列的时候表格没问题 收起的时候 莫名其妙多了一个展开的按钮 代码咋一看没什么问题 百思不解不得其解 甚至怀疑row-key的问题 检查了数…...

Pichome 开源网盘程序index.php 文件读取漏洞(CVE-2025-1743)

免责声明 本文档所述漏洞详情及复现方法仅限用于合法授权的安全研究和学术教育用途。任何个人或组织不得利用本文内容从事未经许可的渗透测试、网络攻击或其他违法行为。使用者应确保其行为符合相关法律法规,并取得目标系统的明确授权。 对于因不当使用本文信息而造成的任何直…...

[SpringBoot]Spring MVC(6.0)----图书管理系统(初)

图书管理系统 需求: 1. 登录: 用户输入账号,密码完成登录功能. 2. 列表展示: 展示图书. 准备工作 将前端代码复制到 static 目录下. 约定前后端交互接口 两个功能: 用户登录 和 图书列表展示. 需求分析: 1. 用户登录 url : /user/login param : userName 和 password return …...

C语言:基础篇之常见概念

文章目录 1.C语言是什么&#xff1f;2.C语言的历史和辉煌3.编译器的选择VS20223.1 编译和链接3.2 编译器的对比3.3 VS2022 的优缺点 4.VS项目和源文件、头文件介绍5.第一个C语言程序6.main函数7.printf和库函数8.关键字介绍9.字符和ASCII编码10.字符串和\011.转义字符12.语句和…...

Ansible模块——管理100台Linux的最佳实践

使用 Ansible 管理 100 台 Linux 服务器时&#xff0c;推荐遵循以下 最佳实践&#xff0c;以提升可维护性、可扩展性和安全性。以下内容结合实战经验进行总结&#xff0c;适用于中大型环境&#xff08;如 100 台服务器&#xff09;&#xff1a; 一、基础架构设计 1. 分组与分层…...

算法与数据结构:质数、互质判定和裴蜀定理

文章目录 质数质数判定质数筛选质因数分解互质判定裴蜀定理 质数 首先回顾「质数」的定义&#xff1a;若一个正整数无法被除了 1 ​和它自身之外的任何自然数整除&#xff0c;则称该数为质数&#xff08;或素数&#xff09;&#xff0c;否则称该正整数为合数。 根据上述定义&…...

基于C#的Modbus通信协议全面解析与实现指南

目录 1. Modbus协议概述 1.1 Modbus网络结构 1.2 Modbus功能码 2. Modbus RTU模式实现 2.1 RTU模式特点 2.2 CRC-16校验算法 2.3 使用NModbus4库实现RTU通信 3. Modbus TCP/IP模式实现 3.1 TCP模式特点 3.2 MBAP报文头结构 3.3 使用NModbus实现TCP通信 3.4 原生TCP套…...

IVX:重构 AI 原生开发范式,让模型调用成为指尖艺术​

一、AI 原生开发的技术跃迁&#xff1a;从黑箱集成到白盒重构 在传统 AI 开发范式中&#xff0c;将 GPT-4o、Mediapipe 等模型集成到业务系统往往需要经历 "模型训练 - API 对接 - 前端适配" 的复杂流程。开发团队需同时掌握机器学习框架&#xff08;如 TensorFlow&…...

源码分析之Leaflet中TileLayer

概述 TileLayer 是 Layer 的子类&#xff0c;继承自GridLayer基类&#xff0c;用于加载和显示瓦片地图。它提供了加载和显示瓦片地图的功能&#xff0c;支持自定义瓦片的 URL 格式和参数。 源码分析 源码实现 TileLayer的源码实现如下&#xff1a; export var TileLayer …...

Java虚拟机 - 程序计数器和虚拟机栈

运行时数据结构 Java运行时数据区程序计数器为什么需要程序计数器执行流程虚拟机栈虚拟机栈作用虚拟机栈核心结构运行机制 Java运行时数据区 首先介绍Java运行时数据之前&#xff0c;我们要了解&#xff0c;对于计算机来说&#xff0c;内存是非常重要的资源&#xff0c;因为内…...

大语言模型 15 - Manus 超强智能体 开源版本 OpenManus 案例与原理深入解析

写在前面 Manus 是由中国初创公司 Monica.im 于 2025 年 3 月推出的全球首款通用型 AI 智能体&#xff08;AI Agent&#xff09;&#xff0c;旨在实现“知行合一”&#xff0c;即不仅具备强大的语言理解和推理能力&#xff0c;还能自主执行复杂任务&#xff0c;直接交付完整成…...

开源CMS系统中哪些常见的安全漏洞最需要注意?

在当今数字化时代&#xff0c;开源内容管理系统&#xff08;CMS&#xff09;因其灵活性和低成本广受欢迎。然而&#xff0c;开源CMS的安全漏洞也频频成为黑客攻击的突破口。本文将带大家全面了解下开源CMS中需要警惕的安全漏洞以及防护建议&#xff0c;以帮助开发者和管理员更好…...

文件包含靶场实现

文件包含漏洞&#xff08;File Inclusion Vulnerability&#xff09;是 Web 安全中常见的高危漏洞&#xff0c;主要分为 本地文件包含&#xff08;LFI&#xff09; 和 远程文件包含&#xff08;RFI&#xff09; 1、典型利用方式 利用方式示例 Payload说明路径遍历?page../../…...

在 JavaScript 中正确使用 Elasticsearch,第二部分

作者&#xff1a;来自 Elastic Jeffrey Rengifo 回顾生产环境中的最佳实践&#xff0c;并讲解如何在无服务器环境中运行 Elasticsearch Node.js 客户端。 想获得 Elastic 认证&#xff1f;查看下一期 Elasticsearch Engineer 培训的时间&#xff01; Elasticsearch 拥有大量新…...

DataLight(V1.7.12)版本更新发布

DataLight&#xff08;V1.7.12&#xff09;版本更新发布 亲爱的 DataLight 用户们&#xff0c; DataLight 发布 V1.7.12 版本&#xff0c;此版本带来了新服务 DINKY 的支持&#xff0c;以及多项问题修复&#xff0c;进一步提升了平台的易用性和稳定性。 一. 更新日志 在此次…...

LeetCode-前缀和-和为K的子数组

LeetCode-前缀和-和为K的子数组 ✏️ 关于专栏&#xff1a;专栏用于记录 prepare for the coding test。 文章目录 LeetCode-前缀和-和为K的子数组&#x1f4dd; 和为K的子数组&#x1f3af;题目描述&#x1f50d; 输入输出示例&#x1f9e9;题目提示&#x1f9ea;前缀和❓什么…...

MySQL基础关键_014_MySQL 练习题

目 录 一、有以下表&#xff0c;请用一条 SQL 语句查询出每门课程都大于 80 分的学生 二、综合题1&#xff08;数据自行模拟&#xff09; 1.查询身份证号为“440401430103082”的申请日期 2.查询同一个身份证号有两条及以上记录的身份证号码及记录个数 3.将身份证号码为“4…...

femap许可与云计算集成

随着云计算技术的迅猛发展&#xff0c;越来越多的企业开始将关键应用和服务迁移到云端&#xff0c;以享受其带来的弹性扩展、高效管理和成本优化等优势。Femap作为一款强大的电磁仿真工具&#xff0c;通过与云计算的集成&#xff0c;将为企业带来前所未有的许可管理和仿真分析体…...

uni-app项目从0-1基础架构搭建全流程

前情 最近新接了一个全新项目&#xff0c;我负责从0开始搭建小程序&#xff0c;我选用的技术栈是uni-app技术栈&#xff0c;UI库选择的是uview-plus&#xff0c;CSS引入现在流行的tainlwindcss&#xff0c;实现CSS原子化书写&#xff0c;实现小程序分包&#xff0c;分包中实现…...

轻量级高性能推理引擎MNN 学习笔记 04.线性回归

1. 线性回归 MNN 官方给的iOS Demo中&#xff0c;输入是图片&#xff0c;输出是分类结果&#xff0c;相对来讲&#xff0c;略微有些复杂&#xff0c;我们现在用一个最简单的线性回归模型&#xff0c;来说明MNN的用法。 该线性回归是yaxb &#xff08;其中a2,b0.01&#xff09…...

使用 React PDF 构建 React.js PDF 查看器的指南

在本文中&#xff0c;我们将重点介绍在React.js中制作 PDF 查看器的最受欢迎的开源库。具体来说&#xff0c;我们将利用著名的开源库react-pdf的功能&#xff0c;指导您完成创建 React.js PDF 查看器的过程。 通过本教程&#xff0c;您将在第一部分学习如何使用 React-PDF 在 …...

动力电池点焊机厂家:驱动新能源制造的精密力量|比斯特自动化

在新能源汽车、储能系统等产业蓬勃发展的背景下&#xff0c;动力电池点焊机作为电池模组生产的核心设备&#xff0c;正经历着技术迭代与市场需求的双重升级。这类厂家通过持续研发与创新&#xff0c;不仅满足了电池制造企业对焊接精度、效率与稳定性的严苛要求&#xff0c;更推…...

React的合成事件(SyntheticEventt)

文章目录 前言 前言 React的合成事件&#xff08;SyntheticEvent&#xff09;是React为了统一不同浏览器的事件处理行为而封装的一套跨浏览器事件系统。它与原生事件的主要区别如下&#xff1a; 1. 事件绑定方式 • 合成事件&#xff1a;使用驼峰命名法绑定事件&#xff08;如…...

知识中台Top5:Baklib上榜推荐

Baklib知识中台优势 在数字化转型浪潮中&#xff0c;Baklib凭借其知识中台的核心设计理念&#xff0c;构建了企业级知识管理的差异化竞争力。区别于传统文档管理系统&#xff0c;该平台通过四库体系&#xff08;知识资源库、场景规则库、服务模型库、应用组件库&#xff09;实…...

在Windows系统中使用C++与Orthanc交互:基于DICOMweb的医学影像应用开发

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…...

视频太大?用魔影工厂压缩并转MP4,画质不打折!

在日常生活中&#xff0c;我们常常需要将视频文件转换成不同的格式以适应各种设备或平台的播放需求。魔影工厂作为一款功能强大且操作简单的视频转换工具&#xff0c;深受用户喜爱。本文中简鹿办公将手把手教你如何使用魔影工厂将视频转换为MP4格式&#xff0c;并进行个性化设置…...

Wan2.1 通过首尾帧生成视频

Wan2.1 通过首尾帧生成视频 flyfish 使用 Wan2.1-FLF2V-14B-720P 模型&#xff0c;通过输入两张图像&#xff08;起始帧和结束帧&#xff09;&#xff0c;生成一段连贯的视频。 First Last Frame-to-Video 即 “首末帧到视频” 技术 import numpy as np import torch import…...

宝塔+fastadmin:给项目添加定时任务

一、定时任务脚本编写 1. 使用 shebang 声明执行器 #!/usr/bin/env php 这是 Unix/Linux 系统中脚本文件的标准开头。表示这个脚本使用系统环境变量中的 php 来执行。2. 定义 ThinkPHP 入口路径并加载框架 define(APP_PATH, __DIR__ . /../../application/); require __DIR__…...

[自动化集成] 使用明道云上传附件并在Python后端处理Excel的完整流程

在企业日常自动化场景中,使用低代码平台如明道云搭建前端界面,结合自定义Python后端服务,实现灵活数据处理是一种高效的组合方式。本文将分享一个典型的集成用例:用户通过明道云上传文本和Excel附件,Python后端接收并解析这些信息,最终实现完整的数据处理闭环。 项目背景…...

前端项目采用响式布局

要让整个前端项目采用响应式布局&#xff0c;可以从多个方面进行优化&#xff0c;以下是一些具体的建议和实现方法&#xff1a; 1. 使用 ElementPlus 的响应式特性 ElementPlus 组件库本身提供了一些响应式的能力&#xff0c;例如 el-col 组件可以用于创建响应式的网格布局。…...

【Unity】DOTween的常用函数解释

DOTween插件常用函数解释 1.DOTween.To&#xff08;通用变化动画&#xff09; 解释&#xff1a;将某一个值在一定的时间内变化到另一个值&#xff08;通用的函数&#xff09;&#xff0c;可用于大部分的动画变化 使用示例&#xff1a; using UnityEngine; using DG.Tweenin…...

飞桨paddle import fluid报错【已解决】

跟着飞桨的安装指南安装了paddle之后 pip install paddlepaddle有一个验证&#xff1a; import paddle.fluid as fluid fluid.install check.run check()报错情况如下&#xff0c;但是我在pip list中&#xff0c;确实看到了paddle安装上了 我import paddle别的包&#xff0c…...

ELK简介和docker版安装

使用场景 主要还是给开发人员“打捞日志”用的。 ELK 是由三个开源工具组成的套件&#xff08;Elasticsearch、Logstash 和 Kibana&#xff09;&#xff0c;主要用于日志的收集、分析和可视化。以下是 ELK 常见的使用场景&#xff1a; 日志集中化管理 收集来自多个服务器或服…...

DockerHub被封禁,怎么将镜像传到国内?一种简单合规的镜像同步到国内方案[最佳实践]

Docker将容器化技术普及&#xff0c;推动云计算向云原生的演进。Docker的核心创新技术之一是容器镜像&#xff0c;它是一种文件的打包方式&#xff0c;将应用程序运行的操作系统、库、运行环境等依赖全部打包一起。在其他任意环境&#xff0c;只要可以运行docker服务&#xff0…...

飞桨paddle ‘ParallelEnv‘ object has no attribute ‘_device_id‘【已解决】

书借上回&#xff0c;自从我反复重装paddle之后&#xff0c;我发现了&#xff0c;只要pip list中有库&#xff0c;但是代码报错&#xff0c;那就是飞桨没把代码更新完全&#xff0c;只能自己去改源代码 我又遇到报错了&#xff1a; 根据报错信息&#xff0c;找到ParallelEnv报…...

网络安全面试题(一)

文章目录 一、基础概念与模型‌1. 什么是通信协议&#xff1f;列举三种常见的网络通信模型&#xff1f;2. 解释OSI七层模型及各层功能3. TCP/IP四层模型与OSI模型的对应关系是什么&#xff1f;4. 五层协议体系结构与TCP/IP模型的区别?5. 什么是面向连接与非面向连接的服务&…...

【Leetcode 每日一题】3355. 零数组变换 I

问题背景 给定一个长度为 n n n 的整数数组 n u m s nums nums 和一个二维数组 q u e r i e s queries queries&#xff0c;其中 q u e r i e s [ i ] [ l i , r i ] queries[i] [l_i, r_i] queries[i][li​,ri​]。 对于每个查询 q u e r i e s [ i ] queries[i] quer…...

RK3588 ArmNN CPU/GPU ResNet50 FP32/FP16/INT8 推理测试

RK3588 ArmNN CPU/GPU ResNet50 FP32/FP16/INT8 推理测试 **背景与目标** 一.性能数据【INT8模型在CPU上推理的结果已经不对,暂未分析原因】二.操作步骤2.1 在x86-Linux上生成onnx模型,以及tflite量化模型(避免在RK3588上安装过多依赖)2.1.1 创建容器2.1.2 安装依赖2.1.3 下载推…...

力扣第5题:最长回文子串(动态规划)

小学生一枚&#xff0c;自学信奥中&#xff0c;没参加培训机构&#xff0c;所以命名不规范、代码不优美是在所难免的&#xff0c;欢迎指正。 标签&#xff1a; 字符串、动态规划、中心扩散法 语言&#xff1a; C 题目&#xff1a; 给你一个字符串s&#xff0c;找到s中最长的…...

HCIP实验五

一、实验拓扑图&#xff1a; 二、实验需求分析&#xff1a; 1. PreVal策略&#xff1a;要求确保R4通过R2到达192.168.10.0/24 &#xff0c;需在R4上针对去往该网段路由配置PreVal策略&#xff0c;为经R2的路径赋予更高优先值&#xff0c;影响本地路由表选路。 2. AS Path策略…...

python Numpy-数组

目录 Numpy&#xff1a; 一、Ndarray 1 定义 2 数组的属性方法 2.1 数组的维度&#xff1a;np.ndarray.shape 2.2 元素的类型&#xff1a;np.ndarray.dtype 2.3 数组元素的个数&#xff1a;np.ndarray.size 2.4 转置 3 ndarray 所存储元素的数据类型 4 数组创建 4.1 a…...

数据库分库分表从理论到实战

1.分库分表基础理论 1.1 分库分表基本概念 定义&#xff1a;分库分表是一种将单一数据库中的数据分散存储到多个数据库或表中的技术方案&#xff0c;其核心思想是通过"分而治之"的方式解决数据库性能瓶颈问题。分库&#xff1a;将表按业务或数据量拆分到不同数据库中…...

Java异常处理与File类终极指南

Java异常处理与File类终极指南 目录 异常体系全维度拆解异常处理十五种高阶模式自定义异常企业级实践File类深度探索与NIO进化论分布式系统异常处理架构性能调优与安全防护全网最全异常代码库一、异常体系全维度拆解 1.1 Java异常DNA解析 // 异常类的核心继承关系 public cla…...

pmap中的mode列,脏页,写时复制

写时复制&#xff08;Copy-on-Write&#xff0c;简称 COW&#xff09; 是一种计算机编程中的优化技术&#xff0c;主要用于内存或存储资源的管理。其核心思想是&#xff1a;只有在真正需要修改数据时&#xff0c;才会执行实际的复制操作&#xff0c;从而避免不必要的资源开销。…...