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

基于Mysqlrouter+MHA+keepalived实现高可用半同步 MySQL Cluster项目

目录

项目名称: 基于Mysqlrouter + MHA + keepalived实现半同步主从复制MySQL Cluster

MySQL Cluster: 

项目架构图:

项目环境:

项目环境安装包:

项目描述:

项目IP地址规划:

项目步骤:

一、准备13台全新虚拟机,按照IP规划配置好静态IP,修改主机名。安装部署Ansible,并建立Ansible的免密通道,调用一键二进制安装MySQL脚本,自动化批量部署MySQL

1、根据ip规划配置好静态ip

2、修改主机名 

3、建立Ansible免密通道

4、安装部署ansible

5、准备好MySQL软件包(mysql-5.7.41-linux-glibc2.12-x86_64.tar.gz),上传到linux的root目录下,并上传一键二进制安装mysql脚本

6、编写主机清单,加入主机组

7、编写playbook,上传源码包到远程服务器,调用本地脚本二进制安装MySQL

8、检查yaml文件语法,并执行yaml文件 

9、查看Mysql是否安装成功

二、配置GTID+Mysql半同步主从复制模式(semi-sync),实现MySQL热备,并为读写分离、故障转移做准备

1、在master服务器上开启二进制日志并配置server_id=1,并且在slave服务器上配置server_id=2

2、刷新master和slave上的Mysql数据库服务

3、查看是否开启二进制日志和GTID功能

4、在master上创建可以给slave服务器过来复制二进制日志文件的用户

5、在master上做一个全备,导出数据,导入到slave上,保持master和slave上的数据是一致的

6、再将导出的数据传出到slave服务器上去,并将该sql文件导入Mysql数据库中

7、将该sql文件导入Mysql数据库中,并检查我们的slave的Mysql数据是否与master的Mysql数据一致

8、在slave上配置master上拉取的二进制日志用户名和密码和日志文件名称和位置号和端口等信息

9、启动slave服务器,查看IO线程和SQL线程是否正常启动

10、创建新数据库,用于测试GTID是否启用

11、查看效果GTID效果

12、启用半同步复制

12.1、在主服务器master上执行安装:

12.2、在从服务器slave上执行安装:

12.3、接下来我们将启用我们下载好的插件(在master服务器上)

12.4、在slave服务器上启用我们下载好的插件

12.5、接下来我们将在slave从服务器上刷新服务

12.6、查看是否在slave上打开了半同步复制

12.7、验证是否可以实现同步操作:

12.8、验证是否可以实现异步操作:

三、配置一台延迟备份服务器,从MySQL-slave1上读取二进制文件

1、先在backup_delay机器上安装mysql数据库,再在mysql数据库内添加配置信息(我们延迟备份的机器是slave1)

2、 查看backup_delay延迟服务器的状态:

四、rsync+sersync+计划任务 实现实时同步全备数据(数据备份)

1、对master进行建库建表并插入数据,用于模拟企业已经存在的真实数据,也方便后续效果测试

2、计划任务定时全备数据

2.1、编写数据备份脚本 

2.2、编写计划任务,每天凌晨2点全备数据

3、rsync+sersync实现备份数据实时同步到异地备份服务器

rsync - backup备份服务器操作 

3.1、新建/backup文件夹,用于存放备份数据

3.2、安装rsync服务端软件

3.3、设置开机启动

3.4、启动xinetd,查看进程(看到进程说明xinetd已经启动成功)

3.5、修改/etc/rsyncd.conf配置文件 (注意:[back_data]最好不要加注释,防止出错)

3.6、创建用户认证文件

3.7、设置文件权限

3.8、启动rsync,查看对应的进程、端口 (看到进程,就说明rsync启动成功、xinetd监听873端口)

rsync - master数据源服务器操作

3.9、在master上安装rsync、xinetd软件

3.10、启动xinetd,查看进程

3.11、修改/etc/rsyncd.conf配置文件(注意:[sync]段配置文件最好不要加注释,防止报错)

3.12、创建用户认证文件

3.13、设置文件权限,非root用户不可读认证文件

3.14、测试数据同步

3.15、数据源服务器增加文件或者删除文件,看备份服务器/backup/是否有变化

4、安装sersync工具,inotify实时触发rsync进行同步–数据源服务器操作

4.1、修改inotify默认参数(inotify默认内核参数过小),修改参数(inotify在内核里已经安装了,只需要传参)

4.2、设置永久生效

4.3、装sersync软件包

4.4、解压sersync软件

4.5、创建sersync

4.6、修改配置 data_configxml.xml

4.7、加入PATH环境变量,并设置开机永久生效 

4.8、启动sersync(启动成功如下)

4.9、查看sersync进程

4.10、设置sersync监控开机自动执行

4.11、效果测试

五、Ansible批量部署mha软件环境,搭建MHA高可用架构,实现自动failover,完成主从切换

1、编写主机清单,增添4个mha node节点ip地址,以及一个mha manager节点ip地址

2、编写一键安装mha node脚本和一键安装mha mangaer脚本

3、编写playbook,上传源码包到家目录下,调用本地脚本,远程安装部署mha相关软件环境

4、执行playbook

5、所有服务器互相建立免密通道

5.1、mha manager对所有mysql服务器建立免密通道

5.2、master对slave1、slave2建立免密通道

5.3、slave1对master、slave2建立免密通道

 5.4、slave2对master、slave1建立免密通道

6、在搭建好的主从复制服务器里,配置mha相关信息

6.1、所有mysql服务器加入log_bin和log-slave-updates,并刷新配置文件

6.2、所有mysql服务器(master、slave1、slave2)将mysql命令和mysqlbinlog命令软链接到/usr/sbin,方便manager管理节点

6.3、所有mysql服务器新建允许manager访问的授权用户mha,密码123456

7、在mha manager节点上配置好相关脚本、管理节点服务器

7.1、mha manager节点上复制相关脚本到/usr/local/bin下

7.2、复制自动切换时vip管理的脚本到/usr/local/bin下

7.3、修改master_ip_failover文件内容,配置vip(只配置vip相关参数,其他默认不修改)

7.4、创建 MHA 软件目录并复制配置文件,使用app1.cnf配置文件来管理 mysql 节点服务器,配置文件一般放在/etc/目录下(注意:注释只是提示用,编辑配置文件时最好不要加注释,否则很可能会出错)

8、master服务器上手工开启vip

9、manager节点上测试ssh免密通道,如果正常最后会输出successfully(注意是否每台mysql间都建立了ssh免密通道,否则会报错)

10、在 manager 节点上测试 mysql 主从连接情况,最后出现 MySQL Replication Health is OK 字样说明正常(如果报错,思考是否软链接建立好了?或者主从复制搭建正确了)

11、manager节点后台开启MHA

11.1、查看 MHA 状态,可以看到当前的 master 是 Mysql1 节点

11.2、查看MHA日志,看到当前matser是192.168.2.150

11.3、查看mha进程

六、搭建mysqlrouter-keepalived集群,实现高可用 - 读写分离功能,减轻主节点的压力

1、下载安装Mysql-router:MySQL :: Download MySQL Router

2、安装Mysql-router并解压:

3、修改mysqlrouter配置文件:(mysqlrouter必须绑定到keepalived设定的vip上或者使用任意地址0.0.0.0上)(切记不能添加注释,我添加是为了方便解释,否则会报错)

4、刷新mysqlrouter服务,并查看端口:

5、安装配置keepalived服务

6、修改keepalived的配置文件(从36行以下的全部都不需要)(配置单vip的高可用服务)

6.1、master上的配置

6.2、backup上的配置

7、重新启动keepalived服务

7.1、查看效果:

8、模拟测试:如果master挂掉了,那么vip是否会转移到backup上去呢?

8.1、我们将master上的keepalived关闭,查看backup上的ip地址

8.2、backup上的IP地址

8.3、当我们重启master,vip又会从backup上漂移到master上去的

9、外部连接测试keepalived实现的高可用效果:

10、配置双vip实现keepalived配置(跟MySQL的主主复制十分相似)

10.1、master配置文件:

10.2、backup配置文件:

10.3、刷新keepalived服务,并查看master和backup的IP地址

七、使用sysbench压力测试工具测试整个数据库集群的性能,了解集群系统性能资源的瓶颈

1、安装sysbench工具

2、调大内核资源限制

3、在master上创建用户和库,配置用户的权限可以使他可以访问库(Mysql的主从复制)

4、基于sysbench构造测试表和测试数据

5、创建我们需要的数据库里的数据

6、数据库读写性能测试(获取测试数据)

7、执行完成压测之后可以将run改成cleanup,清除数据

8、IO性能压力测试

8.1、创建5个文件,总共500MB,每个文件大概100MB

8.2、测试效果

8.3、清除数据:

9、cpu性能压力测试

八、搭建基于prometheus + grafana的监控系统,对数据库集群进行监控

1、安装部署mysqld_exporter

2、上传软件包到linux的/root/目录下

3、解压,并移动到/usr/local/mysqld_exporter下

4、在/usr/local/mysqld_exporter下编辑连接本机数据库的配置文件

5、将mysqld_exporter命令加入环境变量,并设置开机自启

6、后台启动

7、看进程,看端口,网页访问测试

8、安装prometheus,配置成服务

8.1、上传安装包到linux家目录下

8.2、解压Prometheus压缩包,并移动到/prometheus目录下

8.3、将Prometheus配置成service服务

8.4、查看Prometheus端口

8.4、访问Prometheus服务页面

9、Prometheus添加node节点

9.1、刷新Prometheus服务

10、测试访问Prometheus服务:

11、安装grafana

11.1、上传grafana的rpm安装包

11.2、安装grafana

11.3、启动grafana

11.4、查看端口,并访问测试grafana

12、在grafana中增添Prometheus数据源

13、添加Dashboards模板(推荐使用14057模板,因为14057模板比较美观,出图效果也比较好,推荐使用)

14、grafana效果展示

九、搭建DNS主域名服务器,增添两条负载均衡记录,实现对Mysqlrouter双vip地址的DNS负载均衡

1、安装DNS服务

2、修改dns配置文件,任意ip可以访问本机的53端口,并且允许dns解析。

3、搭建主域名服务器

3.1、修改named.rfc1912.zones配置文件,告诉named为claylpf.xyz提供域名解析

3.2、创建claylpf.xyz主域名的数据文件

3.3、修改claylpf.xyz.zone文件:

3.4、刷新dns服务

4、效果测试

4.1、修改linux客户机的dns服务器的地址为搭建的dns服务器192.168.2.155

4.2、查看效果

项目结束!!

项目遇到的问题

项目心得 


项目名称: 基于Mysqlrouter + MHA + keepalived实现半同步主从复制MySQL Cluster

MySQL Cluster: 

MySQL Cluster 是 MySQL 数据库的一种高可用性和高可扩展性解决方案,特别适用于需要在分布式环境中提供实时访问和处理大量数据的应用。MySQL Cluster 使用了分布式架构和内存数据库技术,可以提供高度可用的数据库服务,同时支持水平扩展和垂直扩展。

项目架构图:

项目环境:

软件环境
CentOS:CentOS Linux release 7.9.2009 (Core)
MySQL:mysql  Ver 14.14 Distrib 5.7.41, for linux-glibc2.12 (x86_64) using  EditLine wrapper
mha manager:mha4mysql-manager-0.58
mha node:mha4mysql-node-0.58
Mysqlrouter:MySQL Router  Ver 8.0.34 for Linux on x86_64 (MySQL Community - GPL)
Keepalived: Keepalived v1.3.5 (03/19,2017)
sysbench:sysbench 1.0.17
Ansible:ansible 2.9.27
Prometheus: prometheus, version 2.43.0
mysqld_exporter:mysqld_exporter, version 0.15.1
Grafana: grafana 9.4.7
DNS:BIND 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.13

项目环境安装包:

链接:https://pan.baidu.com/s/184n8h0mxUmt1_ETq3wTwRg?pwd=frm3 
提取码:frm3

项目描述:

本项目旨在通过整合 MySQL Router、MHA(Master High Availability)以及 Keepalived 等关键技术,构建一个高可用半同步 MySQL 集群解决方案。通过该解决方案,实现 MySQL 数据库的高可用性、负载均衡以及半同步主从复制,以提供稳定和高效的数据库服务,能方便处理大并发的后端MySQL业务。

项目IP地址规划:

主机名                                             IP地址
Linux客户机                              192.168.2.77
mysqlrouter1                192.168.2.181 vip 192.168.2.221
mysqlrouter2                192.168.2.182 vip 192.168.2.201
mha_manager、mha_node    192.168.2.141
master、mha_node     192.168.2.150 vip 192.168.2.227
slave1、mha_node                   192.168.2.151 
slave2、mha_node                   192.168.2.152
ansible                                       192.168.2.230
sysbench                                   192.168.2.162
prometheus+grafana                192.168.2.149
dns                                             192.168.2.155

backup                                       192.168.2.157

backup_delay                            192.168.2.78

项目步骤:

一、准备13台全新虚拟机,按照IP规划配置好静态IP,修改主机名。安装部署Ansible,并建立Ansible的免密通道,调用一键二进制安装MySQL脚本,自动化批量部署MySQL

1、根据ip规划配置好静态ip

参考:计算机网络 day6 arp病毒 - ICMP协议 - ping命令 - Linux手工配置IP地址_Claylpf的博客-CSDN博客

[root@master ~]# vi /etc/sysconfig/network-scripts/ifcfg-ens33 
BOOTPROTO=static #静态配置ip
NAME=ens33 #网卡名称ens33
DEVICE=ens33 #本机网卡ens33
ONBOOT=yes #开机启动
IPADDR=192.168.2.150 #ip地址
PREFIX=24 #子网掩码24
GATEWAY=192.168.2.1 #我选择的是桥接网络,所以网关是路由器ip 192.168.2.1
DNS1=114.114.114.114 #dns服务器114.114.114.114[root@master ~]# service network restart #重启网络
Restarting network (via systemctl):                        [  确定  ]
[root@master ~]# ip add #查看ip
[root@master ~]# ping www.baidu.com #测试能否上网

2、修改主机名 

[root@master ~]# hostnamectl set-hostname master #修改指定主机名,方便辨认
[root@master ~]# su -

3、建立Ansible免密通道

参考:Linux - SSH服务 - SCP - 免密通道建立_服务器只允许堡垒机登录_Claylpf的博客-CSDN博客

[root@ansible ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
/root/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:wyZdVrUlL22pZs6sLTAXx/FTcrW66v8CDCtqrQEXBnA root@ansible
The key's randomart image is:
+---[RSA 2048]----+
| ..E        ..o +|
|  . .      . ..*=|
|     o    o . ===|
|    . .o + . oo= |
|   . .. S + o=  .|
|    o  + = +* .  |
|     .o . + .=   |
|     o..   .+.   |
|    ...   .+ooo. |
+----[SHA256]-----+
[root@ansible ~]# [root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.150  #master[root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.151  #slave1[root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.152  #slave2[root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.141  #mha_manager[root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.149  #Prometheus[root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.181  #mysqlrouter1[root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.182  #mysqlrouter2[root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.162  #sysbench

4、安装部署ansible

参考:ansible ansible的组成 - ansible的配置免密通道 - ansible 常用模块 - playbook模块的使用_Claylpf的博客-CSDN博客

[root@ansible ~]# yum install -y epel-release
[root@ansible ~]# yum install ansible

5、准备好MySQL软件包(mysql-5.7.41-linux-glibc2.12-x86_64.tar.gz),上传到linux的root目录下,并上传一键二进制安装mysql脚本

参考:Mysql的介绍和软件环境的部署_mysql有软件吗_Claylpf的博客-CSDN博客

[root@master ~]# cat onekey_install_mysql_binary.sh 
#!/bin/bash#步骤:
#解决软件依赖关系
yum install cmake ncurses-devel gcc gcc-c++ vim lsof bzip2 openssl-devel -y#解压二进制安装包
tar xf mysql-5.7.41-linux-glibc2.12-x86_64.tar.gz#移动mysql解压文件到/usr/local下,改名为mysql
mv mysql-5.7.41-linux-glibc2.12-x86_64 /usr/local/mysql#新建组和用户 mysql
groupadd mysql#mysql这个用户的shell 是/bin/false 无法被调用 表示系统用户 属于mysql这个组
useradd -r -g mysql -s /bin/false mysql#进入/usr/local/mysql
cd /usr/local/mysql#关闭firewalld防火墙服务,并且设置开机不启动
service firewalld stop
systemctl disable firewalld #临时关闭selinux,永久关闭selinux
setenforce 0
sed -i '/^SELINUX=/ s/enforcing/disabled/' /etc/selinux/config#mysql初始化操作
#创建/data/mysql文档用于存放数据使用
mkdir /data/mysql -p
#修改文件权限和组别,这样mysql用户可以对这个文件夹进行读写操作了
chown mysql:mysql /data/mysql/
chmod 750 /data/mysql/#进入/usr/local/mysql/bin目录下进行初始化操作
cd /usr/local/mysql/bin
#设置启动用户为mysql base目录为/usr/local/mysql/ data目录为/data/mysql   &>passwd.txt目的是将生成的临时密码存入passwd.txt文件中
./mysqld --initialize --user=mysql --basedir=/usr/local/mysql/ --datadir=/data/mysql &>passwd.txt #让mysql支持ssl方式登录的设置
./mysql_ssl_rsa_setup --datadir=/data/mysql/#获得临时密码
tem_passwd=$(cat passwd.txt| grep "temporary" | awk '{print $NF}')
#$NF表示最后一个字段#修改环境变量,添加我们编译安装的mysql的可执行命令的路径
#临时修改PATH变量的值
export PATH=/usr/local/mysql/bin/:$PATH
#永久修改
echo "PATH=/usr/local/mysql/bin:$PATH" >>/root/.bashrc#刷新/root/.bashrc文件
source ~/.bashrc#复制support-files里的mysql.server文件到/etc/init.d目录下叫mysqld
cp ../support-files/mysql.server  /etc/init.d/mysqld#修改/etc/init.d/mysqld内的第70行的内容(datadir目录的值)
sed -i '70c  datadir=/data/mysql' /etc/init.d/mysqld#生成/etc/my.cnf配置文件
cat  >/etc/my.cnf  <<EOF
[mysqld_safe]
[client]
socket=/data/mysql/mysql.sock
[mysqld]
socket=/data/mysql/mysql.sock
port = 3306
open_files_limit = 8192
innodb_buffer_pool_size = 512M
character-set-server=utf8
[mysql]
auto-rehash
prompt=\\u@\\d \\R:\\m  mysql>
EOF#启动mysqld服务
service mysqld start#将mysqld添加到linux系统里的服务管理名单里
chkconfig --add mysqld
#设置mysqld服务开机启动
/sbin/chkconfig mysqld on#登录重新设置初始密码为123456
#初次修改密码需要使用 --connect-expired-password 选项
#-e 后面接的命令是表示我们需要在mysql里执行的命令
#set password='123456'; 表示修改root用户的密码为:123456 
mysql -uroot -p$tem_passwd --connect-expired-password -e "set password='123456';"#建议修改密码是否修改成功
mysql -uroot -p123456 -e 'show databases;' && echo "database is installed success" 
[root@master ~]# 

6、编写主机清单,加入主机组

[root@ansible ~]# cd /etc/ansible/
[root@ansible ansible]# ls
ansible.cfg  hosts  nginx  node_exporter  roles
[root@ansible ansible]# vim hosts
[root@ansible ansible]# cat hosts
[mysql]
192.168.2.150 #master
192.168.2.151 #slave1
192.168.2.152 #slave2
[root@ansible ansible]# 

7、编写playbook,上传源码包到远程服务器,调用本地脚本二进制安装MySQL

[root@ansible ansible]# vim software_install.yaml
[root@ansible ansible]# cat software_install.yaml 
- hosts: mysqlremote_user: roottasks:- name: copy file  #上传本地源码包到mysql主机组copy: src=/root/mysql-5.7.41-linux-glibc2.12-x86_64.tar.gz dest=/root/- name: one key binary install mysql  #调用本地二进制安装脚本,远程执行安装mysqlscript: /root/onekey_install_mysql_binary.sh- name: alter path #确保mysql命令加入环境变量shell: export PATH=/usr/local/mysql/bin/:$PATH
[root@ansible ansible]# 

使用ansible中的copy模块上传源码包时,速度可能比较慢—可以考虑直接使用xshell里的xftp工具直接上传,不写playbook

8、检查yaml文件语法,并执行yaml文件 

[root@ansible ansible]# ansible-playbook --syntax-check /etc/ansible/software_install.yaml  # 检查yaml文件语法playbook: /etc/ansible/software_install.yaml
[root@ansible ansible]# ansible-playbook  software_install.yaml  # 执行yaml文件

9、查看Mysql是否安装成功

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
database is installed success[root@slave1 ~]# ps aux|grep mysql
root      23541  0.0  0.1  11824  1596 pts/1    S    05:36   0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/data/mysql --pid-file=/data/mysql/slave1.pid
mysql     23695  1.0 20.6 1544672 205120 pts/1  Sl   05:36   0:00 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/mysql --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=slave1.err --open-files-limit=8192 --pid-file=/data/mysql/slave1.pid --socket=/data/mysql/mysql.sock --port=3306
root      23769  0.0  0.0 112824   988 pts/1    R+   05:37   0:00 grep --color=auto mysql
[root@slave1 ~]# 

二、配置GTID+Mysql半同步主从复制模式(semi-sync),实现MySQL热备,并为读写分离、故障转移做准备

参考:Mysql - 主从复制介绍_Claylpf的博客-CSDN博客

1、在master服务器上开启二进制日志并配置server_id=1,并且在slave服务器上配置server_id=2

master上

[root@master ~]# cat /etc/my.cnf
[mysqld_safe][client]
socket=/data/mysql/mysql.sock[mysqld]
socket=/data/mysql/mysql.sock
log-error=/data/mysql/mysql_error.log     #表示设置Mysql的error日志的路径
slow_query_log = 1      #表示开启Mysql慢日志
long_query_time = 0.001  #表示设置慢日志的阈值为0.001毫秒
general_log            #我们不需要添加路径了,因为Mysql会自动帮助我们添加通用日志的路径和日志文件,表示打开了通用日志
log_bin                #表示我们开启了二进制日志
server_id = 1          #给我们的Mysql服务器进行编号
expire_logs_days = 7   #表示二进制日志文件过 7天 自动清除
#开启GTID功能
gtid-mode=ON
enforce-gtid-consistency=ON
#设置主服务器半同步超时时间
rpl_semi_master_timeout=10
#开启主服务器半同步主从复制
rpl_semi_master_enabled=1port = 3306
open_files_limit = 8192
innodb_buffer_pool_size = 512M
character-set-server=utf8[mysql]
auto-rehash
prompt=\u@\d \R:\m  mysql>
[root@master ~]# 

slave上

[root@slave1 ~]# cat /etc/my.cnf
[mysqld_safe][client]
socket=/data/mysql/mysql.sock[mysqld]
socket=/data/mysql/mysql.sock
log-error=/data/mysql/mysql_error.log     #表示设置Mysql的error日志的路径
slow_query_log = 1      #表示开启Mysql慢日志
long_query_time = 0.001  #表示设置慢日志的阈值为0.001毫秒
general_log            #我们不需要添加路径了,因为Mysql会自动帮助我们添加通用日志的路径和日志文件,表示打开了通用日志
log_bin                #表示我们开启了二进制日志
server_id = 2          #给我们的Mysql服务器进行编号
expire_logs_days = 7   #表示二进制日志文件过 7天 自动清除
#开启GTID功能
gtid-mode=ON
enforce-gtid-consistency=ON
#开启从服务器半同步主从复制
rpl_semi_sync_slave_enabled=1port = 3306
open_files_limit = 8192
innodb_buffer_pool_size = 512M
character-set-server=utf8[mysql]
auto-rehash
prompt=\u@\d \R:\m  mysql>
[root@slave1 ~]# 

切记:slave1、slave2配置一致,但是server_id绝对不能一样,slave1我设置的是2,slave2设置的是3 

2、刷新master和slave上的Mysql数据库服务

[root@master ~]# systemctl restart mysqld

3、查看是否开启二进制日志和GTID功能

root@(none) 13:48  mysql>show variables like "%log_bin%";
+---------------------------------+------------------------------+
| Variable_name                   | Value                        |
+---------------------------------+------------------------------+
| log_bin                         | ON                           |#已开启
| log_bin_basename                | /data/mysql/master-bin       |
| log_bin_index                   | /data/mysql/master-bin.index |
| log_bin_trust_function_creators | OFF                          |
| log_bin_use_v1_row_events       | OFF                          |
| sql_log_bin                     | ON                           |
+---------------------------------+------------------------------+
6 rows in set (0.01 sec)root@(none) 13:49  mysql>show variables like "%gtid%";
+----------------------------------+-----------+
| Variable_name                    | Value     |
+----------------------------------+-----------+
| binlog_gtid_simple_recovery      | ON        |
| enforce_gtid_consistency         | ON        |
| gtid_executed_compression_period | 1000      |
| gtid_mode                        | ON        |#已开启
| gtid_next                        | AUTOMATIC |#已开启
| gtid_owned                       |           |
| gtid_purged                      |           |
| session_track_gtids              | OFF       |
+----------------------------------+-----------+
8 rows in set (0.00 sec)root@(none) 13:49  mysql>

4、在master上创建可以给slave服务器过来复制二进制日志文件的用户

[root@master ~]# mysql -u root -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.41 MySQL Community Server (GPL)Copyright (c) 2000, 2023, 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.#创建sc_slave用户,允许任意网段访问
root@(none) 06:01  mysql>create user 'sc_slave'@'%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)#赋予该用户允许复制二进制日志文件的权限
root@(none) 06:02  mysql>grant replication slave on *.* to 'sc_slave'@'%';
Query OK, 0 rows affected (0.00 sec)#重新加载用户权限表
root@(none) 06:02  mysql>FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)root@(none) 06:02  mysql>

5、在master上做一个全备,导出数据,导入到slave上,保持master和slave上的数据是一致的

#为master上的数据做全备,并导出
[root@master ~]# mkdir /backup
[root@master ~]# mysqldump -uroot -p'123456' --all-databases > /backup/all_db.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@master ~]# 

6、再将导出的数据传出到slave服务器上去,并将该sql文件导入Mysql数据库中

[root@master ~]#  scp /backup/all_db.sql root@192.168.2.151:/root
all_db.sql                                                                                                                                                 100%  866KB  28.4MB/s   00:00    
[root@master ~]#  scp /backup/all_db.sql root@192.168.2.152:/root
all_db.sql                                                                                                                                                 100%  866KB  19.8MB/s   00:00    
[root@master ~]# 

7、将该sql文件导入Mysql数据库中,并检查我们的slave的Mysql数据是否与master的Mysql数据一致

[root@slave1 ~]# mysql -uroot -p'123456'  < all_db.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@slave1 ~]# 

8、在slave上配置master上拉取的二进制日志用户名和密码和日志文件名称和位置号和端口等信息

在master上查看二进制日志文件和位置号:

[root@master mysql]# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.41-log MySQL Community Server (GPL)Copyright (c) 2000, 2023, 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.# 刷新二进制文件 每运行一次flush logs; 会从新创建一个二进制文件
root@(none) 06:33  mysql>flush logs;
Query OK, 0 rows affected (0.01 sec)# 查看正在使用的二进制文件和它对应的位置号
root@(none) 06:33  mysql>show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000002 |      154 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)root@(none) 06:33  mysql>

上图所示,我通过flush logs命令刷新了二进制日志,产生了一个新的二进制日志文件,位置号为:154。

在slave上配置关于master的配置并上拉取二进制日志的用户信息和日志文件的名称和位置号

[root@slave2 ~]# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.41 MySQL Community Server (GPL)Copyright (c) 2000, 2023, 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.# 在slave上配置master的信息
root@(none) 06:35  mysql>CHANGE MASTER TO MASTER_HOST='192.168.2.150',-> MASTER_USER='sc_slave',-> MASTER_PASSWORD='123456',-> MASTER_PORT=3306,-> MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)root@(none) 06:35  mysql>

9、启动slave服务器,查看IO线程和SQL线程是否正常启动

直接使用start slave命令

如果启动了,可以查看如下:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes 

如果出现了上述内容,说明Mysql的主从复制功能成功的搭建了

# 在slave上运行, 目的是启动slave服务
root@(none) 06:41  mysql>start slave;
Query OK, 0 rows affected (0.00 sec)root@(none) 06:41  mysql>show slave status\G;
*************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 192.168.2.150Master_User: sc_slaveMaster_Port: 3306Connect_Retry: 60Master_Log_File: master-bin.000002Read_Master_Log_Pos: 154Relay_Log_File: slave1-relay-bin.000002Relay_Log_Pos: 321Relay_Master_Log_File: master-bin.000002Slave_IO_Running: Yes           #说明主从复制服务建立成功Slave_SQL_Running: Yes           #说明主从复制服务建立成功Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: Skip_Counter: 0Exec_Master_Log_Pos: 154Relay_Log_Space: 529Until_Condition: NoneUntil_Log_File: Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: NoLast_IO_Errno: 0Last_IO_Error: Last_SQL_Errno: 0Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1Master_UUID: 4cb77830-3958-11ee-83a7-000c29615077Master_Info_File: /data/mysql/master.infoSQL_Delay: 0SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Slave has read all relay log; waiting for more updatesMaster_Retry_Count: 86400Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 
1 row in set (0.00 sec)ERROR: 
No query specifiedroot@(none) 06:42  mysql>

10、创建新数据库,用于测试GTID是否启用

root@(none) 14:09  mysql>create database gtid;
Query OK, 1 row affected (0.00 sec)root@(none) 14:10  mysql>show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| gtid               |
| liubo              |
| liubo2             |
| mysql              |
| performance_schema |
| sys                |
| test1              |
| test_db            |
+--------------------+
9 rows in set (0.00 sec)

11、查看效果GTID效果

master上
root@(none) 14:28  mysql>show master status\G;
*************************** 1. row ***************************File: master-bin.000004Position: 313Binlog_Do_DB: Binlog_Ignore_DB: 
Executed_Gtid_Set: 4cb77830-3958-11ee-83a7-000c29615077:1
1 row in set (0.00 sec)ERROR: 
No query specifiedslave上
root@(none) 14:11  mysql>show slave status\G;
*************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 192.168.2.150Master_User: sc_slaveMaster_Port: 3306Connect_Retry: 60Master_Log_File: master-bin.000004Read_Master_Log_Pos: 313Relay_Log_File: slave1-relay-bin.000011Relay_Log_Pos: 369Relay_Master_Log_File: master-bin.000004Slave_IO_Running: YesSlave_SQL_Running: YesReplicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: 0Exec_Master_Log_Pos: 154Relay_Log_Space: 903Until_Condition: NoneUntil_Log_File: Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: NoLast_IO_Errno: 0Last_IO_Error: Last_SQL_Errno: 0Last_SQL_Error: 0Replicate_Ignore_Server_Ids: Master_Server_Id: 1Master_UUID: 4cb77830-3958-11ee-83a7-000c29615077Master_Info_File: /data/mysql/master.infoSQL_Delay: 0SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Master_Retry_Count: 86400Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: 230813 14:11:09Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: 4cb77830-3958-11ee-83a7-000c29615077:1  #GTID号,出现则代表gtid功能已经实现了Executed_Gtid_Set: 4cb77830-3958-11ee-83a7-000c29615077:1Auto_Position: 1Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 
1 row in set (0.00 sec)ERROR: 
No query specified

12、启用半同步复制

12.1、在主服务器master上执行安装:

root@(none) 06:44  mysql>INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.01 sec)root@(none) 06:44  mysql>

12.2、在从服务器slave上执行安装:

root@(none) 06:42  mysql>INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.01 sec)root@(none) 06:45  mysql>

我们可以通过命令show plugins;命令查看我们mysql安装的插件。

12.3、接下来我们将启用我们下载好的插件(在master服务器上)

root@(none) 06:44  mysql>SET GLOBAL rpl_semi_sync_master_enabled = 1;
Query OK, 0 rows affected (0.00 sec)root@(none) 06:47  mysql>

12.4、在slave服务器上启用我们下载好的插件

root@(none) 06:45  mysql>SET GLOBAL rpl_semi_sync_slave_enabled = 1;
Query OK, 0 rows affected (0.00 sec)root@(none) 06:48  mysql>

12.5、接下来我们将在slave从服务器上刷新服务

root@(none) 06:48  mysql>stop slave;
Query OK, 0 rows affected (0.00 sec)root@(none) 06:49  mysql>start slave;
Query OK, 0 rows affected (0.00 sec)root@(none) 06:49  mysql>

12.6、查看是否在slave上打开了半同步复制

root@(none) 06:51  mysql>show global variables like '%rpl_semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.00 sec)root@(none) 06:51  mysql>

在master上查看

root@(none) 06:47  mysql>show global variables like '%rpl_semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | ON         |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)root@(none) 06:51  mysql>

rpl_semi_sync_master_timeout, the value N is given in milliseconds. The default value is 10000 (10 seconds).意思是如果ack确认包在10秒钟内没有送达,master会启用异步模式

12.7、验证是否可以实现同步操作:

在master上创建一个新库;

root@(none) 06:51  mysql>create database liubo;
Query OK, 1 row affected (0.01 sec)

在slave上查看是否存在liubo库

root@(none) 06:53  mysql>show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| liubo              |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)root@(none) 06:53  mysql>

12.8、验证是否可以实现异步操作:

我们将slave服务中断,然后在master上创建一个库,10s过后,查看slave服务器上是否产生了相同的库

slave服务中断 

root@(none) 06:53  mysql>stop slave;
Query OK, 0 rows affected (0.00 sec)

在master上创建一个库 

# 10.01 sec 表示该过程持续了10s
root@(none) 06:53  mysql>create database liubo2;
Query OK, 1 row affected (10.01 sec)   root@(none) 06:56  mysql>

如上图所示,一共维持了10s钟才完成了库的创建,然后我们打开slave服务,查看slave服务器上是否存在了liubo2库 

root@(none) 06:56  mysql>start slave;
Query OK, 0 rows affected (0.00 sec)root@(none) 06:57  mysql>show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| liubo              |
| liubo2             |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)root@(none) 06:58  mysql>

如上图所示,当我们一打开slave服务,databases里面就出现了了lao10这个库,说明他变成了异步复制。而这两者的结合就是半同步复制。

三、配置一台延迟备份服务器,从MySQL-slave1上读取二进制文件

延迟服务器:backup_delay:192.168.2.78

1、先在backup_delay机器上安装mysql数据库,再在mysql数据库内添加配置信息(我们延迟备份的机器是slave1)

root@(none) 15:18  mysql>CHANGE MASTER TO MASTER_HOST='192.168.2.151',  #IP地址是slave1的IP-> MASTER_USER='sc_slave',-> MASTER_PASSWORD='123456',-> MASTER_PORT=3306,-> MASTER_AUTO_POSITION=1;                        # MASTER_AUTO_POSITION=1; 时,从节点会自动获取主节点的当前 GTID 位置
Query OK, 0 rows affected, 2 warnings (0.01 sec)root@(none) 15:18  mysql>change master to master_delay = 10; # 其中设置延迟备份时,默认情况下的单位是秒,我们这里是延迟10s钟拿取二进制日志
Query OK, 0 rows affected (0.01 sec)

2、 查看backup_delay延迟服务器的状态:

root@(none) 15:19  mysql>start slave;
Query OK, 0 rows affected (0.00 sec)root@(none) 15:19  mysql>show slave status\G;
*************************** 1. row ***************************Slave_IO_State: Master_Host: 192.168.2.151Master_User: sc_slaveMaster_Port: 3306Connect_Retry: 60Master_Log_File: master-bin.000002Read_Master_Log_Pos: 154Relay_Log_File: slave1-relay-bin.000002Relay_Log_Pos: 154Relay_Master_Log_File: master-bin.000002Slave_IO_Running: YesSlave_SQL_Running: YesReplicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: Skip_Counter: 0Exec_Master_Log_Pos: 154Relay_Log_Space: 577Until_Condition: NoneUntil_Log_File: Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: NoLast_IO_Errno: 1236Last_IO_Error: 0Last_SQL_Errno: 0Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1Master_UUID: 4cb77830-3958-11ee-83a7-000c29615077Master_Info_File: /data/mysql/master.infoSQL_Delay: 0SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Slave has read all relay log; waiting for more updatesMaster_Retry_Count: 86400Master_Bind: Last_IO_Error_Timestamp: 230813 15:19:57Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: 4cb77830-3958-11ee-83a7-000c29615077:1Executed_Gtid_Set: 4cb77830-3958-11ee-83a7-000c29615077:1Auto_Position: 1Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 
1 row in set (0.00 sec)

配置成功!

四、rsync+sersync+计划任务 实现实时同步全备数据(数据备份)

1、对master进行建库建表并插入数据,用于模拟企业已经存在的真实数据,也方便后续效果测试

root@(none) 06:56  mysql>create database test1;
Query OK, 1 row affected (0.00 sec)root@(none) 07:10  mysql>use test1;
Database changed
root@test1 07:11  mysql>create table t1(id int primary key,name varchar(20));
Query OK, 0 rows affected (0.01 sec)root@test1 07:11  mysql>insert into t1 values(1,'li');
Query OK, 1 row affected (0.04 sec)root@test1 07:11  mysql>insert into t1 values(2,'peng');
Query OK, 1 row affected (0.00 sec)root@test1 07:11  mysql>insert into t1 values(3,'fei');
Query OK, 1 row affected (0.00 sec)root@test1 07:11  mysql>select * from t1;
+----+------+
| id | name |
+----+------+
|  1 | li   |
|  2 | peng |
|  3 | fei  |
+----+------+
3 rows in set (0.00 sec)root@test1 07:11  mysql>

2、计划任务定时全备数据

2.1、编写数据备份脚本 

[root@master ~]# cd /backup/
[root@master backup]# vim backup_db.sh
[root@master backup]# cat backup_db.sh 
#!/bin/bash#导出数据库数据到/backup目录下,以日期时间的格式命名
mysqldump -uroot -p"123456#" --all-databases >/backup/$(date +%F)_all_db.sql
[root@master backup]# 

2.2、编写计划任务,每天凌晨2点全备数据

[root@master backup]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
[root@master backup]# crontab -l
30 2 * * * bash /backup/backup_db.sh
[root@master backup]# 

3、rsync+sersync实现备份数据实时同步到异地备份服务器

数据源服务器:master 192.168.2.150

备份服务器:backup 192.168.31.157

rsync - backup备份服务器操作 

3.1、新建/backup文件夹,用于存放备份数据

[root@backup ~]# mkdir /backup
[root@backup ~]# 

3.2、安装rsync服务端软件

[root@backup ~]# yum install -y epel-release[root@backup ~]# yum install -y rsync xinetd -y

3.3、设置开机启动

[root@backup ~]# echo "/usr/bin/rsync --daemon --config=/etc/rsyncd.conf"  #设置开机启动rsync" >>/etc/rc.d/rc.local 
/usr/bin/rsync --daemon --config=/etc/rsyncd.conf
[root@backup ~]# chmod +x /etc/rc.d/rc.local  #赋予可执行权限
[root@backup ~]# 

3.4、启动xinetd,查看进程(看到进程说明xinetd已经启动成功)

[root@backup ~]# systemctl start xinetd
[root@backup ~]# ps aux|grep xinetd
root      13695  0.0  0.0  25044   588 ?        Ss   06:20   0:00 /usr/sbin/xinetd -stayalive -pidfile /var/run/xinetd.pid
root      13697  0.0  0.0 112824   976 pts/1    S+   06:20   0:00 grep --color=auto xinetd
[root@backup ~]# 

xinetd就好像是一个保姆进程,rsync是它照顾的进程

3.5、修改/etc/rsyncd.conf配置文件 (注意:[back_data]最好不要加注释,防止出错)

[root@backup ~]# >/etc/rsyncd.conf
[root@backup ~]# vim /etc/rsyncd.conf
[root@backup ~]# cat /etc/rsyncd.conf 
uid = root
gid = root
use chroot = yes
max connections = 0
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid 
lock file = /var/run/rsync.lock 
secrets file = /etc/rsync.pass   #认证文件
motd file = /etc/rsyncd.Motd
[back_data]    #配置项名称(自定义)path = /backup/     #数据源服务器,备份文件存储地址,存放备份文件comment = A directory in which data is storedignore errors = yesread only = nohosts allow = 192.168.2.150  #允许的ip地址(数据源服务器地址)
[root@backup ~]# 

3.6、创建用户认证文件

[root@backup ~]# vim /etc/rsyncd.pass
[root@backup ~]# cat /etc/rsyncd.pass
backup:123456    #设置 认证用户和密码,后面会用到
[root@backup ~]# 注意:不要添加注释

3.7、设置文件权限

[root@backup ~]# chmod 600 /etc/rsyncd.conf 
[root@backup ~]# chmod 600 /etc/rsyncd.pass

增强安全性,非root用户不可读配置文件和认证文件

3.8、启动rsync,查看对应的进程、端口 (看到进程,就说明rsync启动成功、xinetd监听873端口)

[root@backup ~]# /usr/bin/rsync --daemon --config=/etc/rsyncd.conf
[root@backup ~]# ps aux|grep rsyncd
root      13708  0.0  0.0 114852   572 ?        Ss   06:28   0:00 /usr/bin/rsync --daemon --config=/etc/rsyncd.conf
root      13710  0.0  0.0 112824   980 pts/1    R+   06:29   0:00 grep --color=auto rsyncd
[root@backup ~]# netstat -anplut|grep rsync
tcp        0      0 0.0.0.0:873             0.0.0.0:*               LISTEN      13708/rsync         
tcp6       0      0 :::873                  :::*                    LISTEN      13708/rsync         
[root@backup ~]# 

rsync - master数据源服务器操作

3.9、在master上安装rsync、xinetd软件

[root@master backup]# yum install -y rsync xinetd

3.10、启动xinetd,查看进程

[root@master backup]# systemctl start xinetd
[root@master backup]# ps aux|grep xinetd
root      24033  0.0  0.0  25044   588 ?        Ss   07:42   0:00 /usr/sbin/xinetd -stayalive -pidfile /var/run/xinetd.pid
root      24035  0.0  0.0 112824   984 pts/1    R+   07:42   0:00 grep --color=auto xinetd
[root@master backup]# 

3.11、修改/etc/rsyncd.conf配置文件(注意:[sync]段配置文件最好不要加注释,防止报错)

[root@master backup]# >/etc/rsyncd.conf 
[root@master backup]# cd ~
[root@master ~]# vim /etc/rsyncd.conf 
[root@master ~]# cat /etc/rsyncd.conf 
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
motd file = /etc/rsyncd.Motd
[Sync]comment = Syncuid = rootgid = rootport= 873
[root@master ~]# 

3.12、创建用户认证文件

[root@master ~]# vim /etc/passwd.txt
[root@master ~]# cat /etc/passwd.txt 
123456 #该密码应与备份服务器中的/etc/rsync.pass中的密码一致
[root@master ~]# 

3.13、设置文件权限,非root用户不可读认证文件

[root@master ~]# chmod 600 /etc/passwd.txt

3.14、测试数据同步

数据源服务器开启rysnc同步

[root@master ~]# rsync -avH --port=873 --progress --delete  /backup/ root@192.168.2.157::back_data  --password-file=/etc/passwd.txtsending incremental file list
./
all_db.sql887,244 100%   67.91MB/s    0:00:00 (xfr#1, to-chk=1/3)
backup_db.sh165 100%   13.43kB/s    0:00:00 (xfr#2, to-chk=0/3)sent 887,818 bytes  received 61 bytes  1,775,758.00 bytes/sec
total size is 887,409  speedup is 1.00
[root@master ~]# 

–port 备份服务器端rsync端口

/backup/ 数据源服务器上要备份的数据

root:192.168.2.157 备份服务器的用户和ip地址

如果有报错,建议查看日志文件/var/log/rysncd.conf

3.15、数据源服务器增加文件或者删除文件,看备份服务器/backup/是否有变化

数据源服务器新建文件夹,并上传同步文件

[root@master ~]# cd /backup/
[root@master backup]# ls
all_db.sql  backup_db.sh
[root@master backup]# touch test1.txt
[root@master backup]# ls
all_db.sql  backup_db.sh  test1.txt
# 使用rsync同步上传文件
[root@master backup]# rsync -avH --port=873 --progress --delete  /backup/ root@192.168.2.157::back_data  --password-file=/etc/passwd.txtsending incremental file list
./
test1.txt0 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=0/4)sent 174 bytes  received 42 bytes  432.00 bytes/sec
total size is 887,409  speedup is 4,108.38
[root@master backup]# 

查看备份服务器/backup/的效果:

[root@backup ~]# cd /backup/
[root@backup backup]# ls    #没有同步之前
all_db.sql  backup_db.sh
[root@backup backup]# ls    #同步之后
all_db.sql  backup_db.sh  test1.txt
[root@backup backup]# 

4、安装sersync工具,inotify实时触发rsync进行同步–数据源服务器操作

4.1、修改inotify默认参数(inotify默认内核参数过小),修改参数(inotify在内核里已经安装了,只需要传参)

[root@master backup]# cd ~
[root@master ~]# sysctl -w fs.inotify.max_queued_events="99999999"
fs.inotify.max_queued_events = 99999999
[root@master ~]# sysctl -w fs.inotify.max_user_watches="99999999"
fs.inotify.max_user_watches = 99999999
[root@master ~]# sysctl -w fs.inotify.max_user_instances="65535"
fs.inotify.max_user_instances = 65535
[root@master ~]# 

4.2、设置永久生效

[root@master ~]# vim /etc/sysctl.conf 
fs.inotify.max_queued_events=99999999
fs.inotify.max_user_watches=99999999
fs.inotify.max_user_instances=65535

4.3、装sersync软件包

[root@master ~]# wget  http://down.whsir.com/downloads/sersync2.5.4_64bit_binary_stable_final.tar.gz

4.4、解压sersync软件

[root@master ~]# tar xf sersync2.5.4_64bit_binary_stable_final.tar.gz

4.5、创建sersync

[root@master ~]# mv GNU-Linux-x86/ /usr/local/sersync
[root@master ~]# cd /usr/local/sersync/
[root@master sersync]# ls
confxml.xml  sersync2
[root@master sersync]# cp confxml.xml confxml.xml.bak    #备份,防止后续出错
[root@master sersync]# cp confxml.xml data_configxml.xm  #增加数据配置
[root@master sersync]# ls
confxml.xml  confxml.xml.bak  data_configxml.xm  sersync2
[root@master sersync]# 

4.6、修改配置 data_configxml.xml

[root@master sersync]# vim data_configxml.xm #第24行位置<sersync><localpath watch="/backup/"> #本地要备份的数据文件<remote ip="192.168.31.210" name="back_data"/> #备份服务器的ip地址以配置文件里的配置项<!--<remote ip="192.168.8.39" name="tongbu"/>--><!--<remote ip="192.168.8.40" name="tongbu"/>--></localpath><rsync><commonParams params="-artuz"/><auth start="false" users="root" passwordfile="/etc/passwd.txt"/> #认证用户和密码所在的路径<userDefinedPort start="false" port="874"/><!-- port=874 --><timeout start="false" time="100"/><!-- timeout=100 --><ssh start="false"/>

4.7、加入PATH环境变量,并设置开机永久生效 

[root@master sersync]# PATH=/usr/local/sersync/:$PATH
[root@master sersync]# which sersync2
/usr/local/sersync/sersync2
[root@master sersync]# echo "PATH=/usr/local/sersync/:$PATH" >>/root/.bashrc
[root@master sersync]# 

4.8、启动sersync(启动成功如下)

[root@master sersync]# sersync2 -d -r -o /usr/local/sersync/data_configxml.xm
set the system param
execute:echo 50000000 > /proc/sys/fs/inotify/max_user_watches
execute:echo 327679 > /proc/sys/fs/inotify/max_queued_events
parse the command param
option: -d 	run as a daemon
option: -r 	rsync all the local files to the remote servers before the sersync work
option: -o 	config xml name:  /usr/local/sersync/data_configxml.xm
daemon thread num: 10
parse xml config file
host ip : localhost	host port: 8008
daemon start,sersync run behind the console 
config xml parse success
please set /etc/rsyncd.conf max connections=0 Manually
sersync working thread 12  = 1(primary thread) + 1(fail retry thread) + 10(daemon sub threads) 
Max threads numbers is: 22 = 12(Thread pool nums) + 10(Sub threads)
please according your cpu ,use -n param to adjust the cpu rate
------------------------------------------
rsync the directory recursivly to the remote servers once
working please wait...
execute command: cd /backup && rsync -artuz -R --delete ./ 192.168.2.157::back_data >/dev/null 2>&1 
run the sersync: 
watch path is: /backup
[root@master sersync]# 

4.9、查看sersync进程

[root@master sersync]# ps aux|grep sersync
root      24100  0.0  0.0  92324   716 ?        Ssl  08:06   0:00 sersync2 -d -r -o /usr/local/sersync/data_configxml.xm
root      24116  0.0  0.0 112824   984 pts/1    R+   08:07   0:00 grep --color=auto sersync
[root@master sersync]# 

4.10、设置sersync监控开机自动执行

[root@master sersync]# vim /etc/rc.d/rc.local
[root@master sersync]# cat /etc/rc.d/rc.local /usr/local/sersync/sersync2 -d -r -o  /usr/local/sersync/data_configxml.xm[root@master sersync]# 

4.11、效果测试

数据源服务器新建文件夹

[root@master sersync]# cd /backup/
[root@master backup]# touch test2.txt
[root@master backup]# ls
all_db.sql  backup_db.sh  test1.txt  test2.txt
[root@master backup]# 

backup备份服务器发现了实时同步的新建文件夹

[root@backup backup]# ls
all_db.sql  backup_db.sh  test1.txt
[root@backup backup]# ls
all_db.sql  backup_db.sh  test1.txt  test2.txt
[root@backup backup]# 

测试成功!rsync+sersync实时数据同步搭建成功!

五、Ansible批量部署mha软件环境,搭建MHA高可用架构,实现自动failover,完成主从切换

参考:Mysql 搭建MHA高可用架构,实现自动failover,完成主从切换_Claylpf的博客-CSDN博客

1、编写主机清单,增添4个mha node节点ip地址,以及一个mha manager节点ip地址

[root@ansible ansible]# vim /etc/ansible/hosts
[root@ansible ansible]# cat /etc/ansible/hosts 
[mha_manager]
192.168.2.141  #mha manager
[mha_node]
192.168.2.141  #mha manager
192.168.2.150  #master 
192.168.2.151  #slave1
192.168.2.152  #slave2
[root@ansible ansible]# 

2、编写一键安装mha node脚本和一键安装mha mangaer脚本

mha node脚本

[root@ansible ~]# cat onekey_install_mha_node.sh 
#查看可以安装或者已安装的rpm包,并且作缓存
yum list
#下载epel源
yum install epel-release --nogpgcheck -y
#下载依赖包
yum install -y perl-DBD-MySQL \
perl-Config-Tiny \
perl-Log-Dispatch \
perl-Parallel-ForkManager \
perl-ExtUtils-CBuilder \
perl-ExtUtils-MakeMaker \
perl-CPAN
#软件包mha4mysql-node-0.58.tar.gz放入/root目录下
cd ~
tar zxvf mha4mysql-node-0.58.tar.gz
cd mha4mysql-node-0.58
#编译安装
perl Makefile.PL
make && make install

mha manager脚本(因为在安装mha node时已经安装好了所有的依赖包,就可以直接进行解压编译安装了)

[root@ansible ~]# cat onekey_install_mha_manager.sh 
#软件包mha4mysql-manager-0.58.tar.gz放入/root目录下
cd ~
tar zxvf mha4mysql-manager-0.58.tar.gz
cd mha4mysql-manager-0.58
#编译安装
perl Makefile.PL
make && make install

3、编写playbook,上传源码包到家目录下,调用本地脚本,远程安装部署mha相关软件环境

[root@ansible ansible]# vim mha_install.yaml
[root@ansible ansible]# cat mha_install.yaml 
- hosts: mha_noderemote_user: roottasks: - name: copy filecopy: src=/root/mha4mysql-node-0.58.tar.gz dest=/root/- name: install mha_nodescript: /root/onekey_install_mha_node.sh
- hosts: mha_managerremote_user: roottasks:- name: copy filecopy: src=/root/mha4mysql-manager-0.58.tar.gz dest=/root/- name: install mha_managerscript: /root/onekey_install_mha_manager.sh 
[root@ansible ansible]# 

4、执行playbook

[root@ansible ansible]# ansible-playbook mha_install.yaml 

5、所有服务器互相建立免密通道

参考:Linux - SSH服务 - SCP - 免密通道建立_linux ssh服务状态_Claylpf的博客-CSDN博客

5.1、mha manager对所有mysql服务器建立免密通道

[root@mha_manager .ssh]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
/root/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:36631NGvhLwX3HXPFgkfo8t/C0g+k59hqkGi1cn0/cA root@mha_manager
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|             . o |
|         .    + +|
|        + o o. =o|
|       oS= o.Eoo*|
|      o o.ooo==.*|
|     .   ..*=+++.|
|          .oBo=o.|
|         .o++=..o|
+----[SHA256]-----+
[root@mha_manager .ssh]# ssh-copy-id root@192.168.2.150
/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.2.150's password: Number of key(s) added: 1Now try logging into the machine, with:   "ssh 'root@192.168.2.150'"
and check to make sure that only the key(s) you wanted were added.[root@mha_manager .ssh]# [root@mha_manager .ssh]# ssh-copy-id root@192.168.2.151[root@mha_manager .ssh]# ssh-copy-id root@192.168.2.152

5.2、master对slave1、slave2建立免密通道

[root@mysql-1 ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:rB6Rg0nbJCHYxWxuBafl4HDB8+1RuuOpHC9/5LYRTAI root@mysql-1
The key's randomart image is:
+---[RSA 2048]----+
| oo=BoE          |
|. .=*B..  .      |
|   o=+o..o.      |
|   .oB.o++       |
|   .+ =.Soo      |
|       ++ ..     |
|      +. =.      |
|     o.+o +.     |
|      ++oo..     |
+----[SHA256]-----+
[root@mysql-1 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.151
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.2.151's password: Number of key(s) added: 1Now try logging into the machine, with:   "ssh '192.168.2.151'"
and check to make sure that only the key(s) you wanted were added.[root@mysql-1 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.152
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.2.152's password: Number of key(s) added: 1Now try logging into the machine, with:   "ssh '192.168.2.152'"
and check to make sure that only the key(s) you wanted were added.[root@mysql-1 ~]# 

5.3、slave1对master、slave2建立免密通道

[root@mysql-2 ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:MMCE8STghhwmha65CVG/w3/9k8/T96sFfcr75CFMTGs root@mysql-2
The key's randomart image is:
+---[RSA 2048]----+
|o*+=+            |
|B ++..           |
|o= .. o      .   |
|o.  .  o    o o  |
|.o . .  S    E ..|
|+   +       +....|
|.o   o   .   +o+.|
|o     . . . o.+++|
|       .   ..+=+B|
+----[SHA256]-----+
[root@mysql-2 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.150
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.2.150 (192.168.2.150)' can't be established.
ECDSA key fingerprint is SHA256:rUDllK9IdVfMva40nDGHGyHLkpuXrHJyRHRPuLbkkv8.
ECDSA key fingerprint is MD5:6d:46:aa:d1:48:87:92:8b:14:ca:d2:18:af:3b:89:51.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.2.150's password: Number of key(s) added: 1Now try logging into the machine, with:   "ssh '192.168.2.150'"
and check to make sure that only the key(s) you wanted were added.[root@mysql-2 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.152
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.2.152 (192.168.2.152)' can't be established.
ECDSA key fingerprint is SHA256:t7FSFcUpEOJYIGkZo1HvvfqhsezGEz7WEScc4KTgQDU.
ECDSA key fingerprint is MD5:7c:68:1c:c3:aa:a5:34:b7:f7:4b:18:0b:93:fb:a6:76.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.2.152's password: 
Permission denied, please try again.
root@192.168.2.152's password: Number of key(s) added: 1Now try logging into the machine, with:   "ssh '192.168.2.152'"
and check to make sure that only the key(s) you wanted were added.[root@mysql-2 ~]# 

 5.4、slave2对master、slave1建立免密通道

[root@mysql-3 ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:m6F9WyLFkNnweKy2ERj3LflPDHqU5ZUL+S8FpCbXhtw root@mysql-3
The key's randomart image is:
+---[RSA 2048]----+
|      . o    .+ o|
|       + X + @.o |
|      . * X @ E..|
|         * O + o.|
|        S + o o..|
|       + B . o. .|
|      . * o . .. |
|         o +     |
|          .      |
+----[SHA256]-----+
[root@mysql-3 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.150
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.2.150 (192.168.2.150)' can't be established.
ECDSA key fingerprint is SHA256:rUDllK9IdVfMva40nDGHGyHLkpuXrHJyRHRPuLbkkv8.
ECDSA key fingerprint is MD5:6d:46:aa:d1:48:87:92:8b:14:ca:d2:18:af:3b:89:51.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.2.150's password: Number of key(s) added: 1Now try logging into the machine, with:   "ssh '192.168.2.150'"
and check to make sure that only the key(s) you wanted were added.[root@mysql-3 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.151
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.2.151 (192.168.2.151)' can't be established.
ECDSA key fingerprint is SHA256:3SsW//YjcK0UTRAlQkOUcqMcFMaQEhZ1xRSUgHRs/JQ.
ECDSA key fingerprint is MD5:58:8e:3f:27:fb:f5:4e:83:56:70:e6:fd:f7:d0:9d:17.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.2.151's password: Number of key(s) added: 1Now try logging into the machine, with:   "ssh '192.168.2.151'"
and check to make sure that only the key(s) you wanted were added.[root@mysql-3 ~]# 

6、在搭建好的主从复制服务器里,配置mha相关信息

6.1、所有mysql服务器加入log_bin和log-slave-updates,并刷新配置文件

master:

root@master ~]# cat /etc/my.cnf
[mysqld_safe][client]
socket=/data/mysql/mysql.sock[mysqld]
socket=/data/mysql/mysql.sock
log-error=/data/mysql/mysql_error.log     #表示设置Mysql的error日志的路径
slow_query_log = 1      #表示开启Mysql慢日志
long_query_time = 0.001  #表示设置慢日志的阈值为0.001毫秒
general_log            #我们不需要添加路径了,因为Mysql会自动帮助我们添加通用日志的路径和日志文件,表示打开了通用日志
log_bin                #表示我们开启了二进制日志
server_id = 1          #给我们的Mysql服务器进行编号
expire_logs_days = 7   #表示二进制日志文件过 7天 自动清除
log-slave-updates      #主从切换时,主从服务器身份都可能对换,从服务器重演relay_log日志操作时,也写入自己的log_bin中port = 3306
open_files_limit = 8192
innodb_buffer_pool_size = 512M
character-set-server=utf8[mysql]
auto-rehash
prompt=\u@\d \R:\m  mysql>
[root@master ~]# service mysqld restart
Shutting down MySQL............. SUCCESS! 
Starting MySQL.. SUCCESS! 
[root@master ~]# 

slave:

[root@slave1 ~]# vim /etc/my.cnf
[root@slave1 ~]# cat /etc/my.cnf
[mysqld_safe][client]
socket=/data/mysql/mysql.sock[mysqld]
socket=/data/mysql/mysql.sock
log-error=/data/mysql/mysql_error.log     #表示设置Mysql的error日志的路径
slow_query_log = 1      #表示开启Mysql慢日志
long_query_time = 0.001  #表示设置慢日志的阈值为0.001毫秒
general_log            #我们不需要添加路径了,因为Mysql会自动帮助我们添加通用日志的路径和日志文件,表示打开了通用日志
log_bin                #表示我们开启了二进制日志
server_id = 2          #给我们的Mysql服务器进行编号
expire_logs_days = 7   #表示二进制日志文件过 7天 自动清除
log-slave-updates      #主从切换时,主从服务器身份都可能对换,从服务器重演relay_log日志操作时,也写入自己的log_bin中port = 3306
open_files_limit = 8192
innodb_buffer_pool_size = 512M
character-set-server=utf8[mysql]
auto-rehash
prompt=\u@\d \R:\m  mysql>
[root@slave1 ~]# service mysqld restart
Shutting down MySQL.... SUCCESS! 
Starting MySQL.. SUCCESS! 
[root@slave1 ~]# 

6.2、所有mysql服务器(master、slave1、slave2)将mysql命令和mysqlbinlog命令软链接到/usr/sbin,方便manager管理节点

[root@master ~]# ln -s /usr/local/mysql/bin/mysql /usr/sbin/
[root@master ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/[root@salve1 ~]# ln -s /usr/local/mysql/bin/mysql /usr/sbin/
[root@salve1 ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/[root@salve2 ~]# ln -s /usr/local/mysql/bin/mysql /usr/sbin/
[root@salve2 ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/

6.3、所有mysql服务器新建允许manager访问的授权用户mha,密码123456

root@(none) 08:38  mysql>grant all on *.* to 'mha'@'192.168.2.%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.01 sec)root@(none) 08:39  mysql>grant all on *.* to 'mha'@'192.168.2.150' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)root@(none) 08:39  mysql>grant all on *.* to 'mha'@'192.168.2.151' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)root@(none) 08:39  mysql>grant all on *.* to 'mha'@'192.168.2.152' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)root@(none) 08:40  mysql>select user,host from mysql.user;
+---------------+---------------+
| user          | host          |
+---------------+---------------+
| sc_slave      | %             |
| mha           | 192.168.2.%   |
| mha           | 192.168.2.150 |
| mha           | 192.168.2.151 |
| mha           | 192.168.2.152 |
| mysql.session | localhost     |
| mysql.sys     | localhost     |
| root          | localhost     |
+---------------+---------------+
8 rows in set (0.00 sec)root@(none) 08:40  mysql>

7、在mha manager节点上配置好相关脚本、管理节点服务器

7.1、mha manager节点上复制相关脚本到/usr/local/bin下

[root@mha_manager ~]# cp -rp /root/mha4mysql-manager-0.58/samples/scripts/ /usr/local/bin/
#-r 复制目录
#-p 同时复制文件访问权限
[root@mha_manager ~]# cd /usr/local/bin/
[root@mha_manager bin]# ls
scripts
[root@mha_manager bin]# 
[root@mha_manager bin]# cd scripts/
[root@mha_manager scripts]# ls
master_ip_failover  master_ip_online_change  power_manager  send_report
[root@mha_manager scripts]# 

7.2、复制自动切换时vip管理的脚本到/usr/local/bin下

[root@mha_manager scripts]#  cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin/
[root@mha_manager scripts]# cd ..
[root@mha_manager bin]# ls
master_ip_failover  scripts
[root@mha_manager bin]# 

7.3、修改master_ip_failover文件内容,配置vip(只配置vip相关参数,其他默认不修改)

[root@mha_manager bin]# >/usr/local/bin/master_ip_failover   # 清空文件
[root@mha_manager bin]# vim /usr/local/bin/master_ip_failover
[root@mha_manager bin]# cat /usr/local/bin/master_ip_failover 
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';use Getopt::Long;my (
$command, $ssh_user, $orig_master_host, $orig_master_ip,
$orig_master_port, $new_master_host, $new_master_ip, $new_master_port
);
#############################添加内容部分#########################################
my $vip = '192.168.2.227';								#指定vip的地址,自己指定
my $brdc = '192.168.2.255';								#指定vip的广播地址
my $ifdev = 'ens33';										#指定vip绑定的网卡
my $key = '1';												#指定vip绑定的虚拟网卡序列号
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";		#代表此变量值为ifconfig ens33:1 192.168.2.227
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";		#代表此变量值为ifconfig ens33:1 192.168.2.227 down
my $exit_code = 0;											#指定退出状态码为0
#my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;";
#my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";
##################################################################################
GetOptions(
'command=s' => \$command,
'ssh_user=s' => \$ssh_user,
'orig_master_host=s' => \$orig_master_host,
'orig_master_ip=s' => \$orig_master_ip,
'orig_master_port=i' => \$orig_master_port,
'new_master_host=s' => \$new_master_host,
'new_master_ip=s' => \$new_master_ip,
'new_master_port=i' => \$new_master_port,
);exit &main();sub main {print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";if ( $command eq "stop" || $command eq "stopssh" ) {my $exit_code = 1;
eval {
print "Disabling the VIP on old master: $orig_master_host \n";
&stop_vip();
$exit_code = 0;
};
if ($@) {
warn "Got Error: $@\n";
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "start" ) {my $exit_code = 10;
eval {
print "Enabling the VIP - $vip on the new master - $new_master_host \n";
&start_vip();
$exit_code = 0;
};
if ($@) {
warn $@;
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "status" ) {
print "Checking the Status of the script.. OK \n";
exit 0;
}
else {
&usage();
exit 1;
}
}
sub start_vip() {
`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
## A simple system call that disable the VIP on the old_master
sub stop_vip() {
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}
[root@mha_manager bin]# 

7.4、创建 MHA 软件目录并复制配置文件,使用app1.cnf配置文件来管理 mysql 节点服务器,配置文件一般放在/etc/目录下(注意:注释只是提示用,编辑配置文件时最好不要加注释,否则很可能会出错)

[root@mha_manager masterha]# >app1.cnf 
[root@mha_manager masterha]# vim app1.cnf
[root@mha_manager masterha]# cat app1.cnf 
[server default]
manager_log=/var/log/masterha/app1/manager.log       #manager日志
manager_workdir=/var/log/masterha/app1.log    		#manager工作目录
master_binlog_dir=/data/mysql/          #master保存binlog的位置,这里的路径要与master里配置的binlog的路径一致,以便MHA能找到
master_ip_failover_script=/usr/local/bin/master_ip_failover            #设置自动failover时候的切换脚本,也就是上面的那个脚本
master_ip_online_change_script=/usr/local/bin/master_ip_online_change  #设置手动切换时候的切换脚本
user=mha					#设置监控用户mha
password=123456			#设置mysql中mha用户的密码,这个密码是前文中创建监控用户的那个密码
ping_interval=1				#设置监控主库,发送ping包的时间间隔1秒,默认是3秒,尝试三次没有回应的时候自动进行failover
remote_workdir=/tmp			#设置远端mysql在发生切换时binlog的保存位置
repl_user=slave			#设置复制用户的用户slave
repl_password=123456		#设置复制用户slave的密码
report_script=/usr/local/send_report     #设置发生切换后发送的报警的脚本
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.2.151 -s 192.168.2.152	#指定检查的从服务器IP地址
shutdown_script=""			#设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机防止发生脑裂,这里没有使用)
ssh_user=root				#设置ssh的登录用户名[server1]
#master
hostname=192.168.2.150
port=3306[server2]
#slave1
hostname=192.168.2.151
port=3306
candidate_master=1
#设置为候选master,设置该参数以后,发生主从切换以后将会将此从库提升为主库,即使这个主库不是集群中最新的slavecheck_repl_delay=0
#默认情况下如果一个slave落后master 超过100M的relay logs的话,MHA将不会选择该slave作为一个新的master, 因为对于这个slave的恢复需要花费很长时间;通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master[server3]
#slave2
hostname=192.168.2.152
port=3306
[root@mha_manager masterha]# 

8、master服务器上手工开启vip

[root@master ~]# ifconfig ens33:1 192.168.2.227/24
[root@master ~]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000link/ether 00:0c:29:61:50:77 brd ff:ff:ff:ff:ff:ffinet 192.168.2.150/24 brd 192.168.2.255 scope global noprefixroute ens33valid_lft forever preferred_lft foreverinet 192.168.2.227/24 brd 192.168.2.255 scope global secondary ens33:1valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fe61:5077/64 scope link valid_lft forever preferred_lft forever
[root@mysql-1 ~]# 

9、manager节点上测试ssh免密通道,如果正常最后会输出successfully(注意是否每台mysql间都建立了ssh免密通道,否则会报错)

[root@mha_manager masterha]# masterha_check_ssh -conf=/etc/masterha/app1.cnf
Mon Aug 14 07:00:46 2023 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Mon Aug 14 07:00:46 2023 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Mon Aug 14 07:00:46 2023 - [info] Reading server configuration from /etc/masterha/app1.cnf..
Mon Aug 14 07:00:46 2023 - [info] Starting SSH connection tests..
Mon Aug 14 07:00:48 2023 - [debug] 
Mon Aug 14 07:00:46 2023 - [debug]  Connecting via SSH from root@192.168.2.150(192.168.2.150:22) to root@192.168.2.151(192.168.2.151:22)..
Mon Aug 14 07:00:47 2023 - [debug]   ok.
Mon Aug 14 07:00:47 2023 - [debug]  Connecting via SSH from root@192.168.2.150(192.168.2.150:22) to root@192.168.2.152(192.168.2.152:22)..
Mon Aug 14 07:00:48 2023 - [debug]   ok.
Mon Aug 14 07:00:49 2023 - [debug] 
Mon Aug 14 07:00:46 2023 - [debug]  Connecting via SSH from root@192.168.2.151(192.168.2.151:22) to root@192.168.2.150(192.168.2.150:22)..
Mon Aug 14 07:00:48 2023 - [debug]   ok.
Mon Aug 14 07:00:48 2023 - [debug]  Connecting via SSH from root@192.168.2.151(192.168.2.151:22) to root@192.168.2.152(192.168.2.152:22)..
Mon Aug 14 07:00:49 2023 - [debug]   ok.
Mon Aug 14 07:00:49 2023 - [debug] 
Mon Aug 14 07:00:47 2023 - [debug]  Connecting via SSH from root@192.168.2.152(192.168.2.152:22) to root@192.168.2.150(192.168.2.150:22)..
Mon Aug 14 07:00:48 2023 - [debug]   ok.
Mon Aug 14 07:00:48 2023 - [debug]  Connecting via SSH from root@192.168.2.152(192.168.2.152:22) to root@192.168.2.151(192.168.2.151:22)..
Mon Aug 14 07:00:49 2023 - [debug]   ok.
Mon Aug 14 07:00:49 2023 - [info] All SSH connection tests passed successfully.
[root@mha_manager masterha]# 

10、在 manager 节点上测试 mysql 主从连接情况,最后出现 MySQL Replication Health is OK 字样说明正常(如果报错,思考是否软链接建立好了?或者主从复制搭建正确了)

[root@mha_manager masterha]# masterha_check_repl -conf=/etc/masterha/app1.cnf
MySQL Replication Health is OK.

11、manager节点后台开启MHA

[root@mha_manager masterha]# nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &
[1] 17621

11.1、查看 MHA 状态,可以看到当前的 master 是 Mysql1 节点

[root@mha_manager masterha]# masterha_check_status --conf=/etc/masterha/app1.cnf
app1 (pid:17621) is running(0:PING_OK), master:192.168.2.150

11.2、查看MHA日志,看到当前matser是192.168.2.150

[root@mha_manager masterha]# cat /var/log/masterha/app1/manager.log | grep "current master"
Mon May  8 11:57:07 2023 - [info] Checking SSH publickey authentication settings on the current master..
192.168.2.150(192.168.2.150:3306) (current master)

11.3、查看mha进程

[root@mha_manager bin]# ps aux|grep manager
root      17624  0.1  4.5 299656 21992 pts/0    S    11:57   0:12 perl /usr/local/bin/masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover
root      17826  0.0  0.0 112824   984 pts/2    R+   07:22   0:00 grep --color=auto manager

六、搭建mysqlrouter-keepalived集群,实现高可用 - 读写分离功能,减轻主节点的压力

参考:Mysql - 配置Mysql主从复制-keepalived高可用-读写分离集群_Claylpf的博客-CSDN博客

Mysql - 读写分离_mysql读写分离的工具_Claylpf的博客-CSDN博客 

有两台mysqlrouter服务器,由于篇幅有限,我就只展示了一台,另外一台操作基本一致的

1、下载安装Mysql-router:MySQL :: Download MySQL Router

[root@mysqlrouter-1 ~]# ls
anaconda-ks.cfg  mysql-router-community-8.0.34-1.el7.x86_64.rpm
[root@mysqlrouter-1 ~]# 

注:下载安装的mysqlrouter的时候必须注意版本,否则解压安装的时候会报错

2、安装Mysql-router并解压:

3、修改mysqlrouter配置文件:(mysqlrouter必须绑定到keepalived设定的vip上或者使用任意地址0.0.0.0上(切记不能添加注释,我添加是为了方便解释,否则会报错)

[root@mysqlrouter-1 mysqlrouter]# cat mysqlrouter.conf 
# Copyright (c) 2015, 2023, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2.0,
# as published by the Free Software Foundation.
#
# This program is also distributed with certain software (including
# but not limited to OpenSSL) that is licensed under separate terms,
# as designated in a particular file or component or in included license
# documentation.  The authors of MySQL hereby grant you an additional
# permission to link the program and your derivative works with the
# separately licensed software that they have included with MySQL.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA#
# MySQL Router configuration file
#
# Documentation is available at
#    http://dev.mysql.com/doc/mysql-router/en/[DEFAULT]
logging_folder = /var/log/mysqlrouter
runtime_folder = /run/mysqlrouter
config_folder = /etc/mysqlrouter[logger]
level = INFO# If no plugin is configured which starts a service, keepalive
# will make sure MySQL Router will not immediately exit. It is
# safe to remove once Router is configured.
[keepalive]
interval = 60[routing:read_write]
bind_address = 192.168.2.221  #vip地址  虚拟IP地址,可以在keepalived配置之前确定 当然我们可以使用0.0.0.0(任意IP地址),那么不管是vip还是本机的ip地址所对应的7001端口都能访问到     
bind_port= 7001               #自己的端口号      
destinations = 192.168.2.150:3306   #设置目的机器IP地址,可以填master的IP,端口为mysqld运行的端口    
mode = read-write             #设置目的机器IP地址,可以填master的IP,端口为mysqld运行的端口        
max_connections = 65535
max_connect_errors = 100
client_connect_timeout = 9[routing:read_only_1]
bind_address = 192.168.2.221        
bind_port= 7002                     
destinations = 192.168.2.151:3306   #设置目的机器IP地址,可以填master的IP,端口为mysqld运行的端口
mode = read-only                    
max_connections = 65535
max_connect_errors = 100
client_connect_timeout = 9[routing:read_only_2]
bind_address = 192.168.2.221        
bind_port= 7003                     
destinations = 192.168.2.152:3306   #设置目的机器IP地址,可以填master的IP,端口为mysqld运行的端口
mode = read-only                    
max_connections = 65535
max_connect_errors = 100
client_connect_timeout = 9
[root@mysqlrouter-1 mysqlrouter]# 

4、刷新mysqlrouter服务,并查看端口:

[root@mysqlrouter-1 mysqlrouter]# service mysqlrouter restart
Redirecting to /bin/systemctl restart mysqlrouter.service
[root@mysqlrouter-1 mysqlrouter]# [root@mysqlrouter-1 mysqlrouter]# netstat -anpult |grep mysqlrouter
tcp        0      0 192.168.2.221:7001      0.0.0.0:*               LISTEN      42847/mysqlrouter   
tcp        0      0 192.168.2.221:7002      0.0.0.0:*               LISTEN      42847/mysqlrouter   
tcp        0      0 192.168.2.221:7003      0.0.0.0:*               LISTEN      42847/mysqlrouter   
[root@mysqlrouter-1 mysqlrouter]# 

5、安装配置keepalived服务

下载keepalived服务:

[root@mysqlrouter-1 mysqlrouter]# yum install keepalived -y
已安装:keepalived.x86_64 0:1.3.5-19.el7                                                                                                                                                           作为依赖被安装:lm_sensors-libs.x86_64 0:3.4.0-8.20160601gitf9185e5.el7                net-snmp-agent-libs.x86_64 1:5.7.2-49.el7_9.2                net-snmp-libs.x86_64 1:5.7.2-49.el7_9.2               完毕!

6、修改keepalived的配置文件(从36行以下的全部都不需要)(配置单vip的高可用服务)

6.1、master上的配置

global_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.200.1smtp_connect_timeout 30router_id LVS_DEVELvrrp_skip_check_adv_addr
#   vrrp_strict       # 这一行需要注释:原因是因为会在iptables里添加一条规则,会阻止网络通信,导致出现脑裂现象vrrp_garp_interval 0vrrp_gna_interval 0
}vrrp_instance VI_1 {    # 定义一个vrrp协议的实例 名字是VI_1 表示第一个vrrp实例state MASTER        # 做master角色interface ens33     # 指定监听网络的接口,其实就是vip绑定到那个网络接口上virtual_router_id 81  # 虚拟路由器ID 81表示的是编号,另外一台机器上的配置也必须是81priority 160          # 优先级 数字越大就越容易成为masteradvert_int 1          # 宣告消息的时间间隔 为1sauthentication {auth_type PASS    # 密码认证 passwordauth_pass 1111    # 具体密码 可以不用修改}virtual_ipaddress {   # vip 虚拟ip地址 可以配置多个192.168.2.221     # 配置的vip#192.168.200.17#192.168.200.18}
}

6.2、backup上的配置

[root@mysqlrouter-2 keepalived]# cat keepalived.conf 
global_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.200.1smtp_connect_timeout 30router_id LVS_DEVELvrrp_skip_check_adv_addr# vrrp_strict       # 这一行需要注释:原因是因为会在iptables里添加一条规则,会阻止网络通信,导致出现脑裂现象vrrp_garp_interval 0vrrp_gna_interval 0
}vrrp_instance VI_1 {    # 定义一个vrrp协议的实例 名字是VI_1 表示第一个vrrp实例state BACKUP        # 做backup角色interface ens33     # 指定监听网络的接口,其实就是vip绑定到那个网络接口上virtual_router_id 81  # 虚拟路由器ID 81表示的是编号,另外一台机器上的配置也必须是81priority 100          # 优先级 数字越大就越容易成为masteradvert_int 1          # 宣告消息的时间间隔 为1sauthentication {auth_type PASS    # 密码认证 passwordauth_pass 1111    # 具体密码 可以不用修改}virtual_ipaddress {   # vip 虚拟ip地址 可以配置多个192.168.2.221     # 配置的vip 必须与master配置的vip是一样的#192.168.200.17#192.168.200.18}
}
[root@mysqlrouter-2 keepalived]# 

7、重新启动keepalived服务

[root@mysqlrouter-1 keepalived]# service keepalived restart
Redirecting to /bin/systemctl restart keepalived.service
[root@mysqlrouter-1 keepalived]# 

7.1、查看效果:

[root@mysqlrouter-1 keepalived]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000link/ether 00:0c:29:90:87:dc brd ff:ff:ff:ff:ff:ffinet 192.168.2.181/24 brd 192.168.2.255 scope global noprefixroute ens33valid_lft forever preferred_lft foreverinet 192.168.2.221/32 scope global ens33valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fe90:87dc/64 scope link valid_lft forever preferred_lft forever
[root@mysqlrouter-1 keepalived]# 

8、模拟测试:如果master挂掉了,那么vip是否会转移到backup上去呢?

8.1、我们将master上的keepalived关闭,查看backup上的ip地址

[root@mysqlrouter-1 keepalived]# service keepalived stop
Redirecting to /bin/systemctl stop keepalived.service
[root@mysqlrouter-1 keepalived]# 

8.2、backup上的IP地址

[root@mysqlrouter-2 keepalived]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000link/ether 00:0c:29:a9:7f:87 brd ff:ff:ff:ff:ff:ffinet 192.168.2.182/24 brd 192.168.2.255 scope global noprefixroute ens33valid_lft forever preferred_lft foreverinet 192.168.2.221/32 scope global ens33valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fea9:7f87/64 scope link valid_lft forever preferred_lft forever
[root@mysqlrouter-2 keepalived]# 

成功观察到我们想要的效果,vip真的漂移到了backup上了

8.3、当我们重启master,vip又会从backup上漂移到master上去的

[root@mysqlrouter-1 keepalived]# service keepalived start
Redirecting to /bin/systemctl start keepalived.service
[root@mysqlrouter-1 keepalived]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000link/ether 00:0c:29:90:87:dc brd ff:ff:ff:ff:ff:ffinet 192.168.2.181/24 brd 192.168.2.255 scope global noprefixroute ens33valid_lft forever preferred_lft foreverinet 192.168.2.221/32 scope global ens33valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fe90:87dc/64 scope link valid_lft forever preferred_lft forever
[root@mysqlrouter-1 keepalived]# 

9、外部连接测试keepalived实现的高可用效果:

当我通过Linux上访问192.168.2.221:7001端口的时候,他会访问到我们的master机器的3306端口上去(Mysql数据库的默认端口是3306)

[root@mysql-2 ~]#  mysql -h 192.168.2.221 -P 7001 -u claylpf -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 21
Server version: 5.7.41-log MySQL Community Server (GPL)Copyright (c) 2000, 2023, 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.claylpf@(none) 18:54  mysql>exit
Bye
[root@test ~]# [root@mysql-2 ~]#  mysql -h 192.168.2.221 -P 7002 -u claylpf -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 20
Server version: 5.7.41 MySQL Community Server (GPL)Copyright (c) 2000, 2023, 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.claylpf@(none) 19:15  mysql>

10、配置双vip实现keepalived配置(跟MySQL的主主复制十分相似)

双 VIP 可以用于实现高可用性架构。在一个服务器出现故障时,流量可以被自动切换到另一个服务器,从而保持服务的连续性。这在负载均衡、高可用的网络应用中特别有用。

10.1、master配置文件:

[root@mysqlrouter-1 keepalived]# cat keepalived.conf 
global_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.200.1smtp_connect_timeout 30router_id LVS_DEVELvrrp_skip_check_adv_addr# vrrp_strict       vrrp_garp_interval 0vrrp_gna_interval 0
}vrrp_instance VI_1 {    state MASTER        interface ens33     virtual_router_id 81  priority 160          advert_int 1          authentication {auth_type PASS    auth_pass 1111   }virtual_ipaddress {   192.168.2.221     }
}vrrp_instance VI_2 {    state BACKUP        interface ens33     virtual_router_id 101  priority 100          advert_int 1          authentication {auth_type PASS    auth_pass 1111   }virtual_ipaddress {   192.168.2.201     }
}
[root@mysqlrouter-1 keepalived]# 

10.2、backup配置文件:

[root@mysqlrouter-2 keepalived]# cat keepalived.conf 
global_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.200.1smtp_connect_timeout 30router_id LVS_DEVELvrrp_skip_check_adv_addr# vrrp_strict       # 这一行需要注释:原因是因为会在iptables里添加一条规则,会阻止网络通信,导致出现脑裂现象vrrp_garp_interval 0vrrp_gna_interval 0
}vrrp_instance VI_1 {    # 定义一个vrrp协议的实例 名字是VI_1 表示第一个vrrp实例state BACKUP        # 做backup角色interface ens33     # 指定监听网络的接口,其实就是vip绑定到那个网络接口上virtual_router_id 81  # 虚拟路由器ID 81表示的是编号,另外一台机器上的配置也必须是51priority 100          # 优先级 数字越大就越容易成为masteradvert_int 1          # 宣告消息的时间间隔 为1sauthentication {auth_type PASS    # 密码认证 passwordauth_pass 1111    # 具体密码 可以不用修改}virtual_ipaddress {   # vip 虚拟ip地址 可以配置多个192.168.2.221     # 配置的vip 必须与master配置的vip是一样的}
}vrrp_instance VI_2 {    # 定义一个vrrp协议的实例 名字是VI_1 表示第一个vrrp实例state MASTER        # 做backup角色interface ens33     # 指定监听网络的接口,其实就是vip绑定到那个网络接口上virtual_router_id 101  # 虚拟路由器ID 101表示的是编号,另外一台机器上的配置也必须是101priority 120          # 优先级 数字越大就越容易成为masteradvert_int 1          # 宣告消息的时间间隔 为1sauthentication {auth_type PASS    # 密码认证 passwordauth_pass 1111    # 具体密码 可以不用修改}virtual_ipaddress {   # vip 虚拟ip地址 可以配置多个192.168.2.201     # 配置的vip 必须与master配置的vip是一样的}
}
[root@mysqlrouter-2 keepalived]# 

10.3、刷新keepalived服务,并查看master和backup的IP地址

七、使用sysbench压力测试工具测试整个数据库集群的性能,了解集群系统性能资源的瓶颈

参考:Mysql压力测试(sysbench)_Claylpf的博客-CSDN博客

1、安装sysbench工具

[root@ab ~]# yum install epel-release -y[root@ab ~]# yum install sysbench -y已安装:sysbench.x86_64 0:1.0.17-2.el7                                                                                                                                                             作为依赖被安装:ck.x86_64 0:0.5.2-2.el7                           luajit.x86_64 0:2.0.5-1.20220913.46e62cd.el7                           postgresql-libs.x86_64 0:9.2.24-8.el7_9                          完毕!

2、调大内核资源限制

[root@sysbench ~]# ulimit -n 100000
[root@sysbench ~]# ulimit -u 100000
[root@sysbench ~]# ulimit -s 100000

3、在master上创建用户和库,配置用户的权限可以使他可以访问库(Mysql的主从复制)

CREATE USER 'claylpf'@'%' IDENTIFIED BY '123456';  #创建用户create database test_db;  #创建测试库GRANT ALL PRIVILEGES ON test_db.* TO 'claylpf'@'%';  #配置用户权限FLUSH PRIVILEGES;  #重新加载用户权限表

4、基于sysbench构造测试表和测试数据

[root@ab ~]# sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=192.168.2.221 --mysql-port=7001 --mysql-user=claylpf --mysql-password=123456 --mysql-db=test_db --tables=10 --table_size=1000 oltp_read_write --db-ps-mode=disable prepare

命令行中的参数说明:

​--db-driver=mysql:代表数据库驱动

--time=300:这个就是说连续访问300秒

--threads=10:这个就是说用10个线程模拟并发访问

--report-interval=1:这个就是说每隔1秒输出一下压测情况

--mysql-host=192.168.2.221 --mysql-port=7001 --mysql-user=claylpf --mysql-password=123456:数据库的用户和密码等信息

--mysql-db=test_db --tables=20 --table_size=1000000:这一串的意思,就是说在test_db这个库里,构造20个测试表,每个测试表里构造100万条测试数据,测试表的名字会是类似于sbtest1,sbtest2这个样子的

​oltp_read_write:这个就是说,执行oltp数据库的读写测试

--db-ps-mode=disable:这个就是禁止ps模式

prepare:意思是参照这个命令的设置去构造出来我们需要的数据库里的数据,他会自动创建20个测试表,每个表里创建100万条测试数据,所以这个工具是非常的方便的。

5、创建我们需要的数据库里的数据

[root@ab ~]# sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=192.168.2.221 --mysql-port=7001 --mysql-user=claylpf --mysql-password=123456 --mysql-db=test_db --tables=10 --table_size=1000 oltp_read_write --db-ps-mode=disable prepare# 注意--tables=10 --table_size=1000所对应的数据不能调试太大(如:--tables=20 --table_size=1000000000),否则会导致你的Mysql集群的磁盘耗尽,导致集群崩溃.
sysbench 1.0.17 (using system LuaJIT 2.0.4)Initializing worker threads...Creating table 'sbtest10'...
Creating table 'sbtest3'...
Creating table 'sbtest9'...
Creating table 'sbtest6'...
Creating table 'sbtest1'...
Creating table 'sbtest8'...
Creating table 'sbtest4'...
Creating table 'sbtest5'...
Creating table 'sbtest7'...
Creating table 'sbtest2'...
Inserting 1000 records into 'sbtest10'
Inserting 1000 records into 'sbtest1'
Inserting 1000 records into 'sbtest2'
Inserting 1000 records into 'sbtest4'
Inserting 1000 records into 'sbtest5'
Inserting 1000 records into 'sbtest6'
Inserting 1000 records into 'sbtest7'
Inserting 1000 records into 'sbtest8'
Inserting 1000 records into 'sbtest9'
Inserting 1000 records into 'sbtest3'
Creating a secondary index on 'sbtest1'...
Creating a secondary index on 'sbtest10'...
Creating a secondary index on 'sbtest6'...
Creating a secondary index on 'sbtest4'...
Creating a secondary index on 'sbtest5'...
Creating a secondary index on 'sbtest2'...
Creating a secondary index on 'sbtest7'...
Creating a secondary index on 'sbtest9'...
Creating a secondary index on 'sbtest8'...
Creating a secondary index on 'sbtest3'...

6、数据库读写性能测试(获取测试数据)

数据库读写性能测试,将执行指令最后的prepare修改成run:

[root@ab ~]# sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=192.168.2.221 --mysql-port=7001 --mysql-user=claylpf --mysql-password=123456 --mysql-db=test_db --tables=10 --table_size=1000 oltp_read_write --db-ps-mode=disable run
sysbench 1.0.17 (using system LuaJIT 2.0.4)Running the test with following options:
Number of threads: 10
Report intermediate results every 1 second(s)
Initializing random number generator from current timeInitializing worker threads...Threads started!
#​ 下面是截取的执行1秒,2秒,3秒,4秒等的数据。
[ 1s ] thds: 10 tps: 172.58 qps: 3597.26 (r/w/o: 2541.82/701.30/354.14) lat (ms,95%): 71.83 err/s: 0.00 reconn/s: 0.00
[ 2s ] thds: 10 tps: 187.08 qps: 3691.57 (r/w/o: 2574.10/745.32/372.16) lat (ms,95%): 71.83 err/s: 0.00 reconn/s: 0.00
[ 3s ] thds: 10 tps: 196.01 qps: 3961.13 (r/w/o: 2774.09/792.03/395.01) lat (ms,95%): 65.65 err/s: 0.00 reconn/s: 0.00
[ 4s ] thds: 10 tps: 206.93 qps: 4139.62 (r/w/o: 2900.04/824.73/414.86) lat (ms,95%): 64.47 err/s: 1.00 reconn/s: 0.00
[ 5s ] thds: 10 tps: 212.06 qps: 4236.12 (r/w/o: 2970.79/841.22/424.11) lat (ms,95%): 62.19 err/s: 0.00 reconn/s: 0.00
[ 6s ] thds: 10 tps: 184.06 qps: 3728.31 (r/w/o: 2608.92/751.26/368.13) lat (ms,95%): 97.55 err/s: 0.00 reconn/s: 0.00
[ 7s ] thds: 10 tps: 208.86 qps: 4131.17 (r/w/o: 2894.02/819.44/417.71) lat (ms,95%): 59.99 err/s: 0.00 reconn/s: 0.00
[ 8s ] thds: 10 tps: 214.14 qps: 4283.87 (r/w/o: 2997.01/858.58/428.29) lat (ms,95%): 62.19 err/s: 0.00 reconn/s: 0.00
[ 9s ] thds: 10 tps: 187.96 qps: 3725.23 (r/w/o: 2600.47/750.85/373.92) lat (ms,95%): 84.47 err/s: 0.00 reconn/s: 0.00
[ 10s ] thds: 10 tps: 195.96 qps: 3981.11 (r/w/o: 2795.38/791.82/393.91) lat (ms,95%): 66.84 err/s: 0.00 reconn/s: 0.00
^C
[root@ab ~]# 

对表中的数据进行说明,以第一条数据做解释描述:

thds: 10:这个意思就是有10个线程在压测

​ tps: 151.70:这个意思就是每秒执行了151.70个事务

​ qps: 2996.03:这个意思就是每秒可以执行2996.03个请求

​ (r/w/o: 2091.83/600.80/303.40):这个意思就是说,在每秒2996.03个请求中,有2091.83个请求是读请求,600.80个请求是写请求,303.40个请求是其他的请求,就是对QPS进行了拆解

​ lat (ms, 95%): 97.55:这个意思就是说,95%的请求的延迟都在 97.55毫秒以下

​ err/s: 0.00 reconn/s: 0.00:这两个的意思就是说,每秒有0个请求是失败的,发生了0次网络重连

下面是执行完成后控制台输出的数据:

SQL statistics:queries performed:read:                            836822write:                           239020other:                           119517total:                           1195359transactions:                        59744  (199.12 per sec.)queries:                             1195359 (3984.01 per sec.)ignored errors:                      29     (0.10 per sec.)reconnects:                          0      (0.00 per sec.)General statistics:total time:                          300.0377stotal number of events:              59744Latency (ms):min:                                   19.82avg:                                   50.21max:                                  267.2895th percentile:                       68.05sum:                              2999907.14Threads fairness:events (avg/stddev):           5974.4000/21.35execution time (avg/stddev):   299.9907/0.01

7、执行完成压测之后可以将run改成cleanup,清除数据

[root@ab ~]# sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=192.168.2.221 --mysql-port=7001 --mysql-user=claylpf --mysql-password=123456 --mysql-db=test_db --tables=10 --table_size=1000 oltp_read_write --db-ps-mode=disable cleanup
sysbench 1.0.17 (using system LuaJIT 2.0.4)Dropping table 'sbtest1'...
Dropping table 'sbtest2'...
Dropping table 'sbtest3'...
Dropping table 'sbtest4'...
Dropping table 'sbtest5'...
Dropping table 'sbtest6'...
Dropping table 'sbtest7'...
Dropping table 'sbtest8'...
Dropping table 'sbtest9'...
Dropping table 'sbtest10'...
[root@ab ~]# 

8、IO性能压力测试

8.1、创建5个文件,总共500MB,每个文件大概100MB

[root@sysbench ~]# sysbench fileio --file-num=5 --file-total-size=500MB prepare
sysbench 1.0.17 (using system LuaJIT 2.0.4)5 files, 102400Kb each, 500Mb total
Creating files for the test...
Extra file open flags: (none)
Creating file test_file.0
Creating file test_file.1
Creating file test_file.2
Creating file test_file.3
Creating file test_file.4
524288000 bytes written in 6.21 seconds (80.54 MiB/sec).
[root@sysbench ~]# 

8.2、测试效果

[root@sysbench ~]# sysbench --events=5000 --threads=16 fileio --file-num=5 --file-total-size=500MB --file-test-mode=rndrw --file-fsync-freq=0 --file-block-size=16384 run
sysbench 1.0.17 (using system LuaJIT 2.0.4)Running the test with following options:
Number of threads: 16
Initializing random number generator from current timeExtra file open flags: (none)
5 files, 100MiB each
500MiB total file size
Block size 16KiB
Number of IO requests: 5000
Read/Write ratio for combined random IO test: 1.50
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing random r/w test
Initializing worker threads...Threads started!File operations:reads/s:                      22083.80writes/s:                     14833.29fsyncs/s:                     590.67Throughput:                                        #吞吐量read, MiB/s:                  345.06           #读带宽written, MiB/s:               231.77           #写带宽General statistics:total time:                          0.1292stotal number of events:              5000Latency (ms):min:                                    0.00avg:                                    0.13max:                                   29.0995th percentile:                        0.02sum:                                  664.57Threads fairness:events (avg/stddev):           312.5000/671.89execution time (avg/stddev):   0.0415/0.01[root@sysbench ~]# 

8.3、清除数据:

[root@sysbench ~]#  sysbench fileio --file-num=5 --file-total-size=500MB cleanup
sysbench 1.0.17 (using system LuaJIT 2.0.4)Removing test files...
[root@sysbench ~]# 

9、cpu性能压力测试

[root@sysbench ~]#  sysbench cpu --threads=40 --events=10000 --cpu-max-prime=5000 run
sysbench 1.0.17 (using system LuaJIT 2.0.4)Running the test with following options:
Number of threads: 40
Initializing random number generator from current timePrime numbers limit: 5000Initializing worker threads...Threads started!CPU speed:                                  # CPU运行速度events per second:  4804.95             # 每秒运行的事件数General statistics:total time:                          2.0789stotal number of events:              10000Latency (ms):min:                                    0.11avg:                                    7.31max:                                  858.8695th percentile:                        0.31sum:                                73145.78Threads fairness:events (avg/stddev):           250.0000/35.90execution time (avg/stddev):   1.8286/0.17[root@sysbench ~]# 

八、搭建基于prometheus + grafana的监控系统,对数据库集群进行监控

参考:Prometheus监控软件的学习_nfs exporter_Claylpf的博客-CSDN博客Grafana展示工具的学习_grafana学习_Claylpf的博客-CSDN博客

1、安装部署mysqld_exporter

下载地址:Download | Prometheus

2、上传软件包到linux的/root/目录下

3、解压,并移动到/usr/local/mysqld_exporter下

[root@master ~]# tar -zxvf mysqld_exporter-0.15.0.linux-amd64.tar.gz 
mysqld_exporter-0.15.0.linux-amd64/
mysqld_exporter-0.15.0.linux-amd64/mysqld_exporter
mysqld_exporter-0.15.0.linux-amd64/NOTICE
mysqld_exporter-0.15.0.linux-amd64/LICENSE
[root@master ~]# ls
anaconda-ks.cfg             mha4mysql-node-0.58         mysql-5.7.41-linux-glibc2.12-x86_64.tar.gz  mysqld_exporter-0.15.0.linux-amd64.tar.gz  onekey_install_mysql_binary.sh
mha4mysql-node-0.56.tar.gz  mha4mysql-node-0.58.tar.gz  mysqld_exporter-0.15.0.linux-amd64          onekey_install_mha_node.sh                 sersync2.5.4_64bit_binary_stable_final.tar.gz
[root@master ~]# 
[root@master ~]# mv mysqld_exporter-0.15.0.linux-amd64 /usr/local/mysqld_exporter
[root@master ~]# cd /usr/local/mysqld_exporter/
[root@master mysqld_exporter]# ls
LICENSE  mysqld_exporter  NOTICE
[root@master mysqld_exporter]# 

4、在/usr/local/mysqld_exporter下编辑连接本机数据库的配置文件

[root@master mysqld_exporter]# vim my.cnf
[root@master mysqld_exporter]# cat my.cnf 
[client]
user=mysqld_exporter 
password=123456
[root@master mysqld_exporter]# 

user=mysqld_exporter #监控本机数据库的授权用户

password=123456 #密码

5、将mysqld_exporter命令加入环境变量,并设置开机自启

[root@master mysqld_exporter]# PATH=/usr/local/mysqld_exporter/:$PATH
[root@master mysqld_exporter]# echo "PATH=/usr/local/mysqld_exporter/:$PATH" >>/root/.bashrc
[root@master mysqld_exporter]# 

6、后台启动

[root@master mysqld_exporter]# nohup mysqld_exporter --config.my-cnf=/usr/local/mysqld_exporter/my.cnf &
[1] 25415

7、看进程,看端口,网页访问测试

[root@master mysqld_exporter]# ps aux|grep exporter
root      25415  0.0  0.4 719560  4752 pts/0    Sl   11:18   0:00 mysqld_exporter --config.my-cnf=/usr/local/mysqld_exporter/my.cnf
root      25419  0.0  0.0 112824   988 pts/0    R+   11:19   0:00 grep --color=auto exporter
[root@master mysqld_exporter]# netstat -anplut|grep mysqld
tcp6       0      0 :::3306                 :::*                    LISTEN      25027/mysqld        
tcp6       0      0 :::9104                 :::*                    LISTEN      25415/mysqld_export 
tcp6       0      0 192.168.2.150:3306      192.168.2.152:51232     ESTABLISHED 25027/mysqld        
tcp6       0      0 192.168.2.150:3306      192.168.2.151:47084     ESTABLISHED 25027/mysqld        
[root@master mysqld_exporter]# 

网页访问测试

8、安装prometheus,配置成服务

8.1、上传安装包到linux家目录下

8.2、解压Prometheus压缩包,并移动到/prometheus目录下

[root@prometheus ~]# tar zvxf prometheus-2.43.0.linux-amd64.tar.gz
[root@prometheus ~]# mv prometheus-2.43.0.linux-amd64 /prometheus

8.3、将Prometheus配置成service服务

[root@mysql prometheus]# vim /usr/lib/systemd/system/prometheus.service  
#创建一个prometheus.service文件
[root@mysql prometheus]# cat /usr/lib/systemd/system/prometheus.service
#如果需要自行复制
[Unit]
Description=prometheus[Service]
ExecStart=/prometheus/prometheus/prometheus --config.file=/prometheus/prometheus/prometheus.yml
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure[Install]
WantedBy=multi-user.target
[root@mysql prometheus]# 
[root@mysql prometheus]# systemctl daemon-reload   
#说明我已经向systemd注册prometheus.service文件了,意思是重新加载systemd相关服务[root@mysql prometheus]# service prometheus restart  #对prometheus服务进行运行
Redirecting to /bin/systemctl restart prometheus.service
[root@mysql prometheus]# [root@mysql prometheus]# ps aux|grep prometheus    #检查prometheus的进程是否存在
root       5338  0.1  5.3 930420 52784 pts/0    Sl   19:39   0:02 prometheus --config.file=/prometheus/prometheus/prometheus.yml
root       5506  0.0  0.0 112824   992 pts/0    R+   20:22   0:00 grep --color=auto prometheus
[root@mysql prometheus]# service prometheus stop
Redirecting to /bin/systemctl stop prometheus.service
[root@mysql prometheus]# ps aux|grep prometheus
root       5338  0.1  5.3 930420 52784 pts/0    Sl   19:39   0:02 prometheus --config.file=/prometheus/prometheus/prometheus.yml
root       5524  0.0  0.0 112824   988 pts/0    R+   20:22   0:00 grep --color=auto prometheus
因为第一次是使用nohup方式启动的prometheus,所以还是需要kill的方式杀死进程
后面就可以使用service的方式启动prometheus了
[root@mysql prometheus]# kill -9 5338      #需要kill原来没有使用service运行的prometheus进程 
[root@mysql prometheus]# service prometheus restart
Redirecting to /bin/systemctl restart prometheus.service
[1]+  已杀死               nohup prometheus --config.file=/prometheus/prometheus/prometheus.yml
[root@mysql prometheus]# ps aux|grep prometheus
root       5541  1.0  3.9 798700 39084 ?        Ssl  20:23   0:00 /prometheus/prometheus/prometheus --config.file=/prometheus/prometheus/prometheus.yml
root       5548  0.0  0.0 112824   992 pts/0    R+   20:23   0:00 grep --color=auto prometheus
[root@mysql prometheus]# service prometheus stop      #关闭prometheus,成功关闭
Redirecting to /bin/systemctl stop prometheus.service
[root@mysql prometheus]# ps aux|grep prometheus
root       5567  0.0  0.0 112824   992 pts/0    R+   20:23   0:00 grep --color=auto prometheus
[root@mysql prometheus]# 
验证成功

8.4、查看Prometheus端口

[root@prometheus ~]# netstat -anpult|grep prometheus
tcp6       0      0 :::9090                 :::*                    LISTEN      2433/prometheus     
tcp6       0      0 ::1:9090                ::1:42032               ESTABLISHED 2433/prometheus     
tcp6       0      0 ::1:42032               ::1:9090                ESTABLISHED 2433/prometheus     
[root@prometheus ~]# 

8.4、访问Prometheus服务页面

9、Prometheus添加node节点

[root@prometheus ~]# cd /prometheus/prometheus
[root@prometheus prometheus]# ls
console_libraries  consoles  LICENSE  NOTICE  prometheus  prometheus.yml  promtool
[root@prometheus prometheus]# vim prometheus.yml 
[root@prometheus prometheus]# cat prometheus.yml 
#l config
global:scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.# scrape_timeout is set to the global default (10s).# Alertmanager configuration
alerting:alertmanagers:- static_configs:- targets:# - alertmanager:9093# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:# - "first_rules.yml"# - "second_rules.yml"# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.- job_name: "prometheus"# metrics_path defaults to '/metrics'# scheme defaults to 'http'.static_configs:- targets: ["localhost:9090"]- job_name: "mysqlrouter1"static_configs:- targets: ["192.168.2.181:9104"]- job_name: "mysqlrouter2"static_configs:- targets: ["192.168.2.182:9104"]- job_name: "slave1"static_configs:- targets: ["192.168.2.151:9104"]- job_name: "slave2"static_configs:- targets: ["192.168.2.152:9104"]- job_name: "master"static_configs:- targets: ["192.168.2.150:9104"]- job_name: "mha_manager"static_configs:- targets: ["192.168.2.141:9104"]- job_name: "backup"static_configs:- targets: ["192.168.2.157:9104"]
[root@prometheus prometheus]# 

9.1、刷新Prometheus服务

[root@prometheus prometheus]# service prometheus restart
Redirecting to /bin/systemctl restart prometheus.service
[root@prometheus prometheus]# 

10、测试访问Prometheus服务:

11、安装grafana

11.1、上传grafana的rpm安装包

11.2、安装grafana

[root@prometheus ~]# yum install -y grafana-enterprise-9.4.7-1.x86_64.rpm

11.3、启动grafana

[root@prometheus ~]# service grafana-server start
Starting grafana-server (via systemctl):                   [  确定  ]
[root@prometheus ~]# 

11.4、查看端口,并访问测试grafana

查看端口

[root@prometheus ~]# netstat -anpult | grep grafana
tcp        0      0 192.168.2.149:47398     34.120.177.193:443      ESTABLISHED 2627/grafana        
tcp        0      0 192.168.2.149:58982     185.199.108.133:443     ESTABLISHED 2627/grafana        
tcp6       0      0 :::3000                 :::*                    LISTEN      2627/grafana        
[root@prometheus ~]# 

访问测试grafana

页面访问,第一次登录账号密码默认都为admin

登陆后需要修改密码(lpf1375509........) 账号默认admin

如果忘记密码了我们可以使用

sqlite3 /var/lib/grafana/grafana.db   

> update user set password = '59acf18b94d7eb0694c61e60ce44c110c7a683ac6a8f09580d626f90f4a242000746579358d77dd9e570e83fa24faa88a8a6', salt = 'F3FAxVm33R' where login = 'admin';         

> .exit

PS: 用户:admin 密码:admin

重启服务

/etc/init.d/grafana-server restart

12、在grafana中增添Prometheus数据源

 

13、添加Dashboards模板(推荐使用14057模板,因为14057模板比较美观,出图效果也比较好,推荐使用)

14、grafana效果展示

基于mycat2+mha+keepalived的半同步主从复制MySQL cluster_linux_51

九、搭建DNS主域名服务器,增添两条负载均衡记录,实现对Mysqlrouter双vip地址的DNS负载均衡

1、安装DNS服务

[root@dns ~]# systemctl disable firewalld #关闭防火墙,防止windows客户机无法访问dns服务器 
[root@dns ~]# systemctl disable NetworkManager #关闭NetworkManager
[root@dns ~]# yum install bind* #安装dns服务的软件包
[root@dns ~]# service named start #启动dns服务
[root@dns ~]# systemctl enable named  #开机启动dns服务

2、修改dns配置文件,任意ip可以访问本机的53端口,并且允许dns解析。

[root@dns ~]# vim /etc/named.conf
listen-on port 53 { any; };#允许任意ip访问53端口listen-on-v6 port 53 { any; }; directory       "/var/named";dump-file       "/var/named/data/cache_dump.db";statistics-file "/var/named/data/named_stats.txt";memstatistics-file "/var/named/data/named_mem_stats.txt";recursing-file  "/var/named/data/named.recursing";secroots-file   "/var/named/data/named.secroots";allow-query     { any; }; #允许任意dns解析

3、搭建主域名服务器

3.1、修改named.rfc1912.zones配置文件,告诉named为claylpf.xyz提供域名解析

[root@dns ~]# vim /etc/named.rfc1912.zones 
[root@dns ~]# cat /etc/named.rfc1912.zones 
// named.rfc1912.zones:
//
// Provided by Red Hat caching-nameserver package 
//
// ISC BIND named zone configuration for zones recommended by
// RFC 1912 section 4.1 : localhost TLDs and address zones
// and http://www.ietf.org/internet-drafts/draft-ietf-dnsop-default-local-zones-02.txt
// (c)2007 R W Franks
// 
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//zone "localhost.localdomain" IN {type master;file "named.localhost";allow-update { none; };
};zone "localhost" IN {type master;file "named.localhost";allow-update { none; };
};zone "claylpf.xyz" IN {type master;file "claylpf.xyz.zone";allow-update { none; };
};
#添加上面的配置,建议在localhost的后面zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" IN {type master;file "named.loopback";allow-update { none; };
};zone "1.0.0.127.in-addr.arpa" IN {type master;file "named.loopback";allow-update { none; };
};zone "0.in-addr.arpa" IN {type master;file "named.empty";allow-update { none; };
};[root@dns ~]# 

3.2、创建claylpf.xyz主域名的数据文件

[root@dns ~]# cd /var/named/
[root@dns named]# ls
chroot  chroot_sdb  data  dynamic  dyndb-ldap  named.ca  named.empty  named.localhost  named.loopback  slaves
[root@dns named]# cp -a named.localhost claylpf.xyz.zone
[root@dns named]# ls
chroot  chroot_sdb  claylpf.xyz.zone  data  dynamic  dyndb-ldap  named.ca  named.empty  named.localhost  named.loopback  slaves
[root@dns named]# 

3.3、修改claylpf.xyz.zone文件:

[root@dns named]# vim claylpf.xyz.zone 
[root@dns named]# cat claylpf.xyz.zone 
$TTL 1D
@       IN SOA  @ rname.invalid. (0       ; serial1D      ; refresh1H      ; retry1W      ; expire3H )    ; minimumNS      @A       192.168.2.155 
www IN  A       192.168.2.221 
www IN  A       192.168.2.201 
[root@dns named]# 

3.4、刷新dns服务

[root@dns named]# service named restart
Redirecting to /bin/systemctl restart named.service
[root@dns named]# 

4、效果测试

4.1、修改linux客户机的dns服务器的地址为搭建的dns服务器192.168.2.155

[root@claylpf network-scripts]# vim /etc/resolv.conf 
[root@claylpf network-scripts]# cat /etc/resolv.conf 
# Generated by NetworkManager
#nameserver 114.114.114.114
nameserver 192.168.2.155
[root@claylpf network-scripts]# 

4.2、查看效果

[root@claylpf ~]# nslookup www.claylpf.xyz
Server:		192.168.2.155
Address:	192.168.2.155#53Name:	www.claylpf.xyz
Address: 192.168.2.221
Name:	www.claylpf.xyz
Address: 192.168.2.201[root@claylpf ~]# 

同一域名解析出了中间件mysqlrouter的双vip地址,实现了基于dns的负载均衡

项目结束!!

项目遇到的问题

1、各种软件的有些配置项加了注释项,导致无法正常启动
答:多查看软件的报错信息以及查看服务日志,对排错的帮助会很大

2、主从复制时,只在slave上进行了操作,导致事务数比主服务器还要多,主从复制一直起不来
答:查看报错信息,是事务数比主服务器还要多—>尽可能删除比主服务器还要多出来的数据,在reset master,并重新设置master_info信息

3、本以为mysqlrouter访问读写数据源的vip地址(mha架构里写服务器的特有ip)要修改mysql的绑定ip地址才能登录,后来发现只要新建了允许mysqlrouter访问的授权用户允许所有ip登录就行

4、使用rsync时,数据源备份文件/backup/打成了/backup导致把整个文件夹都同步过去了

发现dns负载均衡的效果不是很明显,再linux上访问能解析出199,而在windows机上能解析出188

5、压力测试的时候,由于内核参数的限制,导致无法起太多的线程
答:修改内核限制参数,以及调大mysql中与内核相关的参数

6、使用ansible调用一键二进制安装脚本中mysql加入环境变量不成功
答:再使用shell模块,远程加入PATH变量

7、ulimit -n修改不生效
答:写入到/etc/security/limits.conf中使其永久生效

8、修改主机名后,mysql重启不成功

答:需要杀死所有mysqld进程,在重新启动mysql

项目心得 

1、提前规划好整个集群的架构,可以提高项目开展时效率

2、运行报错,多看出错信息提示以及日志,对排错的帮助很大


3、对半同步的主从复制有了更深入的理解

4、对keepalived的脑裂和vip漂移现象也有了更加深刻的体会和分析


5、加强了mha架构中自动failover的实现原理的理解


6、对基于mysqlrouter的读写分离过程更加的熟悉


7、认识到了数据备份的重要性


8、深刻的体会到了rsync+sersync数据同步工具的便利与好处


9、熟练了sysbench下的压力测试,认识到了系统性能资源的重要性,对压力测试下整个集群的瓶颈有了一个整体概念


10、对监控也有了的更进一步的认识,监控可以提前看到问题,做好预警


11、对很多软件之间的配合有了一定的理解,如mysqlrouter、mha、mysql等


12、troubleshooting的能力得到了提升

相关文章:

基于Mysqlrouter+MHA+keepalived实现高可用半同步 MySQL Cluster项目

目录 项目名称&#xff1a; 基于Mysqlrouter MHA keepalived实现半同步主从复制MySQL Cluster MySQL Cluster&#xff1a; 项目架构图&#xff1a; 项目环境&#xff1a; 项目环境安装包&#xff1a; 项目描述&#xff1a; 项目IP地址规划&#xff1a; 项目步骤: 一…...

Android12.0 系统限制上网系列之iptables用IOemNetd实现清除所有规则的实现

1.前言 在12.0的系统rom定制化开发中,对于系统限制网络的使用,需要在system中netd网络这块的产品要求中,会要求设置屏蔽ip地址之内的功能, liunx中iptables命令也是比较重要的,接下来就来在IOemNetd这块实现清除所有自定义规则的的相关功能 2. 系统限制上网系列之iptab…...

vue2和vue3响应式原理

Object.DefineProperty配置对象的主要属性有&#xff1a; value:20 //添加的属性的value enumerable:true //是否可以被枚举获取到 默认&#xff1a;false writeable:true //value是否可以被修改 默认&#xff1a;false configurable:true //是否可以被删除 默认&#xff1a;f…...

【面试八股文】每日一题:谈谈你对线程的理解

每日一题-Java核心-谈谈你对线程的理解【面试八股文】 Java线程是Java程序中的执行单元。一个Java程序可以同时运行多个线程&#xff0c;每个线程可以独立执行不同的任务。线程的执行是并发的&#xff0c;即多个线程可以同时执行。 1. 线程的特点 Java中的线程有如下的特点 轻…...

arm开发板 GDB远程调试方法

1.前言 1.在linux下开发&#xff0c;免不了使用gdb调试&#xff0c;但是linux下开发嵌入式&#xff0c;都是跑在ARM板子上的&#xff0c;网上有很多GDB的基础教程&#xff0c;但是能在ARM开发板用的时候&#xff0c;会有各种问题。 比如&#xff1a;*.cpp: No such file or di…...

Linux命令(71)之unxz

linux命令之unxz 1.unxz介绍 linux命令unxz是用来解压由xz命令压缩的文件。unxz等价于xz -d 2.unxz用法 unxz [-c] filename.xz unxz常用参数 参数说明-c <目录>将压缩文件解压到指定目录 3.实例 3.1.解压zzz.txt.xz文件至当前目录 命令&#xff1a; unxz zzz.tx…...

广告牌安全传感器,实时监测事故隐患尽在掌握

在现代城市中&#xff0c;广告牌作为商业宣传的重要媒介&#xff0c;已然成为城市中一道独特的风景线。然而&#xff0c;随着城市迅速发展&#xff0c;广告牌的安全问题也引起了大众关注。广告招牌一般悬挂于建筑物高处&#xff0c;量大面大。由于设计、材料、施工方法的缺陷&a…...

对比学习损失—InfoNCE理论理解

InfoNoise的理解 InfoNCE loss温度系数 τ \tau τ InfoNCE loss 最近在看对比学习的东西&#xff0c;记录点基础的东西 「对比学习」 属于无监督学习的一种&#xff0c;给一堆数据&#xff0c;没有标签&#xff0c;自己学习出一种特征表示。 InfoNCE 这个损失是来自于论文&am…...

贝锐蒲公英助力电子公交站牌联网远程运维,打造智慧出行新趋势

在现代城市公共交通系统中&#xff0c;我们随处可见电子公交站牌的身影。作为公共交通服务的核心之一&#xff0c;电子公交站牌的稳定运行至关重要&#xff0c;公交站台的实时公交状况、公共广告信息&#xff0c;是市民候车时关注的焦点。 某交通科技公司在承接某市智能电子站牌…...

SpringBoot + Vue 微人事(十)

职位管理前后端接口对接 先把table中的数据展示出来&#xff0c;table里面的数据实际上是positions里面的数据&#xff0c;就是要给positions:[] 赋上值 可以在methods中定义一个initPosition方法 methods:{//定义一个初始化positions的方法initPositions(){//发送一个get请求…...

【Redis】Redis哨兵模式

【Redis】Redis哨兵模式 Redis主从模式当主服务器宕机后&#xff0c;需要手动把一台从服务器切换为主服务器&#xff0c;需要人工干预费事费力&#xff0c;为了解决这个问题出现了哨兵模式。 哨兵模式是是一个管理多个 Redis 实例的工具&#xff0c;它可以实现对 Redis 的监控…...

系统架构师---软件重用、基于架构的软件设计、软件模型

目录 软件重用 构件技术 基于架构的软件设计 ABSD方法与生命周期 抽象功能需求 用例 抽象的质量和业务需求 架构选项 质量场景 约束 基于架构的软件开发模型 架构需求 需求获取 标识构件 需求评审 架构设计 架构文档 架构复审 架构实现 架构演化 前言&…...

【Web开发指南】MyEclipse XML编辑器的高级功能简介

MyEclipse v2023.1.2离线版下载 1. 在MyEclipse中编辑XML 本文档介绍MyEclipse XML编辑器中的一些可用的函数&#xff0c;MyEclipse XML编辑器包括高级XML编辑&#xff0c;例如&#xff1a; 语法高亮显示标签和属性内容辅助实时验证(当您输入时)文档内容的源&#xff08;Sou…...

设计模式-观察者模式(观察者模式的需求衍变过程详解,关于监听的理解)

目录 前言概念你有过这样的问题吗&#xff1f; 详细介绍原理&#xff1a;应用场景&#xff1a; 实现方式&#xff1a;类图代码 问题回答监听&#xff0c;为什么叫监听&#xff0c;具体代码是哪观察者模式的需求衍变过程观察者是为什么是行为型 总结&#xff1a; 前言 在软件设计…...

vue+electron中实现文件下载打开wps预览

下载事件 win.webContents.downloadURL(url) 触发session的will-download事件 win.webContents.session.on(will-download, (event, downloadItem, webContents) > {// 设置文件保存路径// 如果用户没有设置保存路径&#xff0c;Electron将使用默认方式来确定保存路径&am…...

第4章 性能分析中的术语和指标

Linux perf和Intel VTune Profiler工具。 4.1 退休指令与执行指令 考虑到投机执行&#xff0c;CPU执行的指令要不退休指令多。Linux perf使用perf stat -e instruction ./a.exe即可获得退休指令的数量。 4.2 CPU利用率 CPU利用率表示在一段时间内的繁忙程度&#xff0c;用时…...

数字化转型能带来哪些价值?_光点科技

随着科技的迅猛发展&#xff0c;数字化转型已成为企业和组织的一项重要战略。它不仅改变了商业模式和运营方式&#xff0c;还为各行各业带来了诸多新的机遇和价值。在这篇文章中&#xff0c;我们将探讨数字化转型所能带来的价值。 数字化转型能够显著提升效率和生产力。通过引入…...

适用于Android™的Windows子系统Windows Subsystem fo r Android™Win11安装指南

文章目录 一、需求二、Windows Subsystem for Android™Win11简介三、安装教程1.查看BIOS是否开启虚拟化2.安装Hyper-V、虚拟机平台3.启动虚拟机管理程序(可选)4.安装适用于Android™的Windows子系统5.相关设置 一、需求 需要在电脑上进行网课APP&#xff08;无客户端只有App&…...

hive高频使用的拼接函数及“避坑”

hive高频使用的拼接函数及“避坑” 说到拼接函数应用场景和使用频次还是非常高&#xff0c;比如一个员工在公司充当多个角色&#xff0c;我们在底层存数的时候往往是多行&#xff0c;但是应用的时候我们通常会只需要一行&#xff0c;角色字段进行拼接&#xff0c;这样join其他…...

windows ipv4 多ip地址设置,默认网关跃点和自动跃点是什么意思?(跃点数)

文章目录 Windows中的IPv4多IP地址设置以及默认网关跃点和自动跃点的含义引言IPv4和IPv6&#xff1a;简介多IP地址设置&#xff1a;Windows环境中的实现默认网关跃点&#xff1a;概念和作用自动跃点&#xff1a;何时使用&#xff1f;关于“跃点数”如何确定应该设置多少跃点数&…...

java_免费文本翻译API_小牛翻译

目录 前言 开始集成API 纯文本翻译接口 双语对照翻译接口 指定术语翻译接口 总结 前言 网络上对百度&#xff0c;有道等的文本翻译API集成的文章比较多&#xff0c;所以集成的第一篇选择了小牛翻译的文本翻译API。 小牛翻译文本翻译API&#xff0c;支持388个语种&#xff0…...

flink消费kafka数据,按照指定时间开始消费

kafka中根据时间戳开始消费数据 import org.apache.flink.api.java.utils.ParameterTool; import org.apache.flink.connector.kafka.source.enumerator.initializer.OffsetsInitializer; import org.apache.flink.kafka.shaded.org.apache.kafka.clients.consumer.OffsetRese…...

【SpringCloud】Feign使用

文章目录 配置maven启动类添加yml 使用添加Feign服务Controller 其他设置超时设置YML开启OpenFeign客户端超时控制&#xff08;Ribbon Timeout&#xff09;OpenFeign日志打印功能日志级别YML开启日志 配置 maven <dependencies><!--openfeign--><dependency&g…...

WebApIs 第五天

window对象 BOM&#xff08;浏览器对象模型&#xff09;定时器-延时函数JS执行机制location对象navigator对象histroy对象 本地存储 一.BOM&#xff08;浏览器对象模型&#xff09; ① BOM是浏览器对象模型 window 对象是一个全局对象&#xff0c;也可以说是JavaScript中的…...

按斤称的C++散知识

一、多线程 std::thread()、join() 的用法&#xff1a;使用std::thread()可以创建一个线程&#xff0c;同时指定线程执行函数以及参数&#xff0c;同时也可使用lamda表达式。 #include <iostream> #include <thread>void threadFunction(int num) {std::cout <…...

C++策略模式

1 简介&#xff1a; 策略模式是一种行为型设计模式&#xff0c;用于在运行时根据不同的情况选择不同的算法或行为。它将算法封装成一个个具体的策略类&#xff0c;并使这些策略类可以相互替换&#xff0c;以达到动态改变对象的行为的目的。 2 实现步骤&#xff1a; 以下是使用…...

如何在网页下载腾讯视频为本地MP4格式

1.打开腾讯视频官网地址 腾讯视频 2.搜索你想要下载的视频 3. 点击分享,选择复制通用代码 <iframe frameborder="0" src="ht...

opencv-yolov8-目标检测

import cv2 from ultralytics import YOLO# 模型加载权重model YOLO(yolov8n.pt)# 视频路径cap cv2.VideoCapture(0)# 对视频中检测到目标画框标出来 while cap.isOpened():# Read a frame from the videosuccess, frame cap.read()if success:# Run YOLOv8 inference on th…...

CRYPTO 密码学-笔记

一、古典密码学 1.替换法&#xff1a;用固定的信息&#xff0c;将原文替换成密文 替换法的加密方式&#xff1a;一种是单表替换&#xff0c;另一种是多表替换 单表替换&#xff1a;原文和密文使用同一张表 abcde---》sfdgh 多表替换&#xff1a;有多涨表&#xff0c;原文和密文…...

基于YOLOv8模型的五类动物目标检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要&#xff1a;基于YOLOv8模型的五类动物目标检测系统可用于日常生活中检测与定位动物目标&#xff08;狼、鹿、猪、兔和浣熊&#xff09;&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的目标检测&#xff0c;另外本系统还支持图片、视频等格式的结果可视化与…...

Java课题笔记~ SpringBoot基础配置

二、基础配置 1. 配置文件格式 问题导入 框架常见的配置文件有哪几种形式&#xff1f; 1.1 修改服务器端口 http://localhost:8080/books/1 >>> http://localhost/books/1 SpringBoot提供了多种属性配置方式 application.properties server.port80 applicati…...

vue实现文件上传,前后端

前端封装el-upload组件&#xff0c;父组件传值dialogVisible&#xff08;用于显示el-dialog&#xff09;&#xff0c;子组件接收&#xff0c;并且关闭的时候返回一个值&#xff08;用于隐藏el-dialog&#xff09;,最多上传五个文件&#xff0c;文件格式为.jpg\pdf\png <tem…...

OJ练习第151题——克隆图

克隆图 力扣链接&#xff1a;133. 克隆图 题目描述 给你无向 连通 图中一个节点的引用&#xff0c;请你返回该图的 深拷贝&#xff08;克隆&#xff09;。 示例 分析 对于一张图而言&#xff0c;它的深拷贝即构建一张与原图结构&#xff0c;值均一样的图&#xff0c;但是…...

keepalived+lvs实现高可用

目录 环境 1.配置real-server服务器 2.配置keepalived和lvs 3.测试&#xff1a; 概述 keepalivedlvs实现高可用&#xff1a; lvs可以监控后端服务器&#xff0c;当服务器宕机之后可以对其进行故障切换。 keepalived是对VIP进行检测&#xff0c;当某一个主机的vip错误&…...

【Let‘s make it big】英语合集61~70

61(82) top-of-range it doesn’t get any better than this There seems to be a problem with my account What seems to be the problem withdraw money from my saving account charged an overdraft fee we don’t give loans to customers whose accounts are overdrawn…...

python实现图像的二分类

要实现图像的二分类&#xff0c;可以使用深度学习中的卷积神经网络&#xff08;Convolutional Neural Network, CNN&#xff09;模型。下面是一个使用Keras库实现的简单CNN模型示例&#xff1a; from keras.models import Sequential from keras.layers import Conv2D, MaxPoo…...

8.深浅拷贝和异常处理

开发中我们经常需要复制一个对象。如果直接用赋值会有下面问题: 8.1 浅拷贝 首先浅拷贝和深拷贝只针对引用类型 浅拷贝&#xff1a;拷贝的是地址 常见方法: 1.拷贝对象&#xff1a;Object.assgin() / 展开运算符{…obj} 拷贝对象 2.拷贝数组&#xff1a;Array.prototype.con…...

Element Plus el-table 数据为空时自定义内容【默认为 No Data】

1. 通过 Table 属性设置 <div class"el-plus-table"><el-table empty-text"暂无数据" :data"tableData" style"width: 100%"><el-table-column prop"date" label"Date" width"180" /&g…...

使用nginx和frp实现高效内网穿透:简单配置,畅通无阻

I. 引言 A. 介绍内网穿透的概念和用途 内网穿透是一种网络技术&#xff0c;它允许用户通过公共网络访问位于私有网络&#xff08;内网&#xff09;中的资源和服务。在传统的网络环境中&#xff0c;内网通常是由路由器或防火墙保护的&#xff0c;无法直接从外部网络访问内部资…...

Python土力学与基础工程计算.PDF-螺旋板载荷试验

python 求解代码如下&#xff1a; 1. import numpy as np 2. 3. # 已知参数 4. p_a 100 # 标准压力&#xff0c; kPa 5. p np.array([25, 50, 100, 200) # 荷载&#xff0c; kPa 6. s np.array([2.88, 5.28, 9.50, 15.00) / 10 # 沉降量&#xff0c; cm 7. D 10 # 螺旋板直…...

低代码开发ERP:精打细算,聚焦核心投入

企业数字化转型已经成为现代商业环境中的一项关键任务。如今&#xff0c;企业面临着日益激烈的竞争和不断变化的市场需求。在这样的背景下&#xff0c;数字化转型不仅是企业生存的必然选择&#xff0c;也是取得竞争优势和实现可持续发展的关键因素。 在数字化转型的过程中&…...

顺序表(数据结构)

“路虽远&#xff0c;行则将至” ❤️主页&#xff1a;小赛毛 顺序表目录 1.线性表 2.顺序表 概念及结构 静态顺序表&#xff1a;使用定长数组存储元素。 动态顺序表&#xff1a;使用动态开辟的数组存储。 接口实现 1.线性表 线性表 &#xff08; linear list &#xff09; 是…...

stable_diffusion_webui docker环境配置

1.新建docker环境 docker run -tid --name e_commerce_sd --net host --runtimenvidia nvidia/cuda:11.1-cudnn8-devel-cent os7-ssh /bin/bashdocker exec -ti e_commerce_sd /bin/bash echo expor…...

【Java】常见面试题:HTTP/HTTPS、Servlet、Cookie、Linux和JVM

文章目录 1. 抓包工具&#xff08;了解&#xff09;2. 【经典面试题】GET和POST的区别&#xff1a;3. URL中不是也有这个服务器主机的IP和端口吗&#xff0c;为啥还要搞个Host&#xff1f;4. 补充5. HTTP响应状态码6. 总结HTTPS工作过程&#xff08;经典面试题&#xff09;7. H…...

批量爬虫采集完成任务

批量爬虫采集是现代数据获取的重要手段&#xff0c;然而如何高效完成这项任务却是让许多程序员头疼的问题。本文将分享一些实际操作价值高的方法&#xff0c;帮助你提高批量爬虫采集的效率和专业度。 目标明确&#xff0c;任务合理划分&#xff1a; 在开始批量爬虫采集前&…...

intelij idea 2023 创建java web项目

1.点击New Project 2.创建项目名称为helloweb &#xff0c;jdk版本这里使用8&#xff0c;更高版本也不影响工程创建 点击create 3.新建的工程是空的&#xff0c;点击File-> Project Structure 4.点击Modules 5.点击加号&#xff0c;然后键盘输入web可以搜索到web模块&…...

【论文笔记】基于指令回译的语言模型自对齐-MetaAI

MetaAI最近发布的Humpback&#xff0c;论文链接&#xff1a;https://arxiv.org/abs/2308.06259 解决什么问题&#xff1f; 大量高质量的指令微调数据集的生成。 思路 在这项工作中&#xff0c;我们通过开发迭代自训练算法来利用大量未标记的数据来创建高质量的指令调优数据集…...

MySQL和MariaDB的版本对应关系

MariaDB 10.0和MariaDB 10.1可以作为MySQL 5.6的有限替代。 MariaDB 10.2可以作为MySQL 5.7的有限替代。 一&#xff0c;目前最新版本 MariaDB 10.5.8 10.4.17 10.3.27 10.2.36 MySQL 8.0.23 二&#xff0c;oracle MySQL版本和MariaDB版本对应表: MariaDB版本 …...

Python数据的输入与输出

编辑&#xff1a;2023-08-14 17:00 Python是一种高级编程语言&#xff0c;它支持多种输入输出方式&#xff0c;包括标准输入输出、文件输入输出等。本文将从以下几个方面详细阐述Python数据的输入与输出。 一、标准输入输出 Python中的标准输入和标准输出指的是控制台输入输…...

生成国密密钥对

在线生成国密密钥对 生成的密钥对要妥善保管&#xff0c;丢失是无法找回的。...