项目说明
-
该项目共分为2个子项目,由MYSQL集群高可用和数据监控平台两部分组成
-
MYSQL集群高可用
业务需求
- 某企业由于业务增加,超出了单库性能阈值,则需要构建高可用的数据库服务器集群,且在业务增长初期,读写业务各半,需选择Active-Active Cluster集群架构,为了保证活性,使用恰当的技术实现high availability,要求架构图如下:

编辑
为了实现自动化运维,预使用开源监控实时报警软件实现服务器的检测、大屏展示,要求使用独立主机安装软件检测数据库集群的性能,以仪表盘形式展示
-
具体要求
-
网络配置:确保集群中的MySQL服务器之间的网络连接稳定可靠,避免网络延迟或丢包对集群性能造成影响。
-
同步参数配置:对于需要数据同步的集群方案(如主从复制和组复制),需要合理配置同步参数,确保数据的实时性和一致性。
-
备份和恢复策略:制定完善的备份和恢复策略,定期备份集群数据,并测试恢复流程的可行性,以确保在发生故障时能够快速恢复数据和服务。
-
监控和告警:使用监控工具对集群进行实时监控,并设置合理的告警阈值。当集群出现异常情况时,能够及时发现并处理。
-
项目设计思路
-
MYSQL集群高可用使用双主双活+keepalived实现
-
MYSQL数据监控平台使用mysqld_exporter+prometheus+Grafana三件套实现
-
集群及监控平台搭建完毕后可以实现企业内部的mysql数据库双主机在线增加高可用性,通过keepalived的故障检测和VIP漂移能力使得发生故障后使用者无感知,增加系统的容错能力,通过监控平台实现mysql数据库监控可视化
项目组织方式及时间
-
时间:建议1.5天至2天内完成所有的项目搭建、压力测试、问题总结
-
方式:通过VmWare17虚拟机实现平台搭建
-
人数:1人
项目特点
-
综合项目从主从复制原理、数据同步方式、主从架构模式、主从架构/双主架构、高可用、数据可视化一步步从零搭建出一个完善的数据库集群/监控平台
-
综合项目完成后可以实现对MYSQL数据库高级运维知识的巩固,通过参与实际项目增加工作实战经验,提升技术能力、故障判断检测维护能力、充实简历项目经历
-
通过prometheus数据库监控三件套的项目搭建,可以掌握数据监控的知识应用能力,通过监控大屏数据的展示使得数据可视化得以实现,使得运维更自动化、直观化
-
该项目进一步巩固和掌握云原生高级数据库部分的知识以及数据监控可视化的知识点
项目背景知识

编辑
集群机构模式-
一主一从/多从架构

编辑
- 一主一从或一主多从,这是传统的主从复制模型,也就是多个主从节点组成的集群中,只有一个主节点,剩余的所有节点都为其附属关系,结构如下:
双主/多主架构
-
若公司项目中读写请求的比例对半开,同时整体的并发量也不算低,至少超出了单库的承载阈值,这时就可以选用双主/多主架构,结构如下:
-

编辑
keepalived高可用方案
- Keepalived是一个轻量级别的高可用解决方案,使用VRRP(Vritrual Router Redundancy Protocol,虚拟路由冗余协议)的VIP虚拟IP的漂移功能,实现单点故障转移

编辑
可视化监控平台三件套
-
Mysqld_exporter:是一款轻量级的mysql监控工具,用来收集MysQL数据库相关指标并将其暴露给prometheus进行监控和告警
-
Prometheus:普罗米修斯,一个开源的服务监控系统,它负责采集和存储应用的监控指标数据,并以可视化的方式进行展示,以便于用户实时掌握系统的运行情况,并对异常进行检测
-
Grafana:格拉法娜,是一个跨平台的开源的度量分析和可视化工具,可以从prometheus获取数据进行可视化数据大屏展示。
-
总结:mysqld_exporter用于抓取mysql监控指标数据,prometheus接收到数据后进行整理分析,grafana从prometheus获取数据使用大屏模版进行仪表盘展示

编辑
项目环境
项目拓扑结构

编辑
软硬件环境清单
| 主机名 | IP地址 | 硬件 | 软件 |
|---|---|---|---|
| master1 | 172.25.254.128 VIP:172.25.254.200 | cpu:1颗2核 内 存:2GB HDD:20GB 网 络:NAT | VmWare17 OpenEuler22.03 SP4 MySql8.0.37 Keepalived2.2.4 |
| master2 | 127.25.254.129 VIP:172.25.254.200 | cpu:1颗2核 内 存:2GB HDD:20GB 网 络:NAT | VmWare17 OpenEuler22.03 SP4 MySql8.0.37 Keepalived2.2.4 |
| monitor | 172.25.254.130 | cpu:1颗2核 内 存:2GB HDD:20GB 网 络:NAT | VmWare17 OpenEuler22.03 SP4 Mysqld_Exporter-0.15.1 Prometheus-2.53.2 grafana-enterprise-11.1.2 |
项目任务清单
系统平台部署
-
安装VmWare17
-
虚拟出三台计算机
-
安装OpenEuler22.03 SP4 LTS 操作系统
-
系统设置:主机名、防火墙、SELinux、hosts映射、IP地址:

安装2台MySql服务器
-
使用二进制包进行安装
-
配置MySql系统服务
部署高可用MySql双主集群
-
配置账户
-
配置主主复制
-
安装keepalived并配置
安装配置监控平台
-
安装Mysqld_Exporter+Prometheus+grafana-enterprise
-
配置监控平台组件
项目实现步骤
环境配置
修改三台主机名

编辑
root@localhost \~\]# hostnamectl set-hostname master1/master2/monitor
* 关闭三台主机防火墙及SELinux
* vi /etc/selinux/config SELINUX=disabled
systemctl stop firewalld # 关闭防火墙 systemctl disable firewalld # 取消开机启动 reboot
* 三台主机下载所需软件并升级
* yum install vim make gcc tree net-tools tar -y yum update
* 三台主机重新设置登录系统密码
* passwd root
* 三台主机时间同步
* 编辑
* 编辑
给主机装mysql--master1和master2步骤一样-----可安装完master1克隆出master2
方法一二进制安装mysql
下载地址:
[https://downloads.mysql.com/archives/community/!\[img\](https://csdnimg.cn/release/blog_editor_html/release2.4.4/ckeditor/plugins/CsdnLink/icons/icon-default.png?t=P9T8)https://downloads.mysql.com/archives/community/](https://downloads.mysql.com/archives/community/ "https://downloads.mysql.com/archives/community/https://downloads.mysql.com/archives/community/")编辑
下载后解压
```
[root@master1 ~]# tar xvf mysql-8.0.37-linux-glibc2.17-x86_64.tar.xz
[root@master1 ~]# cd mysql-8.0.37-linux-glibc2.17-x86_64
[root@master1 mysql-8.0.37-linux-glibc2.28-x86_64]# ls
bin include LICENSE README support-files docs lib man share
```

##### 使用前的准备
```
[root@master1 ~]# cd ~
[root@master1 ~]# mv mysql-8.0.37-linux-glibc2.17-x86_64 /usr/local/mysql
[root@master1 /]# cd /usr/local/mysql
[root@master1 mysql]# groupadd mysql # 创建名为mysql的用户组
[root@master1 mysql]# useradd -r -g mysql -s /bin/false mysql # 创建名为 mysql的系统用户,将其添加到mysql用户组中,并设置其登录shell为/bin/false,以限制该用户的登录权限
[root@master1 mysql]# mkdir data # 创建用于存放MySQL数据文件目录
# 设置mysql目录的账户及工作组,生产环境中不要使用root
[root@master1 mysql]# chown -R mysql:mysql /usr/local/mysql
```

# 移动到默认安装目录,也可自行修改
```
[root@master1 ~]# cd ~
[root@master1 ~]# mv mysql-8.0.37-linux-glibc2.17-x86_64 /usr/local/mysql
[root@master1 /]# cd /usr/local/mysql
[root@master1 mysql]# groupadd mysql # 创建名为mysql的用户组
[root@master1 mysql]# useradd -r -g mysql -s /bin/false mysql # 创建名为 mysql的系统用户,将其添加到mysql用户组中,并设置其登录shell为/bin/false,以限制该用户的登录权限
[root@master1 mysql]# mkdir data # 创建用于存放MySQL数据文件目录
# 设置mysql目录的账户及工作组,生产环境中不要使用root
[root@master1 mysql]# chown -R mysql:mysql /usr/local/mysql
```

##### 初始化软件
```
[root@master1 mysql]# bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data # 注意:需要复制密码
[root@master1 mysql]# bin/mysqld_safe --user=mysql & # 使用后台方式以mysql用户身份启动 MySQL 服务器,mysqld_safe 是一个用于启动和监控 MySQL 服务器的脚本
# 注意:此时上述命令执行完毕处于后台运行状态,需要另行启动一个终端
[root@master1 ~]# ps -ef | grep mysql # 查看进程运行状态
[root@master1 ~]# cd /usr/local/mysql
[root@master1 ~]# bin/mysql -uroot -p # 登录,可能报错
# 报错,需要找到下面的文件进行软连接
[root@master1 ~]# ln -s /usr/lib64/libncurses.so.6.3 /usr/lib64/libncurses.so.5
[root@master1 ~]# ln -s /usr/lib64/libtinfo.so.6.3 /usr/lib64/libtinfo.so.5
```

```
[root@master1 ~]# bin/mysql -u root -p
Enter password:
mysql> alter user 'root'@'localhost' identified with mysql_native_password by '123456';
mysql> flush privileges;
mysql> use mysql;
mysql> select user, host, plugin from mysql.user;
+------------------+-----------+-----------------------+
| user | host | plugin |
+------------------+-----------+-----------------------+
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session | localhost | caching_sha2_password |
| mysql.sys | localhost | caching_sha2_password |
| root | localhost | mysql_native_password |
+------------------+-----------+-----------------------+
4 rows in set (0.00 sec)
mysql>exit
[root@master1 ~]# ps -ef | grep mysql
[root@master1 ~]# kill -9 pid号 # 在当前终端关闭运行的mysql
```

##### 设置mysql的配置文件
# 回到之前的终端,敲一个回车,显示进程以杀死
```
[root@master1 mysql]# vim /etc/my.cnf # 新建配置文件,输入以下内容:
[client]
port = 3306
socket = /tmp/mysql.sock
[mysqld]
port = 3306
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
tmpdir = /tmp
socket = /tmp/mysql.sock
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
default-storage-engine=INNODB
log_error = error.log
```

##### 配置启动脚本
```
[root@master1 ~]# cd /usr/local/mysql/support-files
[root@master1 support-files]# cp -a mysql.server /etc/init.d/mysql
[root@master1 support-files]# vim /etc/init.d/mysql # 增加=之后的内容
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
[root@master1 init.d]# cd ~
[root@master1 ~]# vim ~/.bash_profile # 设置环境变量需添加如下语句
export PATH=$PATH:/usr/local/mysql/bin
[root@master1 ~]# source ~/.bash_profile
[root@master1 ~]# systemctl daemon-reload # 重载系统配置
[root@master1 ~]# systemctl start mysql
[root@master1 ~]# /usr/lib/systemd/systemd-sysv-install enable mysql # 开机启动
```

```
[root@master1 ~]# mysql -uroot -p
mysql> update mysql.user set host="%" where user="root";
mysql> flush privileges;
mysql> exit
若选择安装完毕后进行克隆主机作为mater2,则必须要修改master2的server-uuid,否则无法进行下列主从服务器的搭建
[root@master1 ~]# cat /usr/local/mysql/data/auto.cnf
[auto]
server-uuid=f15a54e5-5954-11ef-a5b0-000c29daf3cc
# 只需删除master2的/usr/local/mysql/data/auto.cnf文件重启即可重新生成
```

**方法二:YUM 源安装 MySQL**
```
1. 添加 MySQL YUM 源
[root@master1 ~]# wget https://dev.mysql.com/get/mysql80-community-release-el7-9.noarch.rpm
安装 YUM 源
[root@master1 ~]# rpm -ivh mysql80-community-release-el7-9.noarch.rpm
检查 YUM 源是否添加成功
[root@master1 ~]# yum repolist enabled | grep mysql
2. 安装 MySQL 服务器
[root@master1 ~]# yum install -y mysql-community-server
或者安装完整的 MySQL 套件
[root@master1 ~]# yum install -y mysql-community-server mysql-community-client mysql-community-common mysql-community-devel
3. 启动 MySQL 服务
[root@master1 ~]# systemctl start mysqld
设置开机自启
[root@master1 ~]# systemctl enable mysqld
检查服务状态
[root@master1 ~]# systemctl status mysqld
4. 获取初始密码
MySQL 8.0 首次启动会生成临时密码
[root@master1 ~]# grep 'temporary password' /var/log/mysqld.log
5. 安全配置 MySQL
使用临时密码登录
[root@master1 ~]# mysql -uroot -p
修改 root 密码
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourNewPassword123!';
运行安全配置脚本(可选,会引导你进行多项安全设置)
[root@master1 ~]# mysql_secure_installation
6. 配置 MySQL
# 编辑配置文件
[root@master1 ~]# vim /etc/my.cnf
添加以下配置
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
default-storage-engine=INNODB
max_connections=1000
[client]
default-character-set=utf8mb4
7. 重启 MySQL 服务
[root@master1 ~]# systemctl restart mysqld
8. 配置远程访问
登录 MySQL
[root@master1 ~]# mysql -uroot -p
创建远程访问用户
mysql> CREATE USER 'root'@'%' IDENTIFIED BY 'YourPassword123!';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
或者修改 root 用户的 host
mysql> UPDATE mysql.user SET host='%' WHERE user='root';
mysql> FLUSH PRIVILEGES;
9. 防火墙配置
开放 3306 端口
[root@master1 ~]# firewall-cmd --permanent --add-port=3306/tcp
[root@master1 ~]# firewall-cmd --reload
10. 验证安装
检查 MySQL 版本
[root@master1 ~]# mysql --version
登录测试
[root@master1 ~]# mysql -uroot -p -h127.0.0.1
查看数据库
mysql> SHOW DATABASES;
重要记录
- 数据目录:`/var/lib/mysql`
- 配置文件:`/etc/my.cnf`
- 日志文件:`/var/log/mysqld.log`
- PID 文件:`/var/run/mysqld/mysqld.pid`
- Socket 文件:`/var/lib/mysql/mysql.sock`
```

#### msyql集群搭建
##### 说明
* 搭建主-主集群,两个节点都是主库,也都属于对方的从库,也就是两者之间会相互同步数据,这时为了防止主键出现冲突,一般都会通过设置数据库自增步长的方式来防重
* 主-主架构集群适用于中读写请求的比例对半开,同时整体的并发量也不算低,至少超出了单库的承载阈值的场景下,架构图如下
编辑
#### MySQL双主集群搭建
* 两台服务器信息如下:
| 主机名 | IP地址 | 系统 / 软件 |
|---------|----------------|------------------------------|
| matser1 | 172.25.254.128 | OpenEuler22.03 / MySql8.0.37 |
| matser2 | 172.25.254.129 | OpenEuler22.03 / MySql8.0.37 |
##### 步骤
* 修改2个主节点的配置文件
* 创建一个用于同步数据的账号
* 建立2个主节点的相互复制
* 测试
##### 主主复制配置
**master1配置 (/etc/my.cnf)(创建用于同步的账号):**
```
[root@master1 ~]# systemctl stop mysql
[root@master1 ~]# vim /etc/my.cnf
[client]
port = 3306
socket = /tmp/mysql.sock
[mysqld]
port = 3306
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
tmpdir = /tmp
socket = /tmp/mysql.sock
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
default-storage-engine=INNODB
log_error = error.log
server-id=1
log-bin=mysql-bin-log
binlog-ignore-db=mysql
binlog_format=mixed
max_binlog_size=1024M
relay_log=mysql-relay-log
log_bin_trust_function_creators=true
slave_skip_errors=1062
auto_increment_offset=1
auto_increment_increment=2
```

```
[root@master1 ~]# systemctl start mysql
[root@master1 ~]# mysql -uroot -p
mysql> create user 'mback'@'%' identified with mysql_native_password by '123456';
Query OK, 0 rows affected (0.01 sec)
mysql> grant replication slave on *.* to 'mback'@'%';
Query OK, 0 rows affected (0.00 sec)
```

**master2配置 (/etc/my.cnf)(创建用于同步的账号):**
```
[root@master2 ~]# systemctl stop mysql
[root@master2 ~]# vim /etc/my.cnf
[client]
port = 3306
socket = /tmp/mysql.sock
[mysqld]
port = 3306
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
tmpdir = /tmp
socket = /tmp/mysql.sock
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
default-storage-engine=INNODB
log_error = error.log
server-id=2
log-bin=mysql-bin-log
binlog-ignore-db=mysql
binlog_format=mixed
max_binlog_size=1024M
relay_log=mysql-relay-log
log_bin_trust_function_creators=true
slave_skip_errors=1062
auto_increment_offset=2
auto_increment_increment=2
```

```
[root@master2 ~]# systemctl start mysql
[root@master2 ~]# mysql -uroot -p
mysql> create user 'mback'@'%' identified with mysql_native_password by '123456';
Query OK, 0 rows affected (0.01 sec)
mysql> grant replication slave on *.* to 'mback'@'%';
Query OK, 0 rows affected (0.00 sec)
```

##### 3.3.3 主从关系建立
**master1指向master2:**
```
mysql> change master to master_host='192.168.88.162',master_user='mback',master_password='123456',master_port=3306,master_log_file='mysql-bin-log.000001',master_log_pos=672;
Query OK, 0 rows affected, 9 warnings (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 192.168.88.162
Master_User: mback
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin-log.000001
Read_Master_Log_Pos: 672
Relay_Log_File: mysql-relay-log.000002
Relay_Log_Pos: 330
Relay_Master_Log_File: mysql-bin-log.000001
Slave_IO_Running: Yes # 这里必须为yes
Slave_SQL_Running: Yes # 这里必须为yes
```

**master2指向master1:**
```
mysql> change master to master_host='192.168.88.161',master_user='mback',master_password='123456',master_port=3306,master_log_file='mysql-bin-log.000001',master_log_pos=672;
Query OK, 0 rows affected, 9 warnings (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 192.168.88.161
Master_User: mback
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin-log.000001
Read_Master_Log_Pos: 672
Relay_Log_File: mysql-relay-log.000002
Relay_Log_Pos: 330
Relay_Master_Log_File: mysql-bin-log.000001
Slave_IO_Running: Yes # 这里必须为yes
Slave_SQL_Running: Yes # 这里必须为yes
```

##### 复制状态验证
两台主机均显示:
```
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
```

#### 数据同步测试
```
数据库创建测试
在master1创建数据库:
CREATE DATABASE test1;
在master2验证同步成功。
表结构同步测试
在master2创建表:
USE test1;
CREATE TABLE back_test (
user_id INT(8) NOT NULL,
user_name VARCHAR(255) NOT NULL,
user_sex VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
register_time DATETIME
);
在master1验证表结构同步成功。
```

#### Keepalived高可用配置
##### Keepalived安装
```
[root@master1 ~] yum install keepalived -y
```

##### master1配置
```
[root@master1 ~] vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id mysql-master01
}
vrrp_instance VI_1 {
state BACKUP
interface ens32
virtual_router_id 51
priority 100
nopreempt
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.200
}
}
virtual_server 172.25.254.200 3306 {
delay_loop 6
lb_algo rr
lb_kind DR
persistence_timeout 50
protocol TCP
real_server 172.25.254.128 3306 {
notify_down /etc/keepalived/chk_mysql.sh
weight 1
TCP_CHECK {
connect_port 3306
connect_timeout 3
retry 3
delay_before_retry 3
}
}
}
```


##### MySQL健康检查脚本
```
[root@master1 ~] vim /etc/keepalived/chk_mysql.sh
#!/bin/bash
counter=$(netstat -na|grep "LISTEN"|grep "3306"|wc -l)
if [ "${counter}" -eq 0 ]; then
killall keepalived
fi
chmod +x /etc/keepalived/chk_mysql.sh
```


```
[root@master1 ~]# chmod +x /etc/keepalived/chk_mysql.sh
[root@master1 ~]# systemctl start keepalived
[root@master1 ~]# systemctl status keepalived
● keepalived.service - LVS and VRRP High Availability Monitor
Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled)
Active: active (running) since Wed 2024-08-14 09:02:49 CST; 15min ago
[root@master1 ~]# ip a
1: lo: