目录
项目名称:基于GTID+Keepalived的半同步主从复制Mysql集群
实验环境:mysql-5.7.38,mysqlrouter,keepalived,rsync+sersync,虚拟机6台(master服务器一台,slave服务器三台,mysqlrouter服务器二台)
实验描述:构建一个master和slave基于GTID半同步主从复制mysql集群,集群内部通过mysqlrouter实现读写分离,同时使用rsync同步备份数据,通过keepalived实现高可用的mysql集群
整体架构图:
实验步骤:
1.配置数据库,保持数据一致性
2.配置基于GTID的半同步主从复制
3.设置定时备份master数据库并且使用rsync+sersync同步备份文件到slave1延时备份服务器上
4.使用mysqlrouter实行读写分离与负载均衡
4.配置keepalived给两台mysqlrouter服务器实现高可用
在master,三台slave服务器上部署mysql,并初始化,使用编写的一键安装脚本,需要提前去官网下载mysql-5.7.38-linux-glibc2.12-x86_64.tar.gz,并上传到服务器
[root@web2 ~]# cat onekey_install_mysql_binary_v3.sh
#!/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.38-linux-glibc2.12-x86_64.tar.gz
#移动mysql解压后的文件到/usr/local下改名叫mysql
mv mysql-5.7.38-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
#修改内核的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用户的密码为Sanchuang123#
mysql -uroot -p$tem_passwd --connect-expired-password -e "set password='Sanchuang123#';"
#检验上一步修改密码是否成功,如果有输出能看到mysql里的数据库,说明成功。
mysql -uroot -p'Sanchuang123#' -e "show databases;"
在四台服务上初始化成功后得到用户名root用户密码为Sanchuang123#,登录验证
保证四台服务器数据一致性,将master上的数据库导出
[root@web1 backup]# mysqldump -uroot -p'Sanchuang123#' --all-databases > all_db.SAQL
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@web1 backup]# ls
all_db.SAQL
此时可以通过构建免密通道将all_db.SAQL导入其他三台slave,这里我选择用工具xttp传输,在另外三台机器导入该数据库
[root@web2 ~]# mysql -uroot -p'Sanchuang123#' < all_db.SAQL
mysql: [Warning] Using a password on the command line interface can be insecure.
整体设计为,slave3,slave2到master上拿二进制日志,slave1到slave3上拿二进制日志,进行/etc/my.conf配置数据库文件
master的配置文件为
[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
#开启二进制日志
log_bin
server_id = 2
#半同步功能
rpl_semi_sync_master_enabled=1 #添加
rpl_semi_sync_master_timeout=1000 # 添加
#gtid功能
gtid-mode=ON
enforce-gtid-consistency=ON
[mysql]
auto-rehash
prompt=\u@\d \R:\m mysql>
slave2的配置文件,slave2是普通的从服务器,没有额外功能,二进制日志可以开也可以不开
[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
#二进制日志
log_bin
server_id = 1
#半同步
rpl_semi_sync_slave_enabled=1 #添加
#开启gtid功能
gtid-mode=ON
enforce-gtid-consistency=ON
[mysql]
auto-rehash
prompt=\u@\d \R:\m mysql>
slave3既要去master上拿二进制日志,也要给slave1同步二进制日志,所以要添加一条额外的配置
[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
#二进制日志
log_bin
server_id = 1
#半同步
rpl_semi_sync_slave_enabled=1 #添加
#开启后,从master出拿到的二进制日志,能写入自己的二进制日志,让slave1来拿
log_slave_updates=ON
#开启gtid功能
gtid-mode=ON
enforce-gtid-consistency=ON
[mysql]
auto-rehash
prompt=\u@\d \R:\m mysql>
配置完之后,进入master数据库,安装半同步插件,创建授权用户renxj,给slave服务器拿二进制日志
root@(none) 09:59 scmysql>INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
root@(none) 15:16 mysql>grant replication slave on *.* to 'renxj'@'192.168.159.%' identified by 'Sanchuang123#';
Query OK, 0 rows affected, 1 warning (0.00 sec)
配置从服务器slave2,slave3,安装对应半同步插件
root@(none) 11:22 mysql>INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
root@(none) 11:19 scmysql>CHANGE MASTER TO MASTER_HOST='192.168.159.131' ,
MASTER_USER='renxj',
MASTER_PASSWORD='Sanchuang123#',
MASTER_PORT=3306,
master_auto_position=1;
root@(none) 17:19 mysql>start slave;
Query OK, 0 rows affected (0.01 sec)
slave1从slave3上拿二进制日志,避免太多机器从master上拿日志,master过于繁忙,并且设置延迟备份10分钟,这里就设置为10s,方便查看
root@(none) 11:22 mysql>INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
root@(none) 11:19 scmysql>CHANGE MASTER TO MASTER_HOST='192.168.159.133' ,
MASTER_USER='renxj',
MASTER_PASSWORD='Sanchuang123#',
MASTER_PORT=3306,
master_auto_position=1;
root@(none) 16:37 mysql>CHANGE MASTER TO MASTER_DELAY = 10; #延迟10秒
root@(none) 17:19 mysql>start slave;
Query OK, 0 rows affected (0.01 sec)
所有服务器刷新服务
service mysqld restart
验证效果master执行sql语句,slave2,slave3同步执行,slave1延迟10s执行
验证GTID的半同步主从复制
在master上操作
root@(none) 16:37 mysql>create database tanxue;
Query OK, 1 row affected (0.03 sec)
root@(none) 16:37 mysql>use tanxue;
Database changed
root@tanxue 16:38 mysql>create table t1(id int);
Query OK, 0 rows affected (0.02 sec)
root@tanxue 16:38 mysql>insert into t1(id) values(1),(2);
Query OK, 2 rows affected (0.10 sec)
Records: 2 Duplicates: 0 Warnings: 0
在slave上操作,验证
root@(none) 17:25 mysql>use tanxue;
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
root@tanxue 17:27 mysql>show tables;
+------------------+
| Tables_in_tanxue |
+------------------+
| t1 |
+------------------+
1 row in set (0.00 sec)
root@tanxue 17:27 mysql>select * from t1;
+------+
| id |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.00 sec)
在slave1上配置
1、关闭 selinux #永久关闭linux防火墙
[root@sc-mysql2 backup]# getenforce
Permissive
[root@sc-mysql2 backup]# vim /etc/selinux/config
SELINUX=disabled
2、关闭防火墙
[root@sc-mysql2 backup]# service firewalld stop
Redirecting to /bin/systemctl stop firewalld.service
3.安装rsync
yum install rsync xinetd -y
4.
[root@sc-mysql2 backup]# vi /etc/rc.d/rc.local # #设置开机启动
/usr/bin/rsync --daemon --config=/etc/rsyncd.conf # 添加开机启动
[root@sc-mysql2 backup]# chmod +x /etc/rc.d/rc.local
[root@sc-mysql2 backup]# systemctl start xinetd #启动xinetd
xinetd是一个提供保姆服务的进程,rsync是它照顾的进程
独立的服务:ssh,dhcp,mysql
非独立的服务,非独立的服务需要依赖其他的服务来管理,rsync就是一个非独立的服务,依赖xinetd来管理
5.创建rsyncd.conf配置文件
[root@sc-mysql2 backup]# 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.159.131 #允许的ip地址(数据源服务器地址)
6.创建用户认证文件
vi /etc/rsync.pass # 配置文件,添加以下内容,添加允许传输用户和密码
# 格式,用户名:密码,可以设置多个,每行一个用户名:密码
sc:sc123456
7.设置文件权限
chmod 600 /etc/rsyncd.conf #设置文件所有者读取、写入权限
chmod 600 /etc/rsync.pass #设置文件所有者读取、写入权限
8.启动rsync和xinetd
[root@sc-mysql2 backup]# /usr/bin/rsync --daemon --config=/etc/rsyncd.conf
[root@web3 mysql]# ps aux|grep rsync
root 745 0.0 0.0 114852 576 ? Ss 19:46 0:00 /usr/bin/rsync --daemon --config=/etc/rsyncd.conf
root 812 0.0 0.0 112824 980 pts/1 S+ 19:47 0:00 grep --color=auto rsync
[root@web3 mysql]# systemctl start xinetd
[root@web3 mysql]# ps aux|grep xinetd
root 962 0.0 0.0 25044 588 ? Ss 19:47 0:00 /usr/sbin/xinetd -stayalive -pidfile /var/run/xinetd.pid
root 993 0.0 0.0 112824 980 pts/1 R+ 19:47 0:00 grep --color=auto xinetd
netstat -anplut
tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 745/rsync
在数据源master服务器上
(1)安装rsync客户端软件
1、关闭 selinux #永久关闭linux防火墙
[root@sc-mysql2 backup]# getenforce
Permissive
[root@sc-mysql2 backup]# vim /etc/selinux/config
SELINUX=disabled
2、关闭防火墙
[root@sc-mysql2 backup]# service firewalld stop
Redirecting to /bin/systemctl stop firewalld.service
3、安装rsync服务端软件
[root@sc-mysql2 backup]# yum install rsync xinetd -y
[root@sc-mysql2 backup]# vi /etc/rc.d/rc.local # #设置开机启动
/usr/bin/rsync --daemon --config=/etc/rsyncd.conf # 添加开机启动
[root@sc-mysql2 backup]# chmod +x /etc/rc.d/rc.local
[root@sc-mysql2 backup]# systemctl start xinetd #启动xinetd
2.修改配置文件
[root@sc-mysql backup]# 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
systemctl start xinetd #启动(CentOS中是以xinetd来管理rsync服务的)
4、创建认证密码文件
[root@sc-mysql backup]# vim /etc/passwd.txt
只存放密码,与备份服务器中一致
[root@web1 .ssh]# cat /etc/passwd.txt
sc123456
[root@sc-mysql backup]# chmod 600 /etc/passwd.txt #设置文件权限,只设置文件所有者具有读取、写入权限即可
5、测试数据同步
数据源服务器192.168.159.131 到备份服务器192.168.159.136之间的数据同步
$ rsync -avH --port=873 --progress --delete /var/www/data(要备份的数据源目录 ) root@***.***.***.222::back_data(rsyncd.conf文件配置名称) --password-file=/etc/passwd.txt
rsync -avH --port=873 --progress --delete /backup [email protected]::back_data(rsyncd.conf文件配置名称) --password-file=/etc/passwd.txt
将本机的/backup 目录同步到备份机器
[root@web1 backup]# rsync -avH --port=873 --progress --delete /backup [email protected]::back_data --password-file=/etc/passwd.txt
sending incremental file list
backup/
backup/check_pwd.sh
204 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=2/4)
backup/passwd
1,559 100% 190.31kB/s 0:00:00 (xfr#2, to-chk=1/4)
backup/qiuchao.sql
1,999 100% 244.02kB/s 0:00:00 (xfr#3, to-chk=0/4)
sent 4,035 bytes received 77 bytes 8,224.00 bytes/sec
total size is 3,762 speedup is 0.91
到此实现了手工同步,还没实现自动同步
安装sersync工具,实时触发rsync进行同步 --》安装到数据源服务器上
备注:Linux下支持inotify的内核最小为2.6.13,可以输入命令:#uname -a查看内核
CentOS 7.0内核为3.10.0,默认已经支持inotify
inotify已经默认在内核里安装了,不需要安装
[root@web1 ~]# sysctl -w fs.inotify.max_queued_events="99999999"
fs.inotify.max_queued_events = 99999999
[root@web1 ~]# sysctl -w fs.inotify.max_user_watches="99999999"
fs.inotify.max_user_watches = 99999999
[root@web1 ~]# sysctl -w fs.inotify.max_user_instances="65535"
fs.inotify.max_user_instances = 65535
[root@web1 ~]# vim /etc/sysctl.conf
添加下面三行
fs.inotify.max_queued_events=99999999
fs.inotify.max_user_watches=99999999
fs.inotify.max_user_instances=65535
下载sersync
wget http://down.whsir.com/downloads/sersync2.5.4_64bit_binary_stable_final.tar.gz
[root@web1 ~]# tar xf sersync2.5.4_64bit_binary_stable_final.tar.gz
[root@web1 ~]# mv GNU-Linux-x86/ /usr/local/sersync
[root@web1 ~]# cd /usr/local/sersync/
[root@web1 sersync]# ls
confxml.xml sersync2
备份配置文件,防止修改错了,不知道哪里出错,好还原
[root@sc-mysql sersync]# cp confxml.xml confxml.xml.bak
[root@sc-mysql sersync]# cp confxml.xml data_configxml.xml
[root@sc-mysql sersync]# ls
confxml.xml confxml.xml.bak data_configxml.xml sersync2
data_configxml.xml 是后面需要使用的配置文件
4、修改配置 data_configxml.xml 文件
第24行后的配置
启动服务
PATH=/usr/local/sersync/:$PATH
echo 'PATH=/usr/local/sersync/:$PATH' >>/root/.bashrc
[root@web1 sersync]# sersync2 -d -r -o /usr/local/sersync/data_configxml.xml
6、设置sersync监控开机自动执行
[root@sc-mysql backup]# vim /etc/rc.local
/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/data_configxml.xml
验证效果
在数据源服务器上
[root@master backup]# cp /etc/my.cnf .、
[root@slave1 backup]#ls
my.conf
下载mysql - router,两台mysqlrouter进行如下配置
https://dev.mysql.com/get/Downloads/MySQL-Router/mysql-router-community-8.0.21-1.el7.x86_64.rpm
rpm -ivh mysql-router-community-8.0.21-1.el7.x86_64.rpm
进入存放配置文件的目录
[root@prometheus ~]# cd /etc/mysqlrouter/
[root@prometheus mysqlrouter]# ls
mysqlrouter.conf
修改mysqlrouter配置文件
[DEFAULT]
logging_folder = /var/log/mysqlrouter
runtime_folder = /var/run/mysqlrouter
config_folder = /etc/mysqlrouter
[logger]
level = INFO
[keepalive]
interval = 60
#实现read
[routing:slaves]
#mysqlrouter的ip地址
bind_address = 0.0.0.0:7001
destinations = 192.168.159.132:3306,192.168.159.133:3306
mode = read-only
connect_timeout = 1
#实现read ,write
[routing:masters]
#mysqlrputer的ip地址
bind_address = 0.0.0.0:7002
destinations = 192.168.159.131:3306
mode = read-write
connect_timeout = 1
在master上创建对应的授权用户,一个只有读权限,一个有读写权限,在mysqlrouter服务器上启动,7001端口为只读,7002端口读写
grant all on *.* to 'write'@'%' identified by 'Sanchuang123#';
grant select on *.* to 'scread'@'%' identified by 'Sanchuang123#';
启动mysql rputer服务
service mysqlrouter start
发现mysqlrputer监听7001 7002端口
[root@prometheus mysqlrouter]# netstat -anplut|grep mysql
tcp 0 0 0.0.0.0:7001 0.0.0.0:* LISTEN 16609/mysqlrouter
tcp 0 0 0.0.0.0:7002 0.0.0.0:* LISTEN 16609/mysqlrouter
在任意一台装有mysql的服务器上测试效果,使用创建的用户,登录mysqlrouter的不同端口
在客户端上测试读写分离的效果,使用2个测试账号,在一台别的机器上访问mysqlrouter的7001和7002端口,使用授予不同权限的账户
#实现读功能
[root@node1 ~]# mysql -h 192.168.159.137 -P 7001 -uscread -p'Sanchuang123#'
#实现写功能
[root@node1 ~]# mysql -h 192.168.159.137 -P 7002 -uwrite -p'Sanchuang123#'
安装keepalived软件,在2台MySQLrouter上都安装
yum install keepalived -y
[root@harbor keepalived]# cat 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 63
priority 200
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.159.188
}
}
[root@prometheus keepalived]# cat 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 63
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.159.188
}
}
两台mysqlrouter的vip为192.168.159.188,最终测试的结果应该为使用不同用户登录ip为192.168.159.188接不同的端口号实现读写分离的mysql集群
读用户
读写用户