基于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实现数据远程备份,做好灾备工作,保证业务稳定。
项目步骤
-
部署ansible,在所有的机器之间配置SSH免密通道,利用ansible快速搭建项目环境;
-
在3台MySQL服务器上配置好主从复制,形成一个master+2个slave节点(半同步+GTID)的集群,提供数据库服务;
-
使用rsync+sersync搭建数据文件实时远程备份,搭建延迟备份服务和利用mysqlrouter实现读写分离,以达到更好的MySQL集群性能;
-
安装keepalived,在2台mysqlrouter服务器上,实现读写分离和高可用,在keepalived上配置2个实例,实现2个vip,互为master和backup,更加好的提升高可用的性能;
-
搭建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
项目中遇见的一些问题:
- 修改配置文件的时候容易出错,导致无法启动,不知道具体情况的时候可以检查日志;
- 搭建延迟备份时遇见:
Starting MySQL... ERROR! The server quit without updating PID file
,查阅资料发现是权限、端口或者配置的问题,但一一尝试都发现不对,日志也模棱两可,最后卸载重装,可能是我做配置的时候出错; - keepalived脑裂情况,检查配置文件以及防火墙问题;
- 修改主机名后,mysql重启不成功,杀死所有mysqld进程,再重新启动mysql。
项目心得
提前规划好整个集群的架构,可以提高项目开展时效率
运行报错,多看出错信息提示以及日志,帮助很大
对基于GTID+半同步的主从复制有了更深入的理解
对keepalived的脑裂和vip漂移现象也有了更加深刻的体会和分析
体会到了rsync+sersync数据同步工具的便利与好处