MySQL-基于Xenon实现MySQL高可用集群
一、什么是Xenon?
Xenon [ˈziːnɒn] (https://github.com/radondb/xenon) 是一款由 RadonDB 开发团队研发并开源的新一代 MySQL 集群高可用工具。基于 Raft 协议进行无中心化选主,实现主从秒级切换;基于 Semi-Sync 机制,保障数据不丢失,实现数据强一致性。并结合 MySQL(5.7 及以上版本)并行复制特性,实现 Binlog 并行回放,大大降低从库延迟
官方网址: https://github.com/radondb/xenon
二、Xenon架构

二、Xenon架构

xenon 架构介绍 ,每个MySQL 节点安装了一个agent ,agent的作用:ping 一下本来MySQL是否存活,然后把本地的gtid 获取出来,写入到local index ,看各节点的local index的gtid 谁大,谁大谁做作为主库。
每个agent 都有一个心跳信息,主库的Leader 和 从库的Follower 的心跳时间是可以配置的,超过了多长时间,就认为主库不存活,然后从节点选举主库。
xenon 为什么要用三节点:其实用了增强半同步架构,最少有一个从节点,给主库ACK响应。两个从节点,就是为了防止,一个从节点挂了,主库不对外工作了。
三、Xenon 工作原理
结合架构图,可看出 Xenon 就是基于 Raft + Semi-Sync + GTID 实现的高可用,保证大多数节点接收到数据。
而 Raft 基于心跳管理,如果从节点超时收不到主的心跳,会尝试发起选举,若得到超过半数(非 IDLE 节点)的选票,则会当选为主节点。
下面以三节点(一主两从)Xenon 集群来简单说明工作原理。
{Leader, [GTID:{1,2,3,4,5}]
{Follower1, [GTID:{1,2,3,4,5}]
{Follower2, [GTID:{1,2,3}]
- 当 Leader 不可用时,Follower1 和 Follower2 立即参与竞选成为主节点。
- Xenon 校验 GTID 值较高的 Follower 成为新主节点,示例中 GTID 值较高的是 Follower1。
-
当 GTID 值最高的 Follower 被选举成为新主时,将结束竞选。示例中 Follower1 成为新主节点后,将会拒绝 Follower2 的选举。自动完成主从切换
四、Xenon+MySQL高可用本地测试
3.2 安装xtrabackup(三台机器)


1、架构环境:
IP | HostName | MySQL | xtrabackup | user | 备注 |
192.168.221.140 | db140 | mysql8.0.24 | mysql | 主库 | |
192.168.221.141 | db141 | mysql8.0.24 | mysql | 备库 | |
192.168.221.142 | db142 | mysql8.0.24 | mysql | 备库 |
VIP:192.168.221.100
2、系统配置
1)、修改三台主机的mysql账号,指定shell为/bin/bash,并修改密码
[root@db140 ~]# useradd mysql #添加用户
[root@db140 ~]# chsh mysql
Changing shell for mysql.
New shell [/bin/bash]: /bin/bash
chsh: Shell not changed.
[root@db140 ~]# passwd mysql #修改密码
2)配置hosts解析(三台)
[root@db140 ~]# vim /etc/hosts
192.168.221.140 db140
192.168.221.141 db141
192.168.221.142 db142
3)配置ssh互信(三台)
[root@db140 ~]# su - mysql
上一次登录:二 7月 20 03:31:20 EDT 2021pts/0 上
[mysql@db140 ~]$ ssh-keygen
[mysql@db140 ~]$ cd .ssh
[mysql@db140 .ssh]$ ll
total 8
-rw-------. 1 mysql mysql 1679 Jul 20 03:37 id_rsa
-rw-r--r--. 1 mysql mysql 393 Jul 20 03:37 id_rsa.pub
[mysql@db140 ~]$ ssh-copy-id mysql@192.168.221.141
[mysql@db140 ~]$ ssh-copy-id mysql@192.168.221.142
注意:141和142两台主机一样操作
2、mysql实例安装(省略)
3、xenon配置准备
3.1、准备golang环境(三台机器)
#下载
[root@db140 ~]$ wget https://dl.google.com/go/go1.14.4.linux-amd64.tar.gz
# 解压
[root@db140 ~]$ tar -zxf go1.14.4.linux-amd64.tar.gz
# 配置环境变量
[root@db140 ~]$ vim .bash_profile
export GOPATH=/root/go
PATH=$PATH:$HOME/.local/bin:$HOME/bin:$GOPATH/bin
export PATH
[root@db140 ~]$ source .bash_profile
# 查看版本
[root@db140 ~]$ go version
go version go1.9.4 linux/amd64
或者直接使用yum install -y go 安装
3.2 安装xtrabackup(三台机器)
[mysql@db140 ~]$ tar -xf percona-xtrabackup-8.0.25-17-Linux-x86_64.glibc2.12.tar.gz
[mysql@db140 ~]$ mv percona-xtrabackup-8.0.25-17-Linux-x86_64.glibc2.12/ percona-xtrabackup-8.0.25/
[mysql@db140 ~]$ vim ~/.bash_profile
export XtrabackupPath=/home/mysql/percona-xtrabackup-8.0.25
PATH=$PATH:$HOME/.local/bin:$HOME/bin:$XtrabackupPath/bin
3.3、构建mysql主从复制关系(GTID、半同步模式)
140/141/142操作:
mysql> create user rep@'%' identified with mysql_native_password by 'rep';
Query OK, 0 rows affected (0.00 sec)
mysql> grant replication slave on *.* to rep@'%';
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
mysql> set global rpl_semi_sync_master_enabled=1;
mysql> set global rpl_semi_sync_master_timeout=2147483648;
mysql> set global rpl_semi_sync_slave_enabled=1;
在141/142上操作:
mysql> change master to master_host='192.168.221.140',master_user='rep',master_password='rep',master_port=3307,master_auto_position=1;
mysql> start slave;
mysql> show slave status\G;
3.4、安装xenon(所有的节点)
# 安装git
[root@db140 ~]# yum -y install git
[root@db140 ~]# mkdir /mygit
[root@db140 ~]# cd /mygit
# 编译xenon
[root@db140 mygit]# git clone https://github.com/radondb/xenon
[root@db141 mygit]# ll xenon/
总用量 44
drwxr-xr-x. 2 root root 66 7月 20 08:56 conf
drwxr-xr-x. 4 root root 207 7月 20 08:56 docs
-rw-r--r--. 1 root root 35147 7月 20 08:56 LICENSE
-rw-r--r--. 1 root root 1371 7月 20 08:56 makefile
-rw-r--r--. 1 root root 2008 7月 20 08:56 README.md
drwxr-xr-x. 13 root root 150 7月 20 08:56 src
[root@db140 mygit]# cd /mygit/xenon/
[root@db140 xenon]# make
[root@db140 xenon]# mkdir -p /data/xenon
[root@db140 xenon]# cp -r /mygit/xenon/bin /data/xenon/
[root@db140 xenon]# cp -r /mygit/xenon/conf/xenon-simple.conf.json /data/xenon/xenon.json
[root@db140 xenon]# echo "/etc/xenon/xenon.json" > /data/xenon/bin/config.path
[root@db140 xenon]#
[root@db140 xenon]# mkdir /etc/xenon
[root@db140 xenon]# mv /data/xenon/xenon.json /etc/xenon/
[root@db140 xenon]# chown -R mysql:mysql /data/xenon/
[root@db140 xenon]# chown -R mysql:mysql /etc/xenon/
3.5、配置xenon(三台主机),以140主机为例,其他主机,只需要改为本机ip即可:
[root@db140 ~]# cat /etc/xenon/xenon.json
{
"server":
{
"endpoint":"192.168.221.140:8801"
},
"raft":
{
"meta-datadir":"raft.meta",
"heartbeat-timeout":1000,
"election-timeout":3000,
"leader-start-command":"sudo /sbin/ip a a 192.168.221.100/16 dev ens33 && arping-c3 -A 192.168.221.100 -1 ens33",
"leader-stop-command":"sudo /sbin/ip a d 192.168.221.100/16 dev ens33"
},
"mysql":
{
"admin":"root",
"passwd":"root",
"host":"127.0.0.1",
"port":3307,
"basedir":"/home/mysql/mysql8024",
"defaults-file":"/home/mysql/data3307/my3307.cnf",
"ping-timeout":1000,
"master-sysvars":"tokudb_fsync_log_period=default;sync_binlog=default;innodb_flush_log_at_trx_commit=default",
"slave-sysvars": "tokudb_fsync_log_period=1000;sync_binlog=1000;innodb_flush_log_at_trx_commit=2"
},
"replication":
{
"user":"rep",
"passwd":"rep"
},
"backup":
{
"ssh-host":"192.168.221.140",
"ssh-user":"mysql",
"ssh-passwd":"123456@hj",
"ssh-port":22,
"backupdir":"/home/mysql/data3307/data",
"xtrabackup-bindir":"/home/mysql/percona-xtrabackup-8.0.25",
"backup-iops-limits":100000,
"backup-use-memory": "2GB",
"backup-parallel": 2
},
"rpc":
{
"request-timeout":500
},
"log":
{
"level":"INFO"
}
}
其他节点的配置文件的修改
把 /etc/xenon/xenon.json 拷贝到 另外两个节点(141,142)
"endpoint":"192.168.221.141:8801" #需要把 endpoint 换成各节点相应ip
"ssh-host":"192.168.221.141", #需要把backup 下的 换成各节点相应ip
# 如果是mysql-141
"endpoint":"192.168.221.141:8801"
"ssh-host":"192.168.221.141",
# 如果是mysql-142
"endpoint":"192.168.221.142:8801"
"ssh-host":"192.168.221.142",
# 这个是 vip 生成的脚本
sudo /sbin/ip a a 10.0.0.100/16 dev ens33 && arping-c3 -A 10.0.0.100 -1 ens33
# 这个是删除 vip 的脚本
sudo /sbin/ip a d 10.0.0.100/16 dev ens33
3.6、开启xenon并配置集群
1)启动xenon,用mysql用户启动(三台主机均操作)
[root@db140 ~]# su - mysql
上一次登录:二 7月 20 09:23:01 EDT 2021pts/2 上
[mysql@db140 ~]$ cd /data/xenon/bin/
[mysql@db140 bin]$ ll
total 21076
-rw-r--r--. 1 mysql mysql 22 Jul 20 08:51 config.path
-rwxr-xr-x. 1 mysql mysql 11192283 Jul 20 08:50 xenon
-rwxr-xr-x. 1 mysql mysql 10382288 Jul 20 08:50 xenoncli
[mysql@db140 bin]$ nohup /data/xenon/bin/xenon -c /etc/xenon/xenon.json > /data/xenon/xenon.log 2>&1 &
# 141/142也操作
2)添加xenon节点(所有节点都要添加节点成员140/141/142)
[mysql@db140 bin]$ ./xenoncli cluster add 192.168.221.140:8801,192.168.221.141:8801,192.168.221.142:8801
2021/07/20 09:37:42.060543 cluster.go:82: [WARNING] cluster.prepare.to.add.nodes[192.168.221.140:8801,192.168.221.141:8801,192.168.221.142:8801].to.leader[]
2021/07/20 09:37:42.060811 cluster.go:87: [WARNING] cluster.canot.found.leader.forward.to[192.168.221.140:8801]
2021/07/20 09:37:42.073479 cluster.go:91: [WARNING] cluster.add.nodes.to.leader[].done
# 141/142同样的操作
3)查看vip信息
# 查看vip在哪台主机上
[mysql@db140 bin]$ ip ad show| grep 192.168.221.100
inet 192.168.221.100/16 scope global ens33
# 测试141/142能否连接192.168.221.100
[mysql@db141 bin]$ ~/mysql8024/bin/mysql -uroot -proot -h192.168.221.100 -P3307
mysql> system hostname -I #查看当前ssh系统信息的ip
192.168.221.135 192.168.221.141
mysql> select @@hostname; #查看mysql连接的主机名
+------------+
| @@hostname |
+------------+
| db140 |
+------------+
1 row in set (0.00 sec)
# 通过VIP写入
mysql> use hj;
Database changed
mysql> create table t(id int primary key);
mysql> insert into t (id) values(1);
mysql> insert into t (id) values(2);
# 成功写入数据,通过vip连接没有问题
4)查看xenon集群状态信息:
[mysql@db140 bin]$ ./xenoncli cluster status
+----------------------+-------------------------------+---------+---------+--------------------------+---------------------+----------------+----------------------+
| ID | Raft | Mysqld | Monitor | Backup | Mysql | IO/SQL_RUNNING | MyLeader |
+----------------------+-------------------------------+---------+---------+--------------------------+---------------------+----------------+----------------------+
| 192.168.221.140:8801 | [ViewID:3 EpochID:0]@LEADER | RUNNING | ON | state:[NONE] | [ALIVE] [READWRITE] | [true/true] | 192.168.221.140:8801 |
| | | | | LastError: | | | |
+----------------------+-------------------------------+---------+---------+--------------------------+---------------------+----------------+----------------------+
| 192.168.221.141:8801 | [ViewID:3 EpochID:0]@FOLLOWER | RUNNING | ON | state:[NONE] | [ALIVE] [READONLY] | [true/true] | 192.168.221.140:8801 |
| | | | | LastError: | | | |
+----------------------+-------------------------------+---------+---------+--------------------------+---------------------+----------------+----------------------+
| 192.168.221.142:8801 | [ViewID:3 EpochID:0]@FOLLOWER | RUNNING | ON | state:[NONE] | [ALIVE] [READONLY] | [true/true] | 192.168.221.140:8801 |
| | | | | LastError: | | | |
+----------------------+-------------------------------+---------+---------+--------------------------+---------------------+----------------+----------------------+
(3 rows)
注意:LEADER 是主库
FOLLOWER 是从库
4、检验xenon环境
4.1 检测VIP切换
1)查看VIP信息
[mysql@db140 bin]$ ip ad show| grep 192.168.221.100
inet 192.168.221.100/16 scope global ens33
# 得知VIP信息,在192.168.221.140主机上
2)进行模拟故障,关闭140主机的mysql服务,观察VIP是否切换
注意:当只有140主机宕机或者该主机的xenon服务挂了或者mysql服务损坏(表空间损坏/datadir被删除),才能导致xenon无法把mysql服务拉起来
# 直接把mysql服务主机关机

[mysql@db141 bin]$ ip ad show| grep 192.168.221.100
inet 192.168.221.100/16 scope global ens33
# 得知vip切换到了141主机上,并141成为了leader,即主库
[mysql@db141 ~]$ ~/mysql8024/bin/mysql -uroot -proot -h192.168.221.100 -P3307
mysql> insert into hj.t (id) values(3);
# 插入数据成功
3)宕机主机如何加入集群中??
# 将宕机主机上的xenon服务启动
[mysql@db140 bin]$ nohup /data/xenon/bin/xenon -c /etc/xenon/xenon.json > /data/xenon/xenon.log 2>&1 &
[1] 124818
[mysql@db140 bin]$ ps -ef | grep mysql
mysql 124818 1580 0 22:43 pts/0 00:00:00 /data/xenon/bin/xenon -c /etc/xenon/xenon.json
mysql 124827 1 0 22:43 pts/0 00:00:00 /bin/sh /home/mysql/mysql8024/bin/mysqld_safe --defaults-file=/home/mysql/data3307/my3307.cnf
mysql 125942 124827 20 22:43 pts/0 00:00:01 /home/mysql/mysql8024/bin/mysqld --defaults-file=/home/mysql/data3307/my3307.cnf --basedir=/home/mysql/mysql8024 --datadir=/home/mysql/data3307/data --plugin-dir=/home/mysql/mysql8024/lib/plugin --log-error=/home/mysql/data3307/logs/mysql_error.log --open-files-limit=655350 --pid-file=/home/mysql/data3307/logs/mysql.pid --socket=/home/mysql/data3307/my3307.sock --port=3307
mysql 126386 1580 0 22:43 pts/0 00:00:00 ps -ef
mysql 126387 1580 0 22:43 pts/0 00:00:00 grep --color=auto mysql
注意:此时xenon服务已经把mysql服务已经拉起来了
[mysql@db141 bin]$ ./xenoncli cluster status

4)查看数据是否自动拉齐??
[mysql@db140 bin]$ ~/mysql8024/bin/mysql -uroot -proot -h192.168.221.140 -P3307
mysql> select * from hj.t;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
+----+
3 rows in set (0.00 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.221.141
Master_User: rep
Master_Port: 3307
Connect_Retry: 60
Master_Log_File: mysql_bin.000005
Read_Master_Log_Pos: 1044
Relay_Log_File: relay_bin.000002
Relay_Log_Pos: 686
Relay_Master_Log_File: mysql_bin.000005
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
# 查看141主机的主从复制关系
[mysql@db141 ~]$ mysql8024/bin/mysql -uroot -proot -S data3307/my3307.sock
mysql> show slave status\G;
Empty set, 1 warning (0.00 sec)
# 查看142主机的主从复制关系
[mysql@db142 ~]$ mysql8024/bin/mysql -uroot -proot -S data3307/my3307.sock
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.221.141
Master_User: rep
Master_Port: 3307
Connect_Retry: 60
Master_Log_File: mysql_bin.000005
Read_Master_Log_Pos: 1044
Relay_Log_File: relay_bin.000002
Relay_Log_Pos: 686
Relay_Master_Log_File: mysql_bin.000005
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
总结: 当xenon无法拉齐原来的leader时,则会发生选举,并会更改相应的主从关系
4.2、数据库重建(暂时未测试)
分类:
mysql
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)