基于GTID的半同步高可用MySQL集群

前提准备

网络拓扑图

在这里插入图片描述

准备9台centos7.9的虚拟机,并且分配IP地址:

主机名 IP
master 192.168.78.132
slave1 192.168.78.149
slave2 192.168.78.150
delay_backup 192.168.78.148
ansible 192.168.78.139
mysqlrouter1 192.168.78.135
mysqlrouter2 192.168.78.136
promtheus+grafana 192.168.78.147
test 192.168.78.145

项目环境

centos7.9 mysql5.7.41 mysqlrouter8.0.21 keepalived-1.3.5 ansible-2.9.27
sysbench 1.0.17 grafana-9.1.2

项目描述

本项目的目的是构建一个高可用的能实现读写分离的高效的MySQL集群,同时利用rsync+sersync实现数据远程备份,做好灾备工作,保证业务稳定。

项目步骤

  1. 部署ansible,在所有的机器之间配置SSH免密通道,利用ansible快速搭建项目环境;

  2. 在3台MySQL服务器上配置好主从复制,形成一个master+2个slave节点(半同步+GTID)的集群,提供数据库服务;

  3. 使用rsync+sersync搭建数据文件实时远程备份,搭建延迟备份服务和利用mysqlrouter实现读写分离,以达到更好的MySQL集群性能;

  4. 安装keepalived,在2台mysqlrouter服务器上,实现读写分离和高可用,在keepalived上配置2个实例,实现2个vip,互为master和backup,更加好的提升高可用的性能;

  5. 搭建Prometheus+grafana监控实现数据可视化,使用压力测试软件(sysbench)测试整个MySQL集群的性能。

一、安装ansible,建立免密通道部署MySQL

1、 安装ansible

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

2、建立免密通道

与所有MySQL服务器搭建免密通道:

[root@ansible .ssh]# ssh-keygen 	#一直回车进行
[root@ansible .ssh]# ssh-copy-id -i id_rsa.pub 192.168.78.132  		#master
[root@ansible .ssh]# ssh-copy-id -i id_rsa.pub 192.168.78.149 		#slave1
[root@ansible .ssh]# ssh-copy-id -i id_rsa.pub 192.168.78.150		#slave2
[root@ansible .ssh]# ssh-copy-id -i id_rsa.pub 192.168.78.148		#delay_backup

测试连接:

[root@ansible .ssh]# ssh '192.168.78.148'

3.利用ansible部署MySQL集群

编写主机清单:

[root@ansible ~]# cd /etc/ansible/
[root@ansible ansible]# ls
ansible.cfg  hosts  playbooks  roles
[root@ansible ansible]# vim hosts 
[mysql]
192.168.78.132          #master
192.168.78.149          #slave1
192.168.78.150          #slave2
192.168.78.148          #delay_backup

编写playbook,上传源码包到远程服务器,调用本地脚本安装MySQL:

[root@ansible playbooks]# vim mysql_install.yaml
- hosts: mysql
  remote_user: root
  tasks:
  - name: copy file     #上传MySQL安装包到mysql主机组
    copy: src=/root/mysql-5.7.41-linux-glibc2.12-x86_64.tar.gz dest=/root/
  - name: mysql_install         #安装MySQL
    script: /root/onekey_install_mysql_binary_v3.sh

检查yaml文件语法并且执行:

[root@ansible playbooks]# ansible-playbook --syntax-check mysql_install.yaml 

playbook: mysql_install.yaml
[root@ansible playbooks]# ansible-playbook mysql_install.yaml 

查看是否安装成功:

[root@slave1 ~]# ps aux|grep mysqld
root       2521  0.0  0.1  11824  1612 ?        S    11:22   0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/data/mysql --pid-file=/data/mysql/slave1.pid
mysql      2675  0.4 20.6 1610264 205460 ?      Sl   11:22   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       2784  0.0  0.0 112824   976 pts/0    S+   11:24   0:00 grep --color=auto mysqld
[root@slave1 ~]# netstat -anplut|grep mysqld
tcp6       0      0 :::3306                 :::*                    LISTEN      2675/mysqld    

mysql安装脚本:

#!/bin/bash

#解决软件的依赖关系
yum  install cmake ncurses-devel gcc  gcc-c++  vim  lsof bzip2 openssl-devel ncurses-compat-libs -y

#解压mysql二进制安装包
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

#关闭firewalld防火墙服务,并且设置开机不要启动
service firewalld stop
systemctl  disable  firewalld

#临时关闭selinux
setenforce 0
#永久关闭selinux
sed -i '/^SELINUX=/ s/enforcing/disabled/'  /etc/selinux/config

#新建存放数据的目录
mkdir  /data/mysql -p
#修改/data/mysql目录的权限归mysql用户和mysql组所有,这样mysql用户可以对这个文件夹进行读写了
chown mysql:mysql /data/mysql/
#只是允许mysql这个用户和mysql组可以访问,其他人都不能访问
chmod 750 /data/mysql/

#进入/usr/local/mysql/bin目录
cd /usr/local/mysql/bin/

#初始化mysql
./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表示最后一个字段
  # abc=$(命令)  优先执行命令,然后将结果赋值给abc 

# 修改PATH变量,加入mysql bin目录的路径
#临时修改PATH变量的值
export PATH=/usr/local/mysql/bin/:$PATH
#重新启动linux系统后也生效,永久修改
echo  'PATH=/usr/local/mysql/bin:$PATH' >>/root/.bashrc

#复制support-files里的mysql.server文件到/etc/init.d/目录下叫mysqld
cp  ../support-files/mysql.server   /etc/init.d/mysqld

#修改/etc/init.d/mysqld脚本文件里的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

#修改内核的open file的数量
ulimit -n 1000000
#设置开机启动的时候也配置生效
echo "ulimit -n 1000000" >>/etc/rc.local
chmod +x /etc/rc.d/rc.local


#启动mysqld进程
service mysqld start

#将mysqld添加到linux系统里服务管理名单里
/sbin/chkconfig --add mysqld
#设置mysqld服务开机启动
/sbin/chkconfig mysqld on

#初次修改密码需要使用--connect-expired-password 选项
#-e 后面接的表示是在mysql里需要执行命令  execute 执行
#set password='Sanchuang123#';  修改root用户的密码为long123#
mysql -uroot -p$tem_passwd --connect-expired-password   -e  "set password='long123#';"


#检验上一步修改密码是否成功,如果有输出能看到mysql里的数据库,说明成功。
mysql -uroot -p'long123#'  -e "show databases;"

二、配置MySQL半同步,开启GTID功能

1.master上导出数据

[root@mysql-master ~]# mysqldump -uroot -p"Sanchuang123#" --all-databases >/backup/all_dbdata.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.

2.在所有从服务器上导入master数据

在master上scp数据文件到从服务器:

[root@mysql-master backup]# scp all_dbdata.sql 192.168.78.149:/root
all_dbdata.sql                                                           100%  888KB  60.0MB/s   00:00    
[root@mysql-master backup]# scp all_dbdata.sql 192.168.78.150:/root
all_dbdata.sql                                                           100%  888KB  91.0MB/s   00:00    
[root@mysql-master backup]# scp all_dbdata.sql 192.168.78.148:/root
all_dbdata.sql                                                           100%  888KB 101.8MB/s   00:00    
[root@mysql-master backup]# 

在从服务器导入数据文件到MySQL:

[root@delay_backup ~]# mysql -uroot -p"long123#" <all_dbdata.sql 
mysql: [Warning] Using a password on the command line interface can be insecure.

3.半同步和GTID配置

在master机器上安装半同步插件:

root@(none) 13:37  mysql>install plugin rpl_semi_sync_master SONAME 'semisync_master.so';

在master上修改配置文件进行永久配置,并且刷新服务:

[root@mysql-master /]# vim /etc/my.cnf
[mysqld]
#开启二进制日志
log_bin
server_id=1
#半同步
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000  #1 second
#gtid功能
gtid-mode=ON
enforce-gtid-consistency=ON
[root@mysql-master /]# service mysqld restart
Shutting down MySQL.... SUCCESS! 
Starting MySQL. SUCCESS! 

在3台从服务器上安装半同步插件:

root@(none) 13:46  mysql>install plugin rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.01 sec)

在从服务器上修改配置文件:

[root@slave1 ~]# vim /etc/my.cnf
#二进制日志
log_bin
server_id=2                #!注意:每台slave的id都不一样
expire_logs_days=15     #二进制日志保存15天
#开启gtid功能
gtid-mode=ON
enforce-gtid-consistency=ON
log_slave_updates=ON
#开启半同步,需要提前安装半同步的插件
rpl_semi_sync_slave_enabled=1
[root@slave1 ~]# service mysqld restart

查看是否成功开启半同步:

root@(none) 13:44  mysql>show status like 'Rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON    |
+-----------------------------+-------+
1 row in set (0.02 sec)

在master上新建一个授权用户,给slave来复制二进制日志:

root@(none) 14:57  mysql>grant replication slave on *.* to 'ly'@'192.168.78.%'identified by '123456';
Query OK, 0 rows affected, 1 warning (1.02 sec)

root@(none) 15:03  mysql>flush privileges;	#刷新
Query OK, 0 rows affected (0.01 sec)

在slave1,slave2上配置master info的信息:
注意:为防止配置环境导致IO线程不能正常启动,需要先在slave上做清除记录的操作

#清除二进制记录与master info的记录
root@(none) 16:07  mysql>reset master;
Query OK, 0 rows affected (0.02 sec)

root@(none) 16:07  mysql>stop slave;
Query OK, 0 rows affected (0.01 sec)

root@(none) 16:07  mysql>reset slave all;
Query OK, 0 rows affected (0.01 sec)

root@(none) 16:08  mysql>CHANGE MASTER TO MASTER_HOST='192.168.78.132',
    ->  MASTER_USER='ly',
    ->  MASTER_PASSWORD='123456',
    ->  MASTER_PORT=3306,
    ->  master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.00 sec)

root@(none) 16:11  mysql>start slave;
Query OK, 0 rows affected (0.00 sec)

查看io线程和SQL线程是否启动:

root@(none) 16:11  mysql>show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.78.132
                  Master_User: ly
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-master-bin.000001
          Read_Master_Log_Pos: 890
               Relay_Log_File: slave1-relay-bin.000002
                Relay_Log_Pos: 1117
        Relay_Master_Log_File: mysql-master-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

验证半同步是否成功:
在master上删除一个库:
在这里插入图片描述
在slave上查看:
在这里插入图片描述

4.延迟备份配置

在slave1上开启二进制和log_slave_updates功能,实现延迟备份服务器可以从slave1上拿数据。

[root@slave1 ~]# cat /etc/my.cnf
 
[mysqld]
#添加配置
log_slave_updates=ON 
 
#重启服务
[root@slave1 ~]#service mysqld restart

在延迟备份delay_backup服务器上修改master info:

root@(none) 16:19  mysql>stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)

root@(none) 16:30  mysql>reset slave;
Query OK, 0 rows affected (0.01 sec)

root@(none) 16:31  mysql>reset slave all;
Query OK, 0 rows affected (0.00 sec)

root@(none) 16:31  mysql>CHANGE MASTER TO MASTER_HOST='192.168.78.149',		#slave1的IP
    ->  MASTER_USER='ly',
    ->  MASTER_PASSWORD='123456',
    ->  MASTER_PORT=3306,
    ->  master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.02 sec)

root@(none) 16:31  mysql>change master to MASTER_DELAY=1800;		#延迟半个小时进行备份
Query OK, 0 rows affected (0.01 sec)

root@(none) 16:32  mysql>start slave;
Query OK, 0 rows affected (0.00 sec)

检查IO线程与SQL线程是否正常启动:

root@(none) 16:32  mysql>show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.78.149
                  Master_User: ly
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: slave1-bin.000001
          Read_Master_Log_Pos: 1195
               Relay_Log_File: delay_backup-relay-bin.000002
                Relay_Log_Pos: 1105
        Relay_Master_Log_File: slave1-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

三、搭建rsync+sersync实现文件实时同步

在master服务器与ansible服务器上搭建rsync+sersync文件实现异地备份与数据的实时同步,保证数据的安全性与完整性

1.ansible服务器操作

安装rsync:

[root@ansible /]# yum install rsync xinetd -y

xinetd是一个提供保姆服务的进程,rsync是它照顾的进程
设置开机启动:

[root@ansible /]# vim /etc/rc.d/rc.local 
#添加开机启动
/usr/bin/rsync --daemon --config=/etc/rsyncd.conf
#授权
[root@ansible /]# chmod +x /etc/rc.d/rc.local 
#启动服务
[root@ansible /]# systemctl start xinetd

设置配置文件rsyncd.conf:

[root@ansible /]# vim /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 stored
        ignore errors = yes
        read only = no
        hosts allow = 192.168.78.132  #允许的IP地址(数据源服务器地址)

创建用户认证文件,并设置文件权限:

[root@ansible /]# vim /etc/rsync.pass
[root@ansible /]# cat /etc/rsync.pass
ly:ly123
[root@ansible /]# chmod 600 /etc/rsyncd.conf
[root@ansible /]# chmod 600 /etc/rsync.pass

启动rsync和xinetd:

[root@ansible /]# /usr/bin/rsync --daemon --config=/etc/rsyncd.conf
[root@ansible /]# ps aux|grep rsync
root       5330  0.0  0.0 114852   572 ?        Ss   16:51   0:00 /usr/bin/rsync --daemon --config=/etc/rsyncd.conf
root       5332  0.0  0.0 112824   976 pts/0    S+   16:51   0:00 grep --color=auto rsync
[root@ansible /]# service xinetd restart
Redirecting to /bin/systemctl restart xinetd.service
[root@ansible /]# ps aux|grep xinetd
root       5351  0.0  0.0  25044   588 ?        Ss   16:52   0:00 /usr/sbin/xinetd -stayalive -pidfile /var/run/xinetd.pid
root       5355  0.0  0.0 112824   976 pts/0    S+   16:52   0:00 grep --color=auto xinetd

2.master服务器操作

安装rsync:

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

设置开机启动:

[root@mysql-master /]# vim /etc/rc.d/rc.local 
/usr/bin/rsync --daemon	--config=/etc/rsyncd.conf
[root@mysql-master /]# chmod +x /etc/rc.d/rc.local

修改配置文件,添加相关配置:

[root@mysql-master /]# vim /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 = Sync
uid = root
gid = root
port= 873

创建认证密码,启动服务:
该密码应与目标服务器中的/etc/rsync.pass中的密码一致

[root@mysql-master /]# cat /etc/passwd.txt 
ly123
[root@mysql-master /]# chmod 600 /etc/passwd.txt 
[root@mysql-master /]# systemctl start xinetd

测试数据源服务器master到备份服务器ansible,之间的数据同步,把mysql的数据目录备份到备份服务器:

[root@mysql-master backup]# rsync -avH --port=873 --progress --delete  /data  [email protected]::back_data --password-file=/etc/passwd.txt

3.安装sersync工具进行实时同步

修改inotify默认参数(inotify已经默认在内核里安装了,不需要安装):

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

安装sersync:

[root@mysql-master /]# wget http://down.whsir.com/downloads/sersync2.5.4_64bit_binary_stable_final.tar.gz
[root@mysql-master /]# tar xf sersync2.5.4_64bit_binary_stable_final.tar.gz 
[root@mysql-master /]# mv GNU-Linux-x86 /usr/local/sersync

创建rsync:

[root@mysql-master ~]# cd /usr/local/sersync
[root@mysql-master sersync]# ls
confxml.xml  sersync2
[root@mysql-master sersync]# cp confxml.xml confxml.xml.bak
[root@mysql-master sersync]# cp confxml.xml data_configxml.xml
[root@mysql-master sersync]# ls
confxml.xml  confxml.xml.bak  data_configxml.xml  sersync2

修改配置 data_configxml.xml 文件第24行后的配置:
在这里插入图片描述
启动服务并且设置开机启动:

[root@mysql-master sersync]# /usr/local/sersync/sersync2 -d -r -o  /usr/local/sersync/data_configxml.xml
set the system param
[root@mysql-master sersync]# vi /etc/rc.d/rc.local
 /usr/local/sersync/sersync2 -d -r -o  /usr/local/sersync/data_configxml.xml
[root@mysql-master sersync]# chmod +x /etc/rc.d/rc.local 

测试:
master:
在这里插入图片描述
备份服务器:
在这里插入图片描述

四、配置MySQL读写分离

1.安装mysqlrouter

下载地址:mysqlrouter
在mysqlrouter1和mysqlrouter2上安装:

[root@mysqlrouter1 ~]# rpm -ivh mysql-router-community-8.0.21-1.el7.x86_64.rpm 

2.修改配置文件

mysqlrouter1和mysqlrouter2都需要修改:

[root@mysqlrouter1 ~]# cd /etc/mysqlrouter/
[root@mysqlrouter1 mysqlrouter]# ls
mysqlrouter.conf
[root@mysqlrouter1 mysqlrouter]# vim mysqlrouter.conf 
[routing:slaves]
bind_address = 0.0.0.0:8888		#8888端口监听读
destinations = 192.168.78.149:3306,192.168.78.150:3306	#在slave上执行读操作
mode = read-only
connect_timeout = 1

[routing:masters]
bind_address = 0.0.0.0:8889		#8889端口监听写
destinations = 192.168.78.132:3306	#在master是执行写操作
mode = read-write
connect_timeout = 1

启动mysqlrouter服务:

[root@mysqlrouter2 mysqlrouter]# service mysqlrouter start
Redirecting to /bin/systemctl start mysqlrouter.service
[root@mysqlrouter2 mysqlrouter]# netstat -anplut |grep 888
tcp        0      0 0.0.0.0:8888            0.0.0.0:*               LISTEN      1683/mysqlrouter    
tcp        0      0 0.0.0.0:8889            0.0.0.0:*               LISTEN      1683/mysqlrouter 

3.验证读写分离

在master上创建2个测试账号,一个是用来读数据,一个用来写数据:

root@(none) 21:48  mysql>grant all on *.*  to 'write'@'%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)

root@(none) 21:49  mysql>grant select on *.*  to 'read'@'%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.01 sec)

在客户端test上测试读写分离的效果:
用客户机连接mysqlrouter的写端口,测试写功能,发现读写正常:

[root@test ~]# mysql -h 192.168.78.135 -P 8889 -uwrite -p'123456'
write@(none) 14:24  mysql>create database db1;
Query OK, 1 row affected (0.00 sec)

write@(none) 14:25  mysql>drop database db1;
Query OK, 0 rows affected (0.02 sec)

write@(none) 14:26  mysql>use ly
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
write@ly 14:26  mysql>show tables;
+--------------+
| Tables_in_ly |
+--------------+
| t1           |
+--------------+
1 row in set (0.01 sec)

write@ly 14:26  mysql>select * from t1;
+----+------+
| id | name |
+----+------+
|  1 | cali |
|  2 | ly   |
|  3 | xx   |
|  4 | ada  |
|  5 | dad  |
|  6 | asd  |
+----+------+
6 rows in set (0.00 sec)

用客户机连接mysqlrouter的读端口,测试读功能,发现读正常,不能写入:

read@(none) 14:56  mysql>create database db2;
ERROR 1044 (42000): Access denied for user 'read'@'%' to database 'db2'
read@(none) 14:56  mysql>use ly
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
read@ly 14:56  mysql>select * from  t1;
+----+------+
| id | name |
+----+------+
|  1 | cali |
|  2 | ly   |
|  3 | xx   |
|  4 | ada  |
|  5 | dad  |
|  6 | asd  |
+----+------+
6 rows in set (0.01 sec)

read@ly 14:57  mysql>insert into t1 values(7,zx);
ERROR 1142 (42000): INSERT command denied to user 'read'@'192.168.78.135' for table 't1'

五、搭建keepalived实现高可用

1.在两台mysqlrouter上都安装keepalived软件:

[root@mysqlrouter1 ~]# yum install keepalived -y

2.修改配置文件:

mysqlrouter1配置:

[root@mysqlrouter1 keepalived]# vim keepalived.conf
! Configuration File for keepalived

global_defs {
    
    
   notification_email {
    
    
     [email protected]
     [email protected]
     [email protected]
   }
   notification_email_from [email protected]
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    
    
    state MASTER
    interface ens33
    virtual_router_id 220
    priority 120
    advert_int 1
    authentication {
    
    
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
    
    
        192.168.78.220
    }
}

vrrp_instance VI_2 {
    
    
    state BACKUP
    interface ens33
    virtual_router_id 221
    priority 100
    advert_int 1
    authentication {
    
    
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
    
    
        192.168.78.221
    }
}
[root@mysqlrouter1 keepalived]# service keepalived restart
Redirecting to /bin/systemctl restart keepalived.service

mysqlrouter2配置:

[root@mysqlrouter2 keepalived]# vim keepalived.conf
! Configuration File for keepalived

global_defs {
    
    
   notification_email {
    
    
     [email protected]
     [email protected]
     [email protected]
   }
   notification_email_from [email protected]
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    
    
    state BACKUP
    interface ens33
    virtual_router_id 220
    priority 100
    advert_int 1
    authentication {
    
    
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
    
    
        192.168.78.220
    }
}
vrrp_instance VI_2 {
    
    
    state MASTER
    interface ens33
    virtual_router_id 221
    priority 120
    advert_int 1
    authentication {
    
    
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
    
    
        192.168.78.221
    }
}
[root@mysqlrouter2 keepalived]# service keepalived restart
Redirecting to /bin/systemctl restart keepalived.service

启动2个vrrp实例,每台机器上都启用2个vrrp实例,一个做master,一个做backup,启用2个vip,每台机器上都会有一个vip,这2个vip都对外提供服务,这样就可以避免单vip的情况下,一个很忙一个很闲。 可以提升设备的使用率.

六、搭建Prometheus+grafana监控

1.安装prometheus server

#上传下载的源码包到linux服务器
[root@prometheus ~]# mkdir /prom
[root@prometheus ~]# cd /prom
[root@prometheus prom]# ls
prometheus-2.34.0.linux-amd64.tar.gz
#解压源码包
[root@prometheus prom]# tar xf prometheus-2.34.0.linux-amd64.tar.gz
[root@prometheus prom]# ls
prometheus-2.34.0.linux-amd64  prometheus-2.34.0.linux-amd64.tar.gz
[root@prometheus prom]# mv prometheus-2.34.0.linux-amd64 prometheus
[root@prometheus prom]# ls
prometheus  prometheus-2.34.0.linux-amd64.tar.gz
#临时和永久修改PATH变量,添加prometheus的路径
[root@prometheus prometheus]# PATH=/prom/prometheus:$PATH		#临时
[root@prometheus prometheus]# cat /root/.bashrc				
PATH=/prom/prometheus:$PATH   #添加
#执行prometheus程序
[root@prometheus prometheus]# nohup prometheus  --config.file=/prom/prometheus/prometheus.yml &
[1] 8431
[root@prometheus prometheus]# nohup: 忽略输入并把输出追加到"nohup.out"

2.把prometheus做成一个服务来进行管理

[root@prometheus prometheus]# vim /usr/lib/systemd/system/prometheus.service 
[Unit]
Description=prometheus
[Service]
ExecStart=/prom/prometheus/prometheus --config.file=/prom/prometheus/prometheus.yml
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
[Install]WantedBy=multi-user.target
#重新加载systemd相关的服务
[root@prometheus prometheus]# systemctl daemon-reload
[root@prometheus prometheus]#  service prometheus start
[root@prometheus system]# ps aux|grep prometheu
root       7193  2.0  4.4 782084 44752 ?        Ssl  13:16   0:00 /prom/prometheus/prometheus --config.file=/prom/prometheus/prometheus.yml
root       7201  0.0  0.0 112824   972 pts/1    S+   13:16   0:00 grep --color=auto prometheu

3.执行Prometheus程序

[root@prometheus prometheus]# nohup prometheus  --config.file=/prom/prometheus/prometheus.yml &
[1] 1543
[root@prometheus prometheus]# nohup: 忽略输入并把输出追加到"nohup.out"

[root@prometheus prometheus]# 
[root@prometheus prometheus]# service prometheus restart
Redirecting to /bin/systemctl restart prometheus.service
[root@prometheus prometheus]# netstat -anplut|grep prome
tcp6       0      0 :::9090                 :::*                    LISTEN      1543/prometheus     
tcp6       0      0 ::1:9090                ::1:42776               ESTABLISHED 1543/prometheus     
tcp6       0      0 ::1:42776               ::1:9090                ESTABLISHED 1543/prometheus   

在这里插入图片描述

4.在node节点服务器上安装exporter程序

下载node_exporter-1.4.0-rc.0.linux-amd64.tar.gz源码,上传到节点服务器上:

 wget https://github.com/prometheus/node_exporter/releases/download/v1.4.0/node_exporter-1.4.0.linux-amd64.tar.gz

解压,单独存放到/node_exporter文件夹:

1.下载node_exporter-1.4.0-rc.0.linux-amd64.tar.gz源码,上传到节点服务器上
2.解压
[root@mysql-master ~]# ls
anaconda-ks.cfg  node_exporter-1.4.0-rc.0.linux-amd64.tar.gz
[root@mysql-master ~]# tar xf node_exporter-1.4.0-rc.0.linux-amd64.tar.gz
[root@mysql-master ~]# ls
node_exporter-1.4.0-rc.0.linux-amd64         
node_exporter-1.4.0-rc.0.linux-amd64.tar.gz  
单独存放到/node_exporter文件夹
[root@mysql-master ~]# mv node_exporter-1.4.0-rc.0.linux-amd64 /node_exporter
[root@mysql-master ~]# cd /node_exporter/
[root@mysql-master node_exporter]# ls
LICENSE  node_exporter  NOTICE
[root@mysql-master node_exporter]#

# 修改PATH变量
[root@mysql-master node_exporter]# PATH=/node_exporter/:$PATH
[root@mysql-master node_exporter]# vim /root/.bashrc 
[root@mysql-master node_exporter]# tail -1 /root/.bashrc 
PATH=/node_exporter/:$PATH

# 执行node exporter 代理程序agent
[root@mysql-master node_exporter]# nohup node_exporter --web.listen-address 0.0.0.0:8090  &
[root@mysql-master node_exporter]# ps aux | grep node_exporter 
root      64281  0.0  2.1 717952 21868 pts/0    Sl   19:03   0:04 node_exporter --web.listen-address 0.0.0.0:8090
root      82787  0.0  0.0 112824   984 pts/0    S+   20:46   0:00 grep --color=auto node_exporter
[root@mysql-master node_exporter]# netstat -anplut | grep 8090
tcp6       0      0 :::8090                 :::*                    LISTEN      64281/node_exporter 
tcp6       0      0 192.168.17.152:8090     192.168.17.156:43576    ESTABLISHED 64281/node_exporter 

5.在prometheus server里添加exporter程序

[root@prometheus prometheus]# vim prometheus.yml 
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: "master"
    static_configs:
      - targets: ["192.168.78.132:8090"]
  - job_name: "delay_backup"
    static_configs:
      - targets: ["192.168.78.148:8090"]
  - job_name: "slave1"
    static_configs:
      - targets: ["192.168.78.149:8090"]
  - job_name: "slave2"
    static_configs:
      - targets: ["192.168.78.150:8090"]
  - job_name: "mysqlrouter1"
    static_configs:
      - targets: ["192.168.78.135:8090"]
  - job_name: "mysqlrouter2"
    static_configs:
      - targets: ["192.168.78.136:8090"]
[root@prometheus prometheus]# service  prometheus restart
Redirecting to /bin/systemctl restart prometheus.service

查看效果:
在这里插入图片描述

6.部署grafana

Grafana是一个开源的数据可视化和分析平台,支持多种数据源的查询和展示。

[root@prometheus grafana]# wget https://dl.grafana.com/enterprise/release/grafana-enterprise-9.1.2-1.x86_64.rpm
[root@prometheus grafana]# yum install grafana-enterprise-9.1.2-1.x86_64.rpm -y
[root@prometheus grafana]# service grafana-server start
Starting grafana-server (via systemctl):                   [  确定  ]
#设置开机启动
[root@prometheus grafana]# systemctl enable grafana-server
Created symlink from /etc/systemd/system/multi-user.target.wants/grafana-server.service to /usr/lib/systemd/system/grafana-server.service.
#查看端口号
[root@prometheus grafana]# netstat -anplut|grep grafana
tcp6       0      0 :::3000                 :::*                    LISTEN      2187/grafana-server 

进入网站并登录grafana:
登录查看http://192.168.78.147:3000/login:

默认的用户名和密码是 用户名admin 密码admin

在这里插入图片描述

配置prometheus的数据源(点击设置>Add data source>Prometheus),填入URL,然后保存,导入grafana的模板(点击Dashboards下的import),填入模板编号,得到以下效果图:
在这里插入图片描述

七、使用sysbench对集群进行压力测试

1.安装sysbench

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

2.测试

先在test上连接到mysqlrouter的写端口,提前首先创建好sysbench所需数据库sbtest(sysbench默认使用的库名)。

[root@slave1 node_exporter]# mysql -uwrite -p"123456" -h 192.168.78.135 -P 8889
write@(none) 17:48  mysql>create database sbtest;
Query OK, 1 row affected (0.01 sec)

数据准备:

#其中--tables=10表示创建10个测试表,--table_size=100000表示每个表中插入10000行数据

[root@test ~]# sysbench --mysql-host=192.168.78.135 --mysql-port=8889 --mysql-user=write --mysql-password='123456' /usr/share/sysbench/oltp_common.lua  --tables=10  --table_size=10000 prepare
sysbench 1.0.17 (using system LuaJIT 2.0.4)

Creating table 'sbtest1'...
Inserting 10000 records into 'sbtest1'
Creating a secondary index on 'sbtest1'...
Creating table 'sbtest2'...
Inserting 10000 records into 'sbtest2'
Creating a secondary index on 'sbtest2'...
Creating table 'sbtest3'...
Inserting 10000 records into 'sbtest3'
Creating a secondary index on 'sbtest3'...
Creating table 'sbtest4'...
Inserting 10000 records into 'sbtest4'
Creating a secondary index on 'sbtest4'...
Creating table 'sbtest5'...
Inserting 10000 records into 'sbtest5'
Creating a secondary index on 'sbtest5'...
Creating table 'sbtest6'...
Inserting 10000 records into 'sbtest6'
Creating a secondary index on 'sbtest6'...
Creating table 'sbtest7'...
Inserting 10000 records into 'sbtest7'
Creating a secondary index on 'sbtest7'...
Creating table 'sbtest8'...
Inserting 10000 records into 'sbtest8'
Creating a secondary index on 'sbtest8'...
Creating table 'sbtest9'...
Inserting 10000 records into 'sbtest9'
Creating a secondary index on 'sbtest9'...
Creating table 'sbtest10'...
Inserting 10000 records into 'sbtest10'
Creating a secondary index on 'sbtest10'...

开始运行数据,进行压力测试:

[root@test sysbench-1.0.17]# sysbench --threads=4 --time=20 --report-interval=5 --mysql-host=192.168.78.135 --mysql-port=8889 --mysql-user=write --mysql-password='123456' /usr/share/sysbench/oltp_read_write.lua  --tables=10  --table_size=10000 run

在这里插入图片描述

项目中遇见的一些问题:

  1. 修改配置文件的时候容易出错,导致无法启动,不知道具体情况的时候可以检查日志;
  2. 搭建延迟备份时遇见:Starting MySQL... ERROR! The server quit without updating PID file,查阅资料发现是权限、端口或者配置的问题,但一一尝试都发现不对,日志也模棱两可,最后卸载重装,可能是我做配置的时候出错;
  3. keepalived脑裂情况,检查配置文件以及防火墙问题;
  4. 修改主机名后,mysql重启不成功,杀死所有mysqld进程,再重新启动mysql。

项目心得

提前规划好整个集群的架构,可以提高项目开展时效率
运行报错,多看出错信息提示以及日志,帮助很大
对基于GTID+半同步的主从复制有了更深入的理解
对keepalived的脑裂和vip漂移现象也有了更加深刻的体会和分析
体会到了rsync+sersync数据同步工具的便利与好处

猜你喜欢

转载自blog.csdn.net/zheng_long_/article/details/131795262