mysql双主双从、负载均衡方案

 

一、方案架构

1、主库A和主库B互为主从,互相复制。从库A复制主库A的数据,从库B复制主库B的数据。

2、使用nginx做数据库负载均衡。keepAlived用于nginx故障转移,实现nginx的高可用。

二、主从复制原理

数据库有个bin-log二进制文件,记录了所有sql语句,把主数据库的bin-log文件中的sql语句复制过来,将这些sql语句写入从数据库的relay-log文件中并执行这些sql语句

1.  Slave开启slave服务后,slave会与master建立tcp长连接
2.  Master执行sql语句时,会按照事件的数据格式(event)写入bin-log
3.  Master启动一个Binlog dump thread线程,负责监听bin-log的改变,并将改变通知给Slave
4.  Slave启动一个IO thread与Master一直保持通信,收到通知后,发送需要的bin-log位置给Master,Master返回日志内容和下次的更新位置
5.  IO thread将收到的bin-log追加到本地relay-log的末尾,位置信息持久化到master.info中,供下次请求调用
6.  Slave启动一个SQL thread读取relay-log,重现在Master中执行的sql,实现与Master同步

三、双主双从架构

双主双从:主库A和主库B互为主从,互相复制。从库A复制主库A的数据,从库B复制主库B的数据。

三、双主双从搭建
1、环境说明

  数据库 IP 端口  数据库版本
主库A 192.169.1.85 3306 mysql8.0
主库B 192.169.1.86 3306 mysql8.0
从库A 192.169.1.71 3306 mysql8.0
从库B 192.169.1.70 3306 mysql8.0



2、搭建步骤
注意:
1、先搭建好主从环境再在主库中执行需要同步的脚本,这里有两个主库,只需要在其中一个主库中执行脚本!!!
2、如果要设置数据库忽略大小写,请在初始化数据库前设置!!!
原因请参阅:http://blog.sina.com.cn/s/blog_47642c6e0102yega.html
3、以下步骤中的sql语句在客户端中操作无效,请直接在linux中登录数据库操作!!!

a、编辑数据库配置文件/etc/my.cnf
在主库A的[mysqld]下添加(不存在则添加,存在则修改)

server-id=1
log_bin=mysql-bin
binlog_format=mixed
log_bin_trust_function_creators=1
expire_logs_days=30
auto_increment_increment=4
auto_increment_offset=1
sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
lower_case_table_names=1
1
2
3
4
5
6
7
8
9
编辑完后保存
sql_mode和lower_case_table_names请根据项目实际情况配置

在主库B的[mysqld]下添加(不存在则添加,存在则修改)

server-id=2
log_bin=mysql-bin
binlog_format=mixed
log_bin_trust_function_creators=1
expire_logs_days=30
auto_increment_increment=4
auto_increment_offset=2
sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
lower_case_table_names=1
1
2
3
4
5
6
7
8
9
编辑完后保存
sql_mode和lower_case_table_names请根据项目实际情况配置

在从库A的[mysqld]下添加(不存在则添加,存在则修改)

server-id=3
log_bin_trust_function_creators=1
auto_increment_increment=4
auto_increment_offset=3
sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
lower_case_table_names=1
1
2
3
4
5
6
编辑完后保存
如果从库默认开启了log_bin和binlog_format,将其注释掉。
sql_mode和lower_case_table_names请根据项目实际情况配置

在从库B的[mysqld]下添加(不存在则添加,存在则修改)

server-id=4
log_bin_trust_function_creators=1
auto_increment_increment=4
auto_increment_offset=4
sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
lower_case_table_names=1
1
2
3
4
5
6
编辑完后保存
如果从库默认开启了log_bin和binlog_format,将其注释掉。
sql_mode和lower_case_table_names请根据项目实际情况配置

配置项说明:

参数 作用
server-id=111 服务器id,任意配置,要求四个数据库间保持唯一
log-bin=mysql-bin 将mysql二进制日志取名为mysql-bin
binlog_format=mixed 二进制日志的格式,有三种:statement/row/mixed
log_bin_trust_function_creators=1 当二进制日志启用后,就要启用这个变量。它控制是否可以信任存储函数创建者,不会创建写入二进制日志引起不安全事件的存储函数。如果设置为0(默认值),用户不得创建或修改存储函数,除非它们具有除CREATE ROUTINE或ALTER ROUTINE特权之外的SUPER权限,如果开启了主从复制,
那么这个变量必须配置为1
expire_logs_days=30 mysql二进制日志过期时间,过期自动清理
auto_increment_increment=4 表示自增长字段每次递增的量,其默认值是1,取值范围是1 … 65535
auto_increment_offset=1 表示自增长字段从那个数开始,他的取值范围是1 … 65535,配置auto_increment_increment和auto_increment_offset是为了避免同时操作主从数据库导致主键冲突
sql_mode =STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION STRICT_TRANS_TABLES:(在该模式下,如果一个值不能插入到一个事务表中,则中断当前的操作,对非事务表不做限制)。NO_ENGINE_SUBSTITUTION:(如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常)详情参阅:http://xstarcd.github.io/wiki/MySQL/MySQL-sql-mode.html
lower_case_table_names 忽略大小写
b、创建用于主从复制的账号
在主库A和主库B中执行以下语句,创建用于主从复制的账号(用户名和密码自定义,我这里是repl和123456)

CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
1
2
c、实现主库A和从库B复制主库B的数据
(实现该图中红线部分)

在主库B中执行以下语句进行锁表操作,不让数据再进行写入动作。

flush tables with read lock;
1
查看主库B状态(记住File和Position的值,第3步要用到)

show master status;
1


在主库A和从库B中执行语句(这里的MASTER_HOST为主库B的ip,MASTER_USER,MASTER_PASSWORD为主库B建立的用于主从复制的账号和密码,MASTER_LOG_FILE,MASTER_LOG_POS为执行show master status时的File,Position的值)

CHANGE MASTER TO MASTER_HOST='192.169.1.86',MASTER_USER ='repl', MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000028',MASTER_LOG_POS=155;
1
在主库A和从库B开启从服务线程

start slave;
1
在主库A和从库B中查看数据库状态(都为yes说明主从复制成功)

show slave status\G;
1


在主库B中取消主数据库锁定

unlock tables;
1
d、实现主库B和从库A复制主库A的数据

(实现该图中红线部分)

在主库A中执行以下语句进行锁表操作,不让数据再进行写入动作

flush tables with read lock;
1
查看主库A状态(记住File和Position的值,第3步要用到)

show master status;
1


在主库B和从库A中执行语句(这里的MASTER_HOST为主库A的ip,MASTER_USER,MASTER_PASSWORD为主库A建立的用于主从复制的账号和密码,MASTER_LOG_FILE,MASTER_LOG_POS为执行show master status时的File,Position的值)

CHANGE MASTER TO MASTER_HOST='192.169.1.85',MASTER_USER ='repl', MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000026',MASTER_LOG_POS=155;
1
在主库B和从库A开启从服务线程

start slave;
1
在主库B和从库A中查看数据库状态(都为yes说明主从复制成功)

show slave status\G;
1
在主库A中取消主数据库锁定

unlock tables;
1
至此,双主双从环境搭好了!

五、负载均衡和高可用架构
使用nginx做数据库负载均衡。keepAlived用于nginx故障转移,实现nginx的高可用。


六、负载均衡和高可用搭建
1、环境说明
Nginx ip 版本 其他
Nginx1 192.169.1.71 1.9.6
Nginx1 192.169.1.70 1.9.6
keepAlived ip 虚拟ip 版本
keepAlived1 192.169.1.71 192.169.1.23 2.0.18
keepAlived2 192.169.1.70 192.169.1.23 2.0.18
2、搭建步骤
a、安装配置nginx
安装nginx之前需要安装openssl和pcre

1.安装openssl
将安装包openssl-1.0.1h.tar.gz上传到/usr/local目录
依次执行如下命令配置、编译和安装openssl
#cd /usr/local
#tar xzvf openssl-1.0.1h.tar.gz
#cd openssl-1.0.1h
#./config --prefix=/usr/local/openssl --openssldir=/usr/local/openssl-1.0.1h
#make
#make install
参数解释:
–prefix=/usr/local/openssl //指定openssl的安装目录–openssldir=/usr/local/openssl-1.0.1h //指的是tar解压后openssl的源码路径

检查安装是否成功,使用命令openssl version 查看openssl是否为最新的版本。

注意:如果查询到的版本号不是openSSL 1.0.1h,那是因为旧版本的openssl路径加载到了系统路径下了,解决的方案如下

#which openssl //查看系统openssl的路径,记录下来,下面会用到

#rm -rf /usr/bin/openssl // usr/bin/openssl代表which openssl 查看到的旧版本的openssl的路径

#cp /usr/local/openssl/bin/openssl /usr/bin/openssl //拷贝新版本的安装路径到系统路径

执行完后输入openssl version 如图所示表示成功读取密码库:


2.安装pcre
将安装包pcre-8.34.tar.gz上传到/usr/local目录
依次执行以下命令安装pcre
#cd /usr/local
#tar xzvf pcre-8.34.tar.gz
#cd pcre-8.34
#./configure --prefix=/usr/local/pcre
#make
#make install
参数解释:
–prefix=/usr/local/pcre //指定pcre的安装目录

3.安装nginx
在安装nginx前必须要确保安装了pcre-8.34和openssl-1.0.1h

将安装包nginx-1.9.6.tar.gz上传到/usr/local目录
依次执行以下命令安装nginx
#cd /usr/local
#tar xzvf nginx-1.9.6.tar.gz
#cd nginx-1.9.6
#./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-openssl=/usr/local/openssl-1.0.1h --with-pcre=/usr/local/pcre-8.34 --with-http_realip_module
–with-stream
#make
#make install
参数介绍:
–prefix=/usr/local/nginx 指定nginx的安装目录
–with-http_stub_status_module 使ngx_stub_status_modul 模块可用
–with-http_ssl_module 使用https协议模块
–with-openssl=/usr/local/openssl-1.0.1h 读取openssl库的源码路径
–with-pcre=/usr/local/pcre-8.34 读取pcre库的源码路径
–with-stream 指定安装stream模块

4.配置nginx
在配置文件/usr/local/nginx/conf/nginx.conf中新增如下配置:

stream {

upstream mysql {
#mysql-router连接地址,这里配置mysql主库的ip和端口
server 192.169.1.85:3306 weight=10; #指定轮询几率,weight和访问比率成正比
server 192.169.1.86:3306 weight=10; #指定轮询几率,weight和访问比率成正比
}

server {
#监听端口
listen 6688;
#建立连接超时时间
proxy_connect_timeout 5s;
#proxy_timeout指定Nginx与客户端,以及Nginx与被代理的主机之间在两个相邻的读或写数据的操作之间的最大时间间隔。超过此时间间隔而没有数据读或写操作发生,则断开连接。
proxy_timeout 36000s;
#设置代理地址,地址和upstream名字一样
proxy_pass mysql;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19


5.启动nginx
根据Nginx的安装路径,使用命令/usr/local/nginx/sbin/nginx 启动Nginx服务
启动后使用数据库客户端测试一下,是否代理成功


b、安装配置keepalived
1.安装keepalived
安装keepalived之前需要安装 openssl。如未安装,请参考上面nginx安装配置中的安装openssl的步骤

安装openssl-devel,(这里是在线安装,离线安装请参考:https://blog.csdn.net/afreon/article/details/77866695)

yum -y install openssl-devel

安装keepalived
1.将安装包keepalived-2.0.18.tar.gz上传到/usr/local目录
2.依次执行以下命令安装keepalived
#cd /usr/local
#tar -zxvf keepalived-2.0.18.tar.gz
#cd keepalived-2.0.18
#./configure --prefix=/usr/local/keepalived
#make
#make install
3.复制到默认路径
#mkdir /etc/keepalived
#cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived
#cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
#cp /usr/local/keepalived/sbin/keepalived /usr/sbin/

2.监听Nginx脚本
准备一个shell脚本,用于检查nginx是否存活。脚本逻辑为判断nginx进程是否存活,如果挂了则尝试重启。如果重启不成功,则停止keepalived服务来切换虚拟IP。
check_nginx.sh脚本内容为:

#! /bin/bash
#日志文件位置
V_LOG="/etc/keepalived/log/keepalived.log"

#日志所属目录
LOG_DIR=${V_LOG%/*}

#启动nginx命令
START_NGINX="/usr/local/nginx/sbin/nginx"


function restart_nginx(){
#如果日志目录不存在,则创建
if [ ! -d "$LOG_DIR" ];then
mkdir $LOG_DIR
fi

#如果日志文件不存在,则创建
if [ ! -f "$V_LOG" ];then
touch $V_LOG
fi

#记录日期
echo "-----`date`-----">>$V_LOG
#查看nginx进程
echo "----ps aux | grep nginx-----">>$V_LOG
echo "`ps aux | grep 'nginx'`">>$V_LOG
#启动nginx服务
echo "----------restart nginx----------">>$V_LOG
$START_NGINX>>$V_LOG
#查看nginx进程
echo "----ps aux | grep nginx-----">>$V_LOG
echo "`ps aux | grep 'nginx'`">>$V_LOG

}

#nginx进程数量
STATE=`ps -C nginx --no-header | wc -l`
if [ $STATE -eq 0 ]; then
#重启nginx
restart_nginx
#休眠1s
sleep 1
STATE=`ps -C nginx --no-header | wc -l`
if [ $STATE -eq 0 ]; then
systemctl stop keepalived
fi
fi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
给脚本授予权限

chmod +775 check_nginx.sh
1
脚本编辑完成后可以手动执行一下脚本,看看是否生效

3.配置Keepalived
1、配置Keepalived1的配置文件(/etc/keepalived/keepalived.conf)内容为(只要配置红色区域,其他默认)


配置keepalived2的配置文件(/etc/keepalived/keepalived.conf)内容为(只要配置红色区域,其他默认)


说明:

keepalived1和keepalived2配置的区别为:
a.keepalived1的state为MASTER,keepalived2的state为BACKUP,
b.state起一个标识作用,真正控制节点角色的是“priority”值,所以初始配置Master的priority较高,Slave的priority较低

interface配置为网卡名称,通过命令ip a查看本机网卡名称

虚拟IP要与本机IP在同一个网段中,且此虚拟IP无机器使用,ping不通即可

4.启动KeepAlived
输入命令systemctl start keepalived启动服务,首次执行这个命令可能会出现警告:

Warning: keepalived.service changed on disk. Run 'systemctl daemon-reload' to reload units.
1
解决方法:先执行systemctl daemon-reload,再执行systemctl start keepalived。

服务启动后,使用命令ip a查看ip信息,可以看到MASTER机器获取到了虚拟IP


4.故障邮件通知
当nginx发送故障,keepalived切换状态时,可以通过邮件通知到客户,让客户及时知晓。
1、安装mailx,这里是在线安装(未找到离线安装包)

yum install mailx
1
2、打开/etc/mail.rc文件,新增红色区域配置

注意:邮箱授权码不是邮箱登录密码,请自行上网搜索如何开启邮箱授权码

3、编辑发送邮件脚本
notify.sh脚本内容为

#!/bin/bash
#接收者邮箱,多个以空格分隔
contact=([email protected] [email protected] [email protected])
#本机ip
HOST_IP=192.169.1.71
notify() {
mailsubject="vip转移,$HOST_IP keepalived to be $1"
mailbody="$(date +'%F %T'): vrrp transition, $HOST_IP keepalived changed to be $1"
for receiver in ${contact[*]}
do
echo "$mailbody" | mail -s "$mailsubject" $receiver
done
}
case $1 in
master)
notify master
;;
backup)
notify backup
;;
fault)
notify fault
;;
*)
echo "Usage: {master|backup|fault}"
exit 1
;;
esac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
授予脚本权限

chmod +775 notify.sh
1
脚本执行完后可以通过命令./notify.sh master执行脚本,测试下是否可以发送邮件
如果出现错误:缺少依赖libmysqlclient.so.18
请参考:https://blog.csdn.net/m0_38102561/article/details/100698011

5、keepalived配置邮件通知脚本
在keepalived.conf中vrrp_instance_VI_1中新增以下配置

#当前节点成为主节点时触发的脚本
notify_master "/etc/keepalived/notify.sh master"
#当前节点转为备节点时触发的脚本
notify_backup "/etc/keepalived/notify.sh backup"
#当前节点转为失败状态时触发的脚本
notify_fault "/etc/keepalived/notify.sh fault"
1
2
3
4
5
6


参考地址:
1.keepalived安装: https://blog.csdn.net/gzhouc/article/details/78169690
2.keepalived之vrrp_script详解:https://www.cnblogs.com/arjenlee/p/9258188.html
3.监控Nginx服务的Shell脚本:https://blog.csdn.net/qq_25600055/article/details/80649212
————————————————
版权声明:本文为CSDN博主「我是小念」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_38102561/article/details/100692375

猜你喜欢

转载自www.cnblogs.com/kiko2014551511/p/11527625.html