欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MYSQL 主主热备高可用方案与实现 博客分类: mysql  

程序员文章站 2024-03-13 14:12:09
...

我们选择主主互热备做生产环境MYSQL高可用方案,该方案的优点是在压力大的时候,仍然可以通过设置负载均衡来做业务分发。而且最重要的是配置简单,两份配置都一样,改个IP就可以MYSQL 主主热备高可用方案与实现
            
    
    博客分类: mysql  就喜欢简单的东西。

 

目前考虑负债均衡分发可能有同步过程中引起数据不一致的问题,我们使用主主机制做数据即时同步,用KeepAliveD做数据库监控及故障自动切换。

 

实现:

 

1.数据库主从设置:

 

MYSQL安装完成后,mysql的配置修改为:

 

写道
[mysqld]
datadir=/usr/local/mysql/data
socket=/var/lib/mysql/mysql.sock
max_connection=1000
log-bin=mysql-bin

server-id=2
//这块两台服务器需要设置成不同

binlog-do-db=CU
binlog-do-db=FAE
binlog-do-db=HA
//它是用于主从同步时,给master用的配置参数。来说明需要复制那些库给从库。因为有时主从不是要把全部的DB都复制给从库。

binlog-ignore-db=mysql
//安全起见,无论如何不从主同步系统DB

replicate-do-db=CU
replicate-do-db=FAE
replicate-do-db=HA
//从主读取的库

replicate-ignore-db=mysql
//安全起见,无论如何不从主同步系统DB


log-slave-updates
#slave-skip-errors=all
#auto_increment_increment=2
#auto_increment_offset=2
//不是用负载均衡模式,用的是主主模式,所以这块不需要设置


[mysql.server]
user=mysql
basedir=/usr/local/mysql

[client]
socket=/var/lib/mysql/mysql.sock


 

配置好之后,在两台机器上分别给从建立账号,登录两台Mysql,执行以下语句:

写道
CHANGE MASTER TO
MASTER_HOST='192.***.***.***',
MASTER_USER='repl_user',
MASTER_PASSWORD='hj3****’;

 

 注意的一点就是,使用sqlyog,一定要使用12.09以上的版本,否者主从同步会出现脏数据,因为sqlyog的老版本在修改数据库的时候,某些时候不会产生binlog,导致这些修改数据不会同步。

 

 

2.故障检测和主从切换。

 

我们使用keepalived和shell脚本搞定。

原理:两台数据库服务器上同时部署Keepalived。Keepalived所有节点会互相通信,互报平安。一旦抢到主的机器的Keepalived没有心跳了,从机器的Keepalived会把主的IP抢过来。Keepalived会定期调用shell脚本检测本机mysql是否可用。一旦本机mysq不可用,Keepalived会通知其他机器的Keepalived抢主的IP来实现故障切换。

 

Keepalived的配置:

 

 

写道
! Configuration File for keepalived

#Keepalived组的名称,各个组之间互相不影响
global_defs {
router_id cu_ha_router
}

#检测MYSQL的实例
vrrp_instance mysql {
state BACKUP # 主也配置为SLAVE
interface eth0 #绑定虚拟IP的网络接口
virtual_router_id 101 #VRRP组名,两个节点的设置必须一样,以指明各个节点属于同一VRRP组
priority 150 #节点的优先级(1-254之间),备用节点必须比主节点优先级低
nopreempt # 不抢占,注意加上
advert_int 1 #组播信息发送间隔,两个节点设置必须一样
authentication { #设置验证信息,两个节点必须一致
auth_type PASS 
auth_pass xmotor
}

#一定要注意这块子网掩码的计算,写错了可能会影响整台的网络访问
virtual_ipaddress { 
172.*.*.201/20
}
track_script { 
chk_mysql


#我们使用的是亚马逊云,不能使用组播模式(advertisement),所以必须使用单播模式。单播模式需要增加以下配置。我们做过测试,单播模式支持三台或以上的机器。
unicast_src_ip 172.31.2.1 #localIp
unicast_peer {
172.31.2.124 #Resource-02
#172.31.0.207 #Management
}

#以下四个脚本分别在机器变成主、从、失败、宕机的时候执行的脚本,目前我们只记录一条日志
notify_master "/home/keepalived/scripts/mysql_be_master.sh"
notify_backup "/home/keepalived/scripts/mysql_be_slave.sh"
notify_fault "/home/keepalived/scripts/mysql_fault.sh"
notify_stop "/home/keepalived/scripts/mysql_stop.sh"
}

#检测MYSQL函数
vrrp_script chk_mysql
{
script "/home/keepalived/scripts/mysql_chk.sh eth0 root root"
interval 2
timeout 2
fall 3
}

vrrp_script chk_redis
{
script "/home/keepalived/scripts/redis_check.sh 6391 eth0"
interval 2
timeout 2
fall 3
}

vrrp_script chk_mongo
{
script "/home/keepalived/scripts/mongo_chk.sh eth0"
interval 2
timeout 2
fall 3
}


vrrp_instance redis {
state BACKUP
interface eth0 #绑定虚拟IP的网络接口
virtual_router_id 102 #VRRP组名,两个节点的设置必须一样,以指明各个节点属于同一VRRP组
priority 100 #节点的优先级(1-254之间),备用节点必须比主节点优先级低
advert_int 1 #组播信息发送间隔,两个节点设置必须一样
authentication { #设置验证信息,两个节点必须一致
auth_type PASS
auth_pass xmotor
}
virtual_ipaddress {
172.*.*.202/20
}
track_script {
chk_redis
}
unicast_src_ip 172.*.*.1 #localIp
unicast_peer {
172.*.*.124 #Resource-02
#172.*.*.207 #Management
}

notify_master "/home/keepalived/scripts/redis_be_master.sh 6391"
notify_backup "/home/keepalived/scripts/redis_be_slave.sh 172.*.*.* 6391"
notify_fault "/home/keepalived/scripts/redis_fault.sh 6391"
notify_stop "/home/keepalived/scripts/redis_stop.sh 6391"
}

vrrp_instance mongodb {
state BACKUP
interface eth0 #绑定虚拟IP的网络接口
virtual_router_id 103 #VRRP组名,两个节点的设置必须一样,以指明各个节点属于同一VRRP组
priority 100 #节点的优先级(1-254之间),备用节点必须比主节点优先级低
advert_int 1 #组播信息发送间隔,两个节点设置必须一样
authentication { #设置验证信息,两个节点必须一致
auth_type PASS
auth_pass xmotor
}

unicast_src_ip 172.*.*.1 #localIp

unicast_peer {
172.*.*.124 #Resource-02
#172.*.*.207 #Management
}

virtual_ipaddress {
172.*.*.203/20
}

track_script {
chk_mongo
}

notify_master "/home/keepalived/scripts/mongo_be_master.sh"
notify_backup "/home/keepalived/scripts/mongo_be_slave.sh"
notify_fault "/home/keepalived/scripts/mongo_fault.sh"
notify_stop "/home/keepalived/scripts/mongo_stop.sh"
}

 

下面是检测mysql的脚本,可用返回0,不可用返回1。

 

写道
#!/bin/bash
#define mysql variable

NETBOARD=$1
MYSQL_USER=$2
MYSQL_PWD=$3
LOGFILE="/var/log/keepalived/mysql/mysql-check.log"


# 看3306端口是否开这
mysql_alive=`netstat -nl | awk 'NR>2{if ($4 ~ /.*:3306/) {print "Yes";exit 0}}'`

#记录日志
echo "[CHECK]" >> $LOGFILE
date >> $LOGFILE

# 取出网关的IP地址
gate=`route -n | grep $NETBOARD | grep UG | awk '{print $2}'`

# 查看网关是否通畅
ping -w 1 -c 1 $gate >/dev/null
ret=$?

#连不上网关,记录日志,返回1
if [ $ret != 0 ];then
echo "Network Gate is not connected" >> $LOGFILE 2>&1
exit 1
fi

Slave_IO_Running=""
Slave_SQL_Running=""

# 如果MYSQL端口是通的,登录mysql,执行mysql语句,检查mysql状态
if [ "$mysql_alive" == "Yes" ];then
Slave_IO_Running=`mysql -u${MYSQL_USER} -p${MYSQL_PWD} -e"show slave status\G" | grep "Slave_IO_Running:" | awk '{print $2}'`
Slave_SQL_Running=`mysql -u${MYSQL_USER} -p${MYSQL_PWD} -e"show slave status\G" | grep "Slave_SQL_Running:" | awk '{print $2}'`
if [ "$Slave_IO_Running" != "" -a "$Slave_SQL_Running" != "" ];then
echo "Success, Slave_IO_Running = $Slave_IO_Running, Slave_SQL_Running = $Slave_SQL_Running" >> $LOGFILE 2>&1
exit 0
else
mysql -u${MYSQL_USER} -p${MYSQL_PWD} -e"show slave status\G"
getSlaveStatusResult=$?
echo "Failed, Reason: $getSlaveStatusResult" >> $LOGFILE 2>&1
exit 1
fi
else
echo "Mysql Down" >> $LOGFILE 2>&1
exit 1
fi