说明:蓝色=命令名称

      浅绿=命令参数

浅蓝=选项

 紫色=目录

CentOS  5.7  x86_64

一、所需准备mysql-master :192.168.1.71 
mysql-slave  :192.168.1.70
mysql版本均为:5.5.21
keepalive 版本:1.1.5
vip:192.168.1.60

二、方案介绍

两台mysql互为主从,但只有master写,slave只负责读。主从通过keepalive做成高可用,当master出问题,由slave接替master工作,即读写都在slave操作。当master恢复正常,master自动同步故障时间段数据,接替slave的写工作。

三、双主配置

1、配置文件
master my.cnf

log_slave_updates
log-bin = mysql-bin
server-id = 1
binlog-ignore-db=mysql
#auto_increment_increment = 2
#auto_increment_offset = 2

 my.cnf 主要参数

log_slave_updates
log-bin = mysql-bin
server-id = 2
binlog-ignore-db=mysql
#auto_increment_increment = 2
#auto_increment_offset = 1

注:
log_slave_updates  同步数据时也写入日志,二进制记录id号,互为主从时时不会引起循环。建议开启方便实施日志恢复。 可选
slave-skip-errors  跳过错误,可以通过=指定特定的错误,如:slave-skip-errors=1062  可选
log-bin = mysql-bin 开启二进制日志,必须开启,主从同步主要是通过二进制日志。 必须
sync_binlog=n  设置二进制日志在写入多少此后与硬盘同步,1 为最安全的也是效率最低的,根据实际情况设定 可选
server-id  设置mysql的id号,主从不能相同。 必须
binlog-ignore-db 设置不写入日志的库,建议设置不需要的库,节省流量。如需设置多个库可加多个此参数  可选
binlog-do-db 设置写入二进制日志的库,如设置则只有设置的库才能写入二进制日志。如需设置多个库可加多个此参数。 可选
replicate-ignore-db 设置slave不同步的库,如需设置多个库可加多个此参数。 可选
replicate-do-db 设置slave同步的库,如需设置多个库可加多个此参数。 可选
auto_increment_increment  自增增长值,如:id 设置为 auto_increment,则每次插入数据自增值为2,以1,3,5...或2,4,6...方式增长。 可选
auto_increment_offset 自增初始化便宜值,如果前一个id 为2 则 下一个为3 然后在这个基础上按auto_increment_increment 设置的值进行自增。 可选
master-host = 192.168.1.2 设置master 服务器地址,也可以启动时通过change master to 设置 。 可选
master-user = repl 设置更新用的帐号,也可以启动时通过change master to 设置 。 可选
master-password = 123 设置跟新用的密码,也可以启动时通过change master to 设置 。 可选
master-port = 3306 设置master端口,也可以启动时通过change master to 设置 。 可选

binlog-do-db、binlog-ignore-db、replicate_do_db、replicate_ignore_db 在使用时应注意,若加了以上参数,则在操作数据库是要避免跨库操作(例:update test.table1 set...)
如设置 binlog-do-db=test
use mysql;
update test.table1 set ......
第二句会执行但不会写入二进制日志,即从库不能同步,主从数据库出现差异

binlog_ignore_db=mysql
use mysql;
update test.table1 set ......
第二句会执行但不会写入二进制日志,即从库不能同步,主从数据库出现差异

replicate_do_db=test
use mysql;
update test.table1 set ......
第二句将不会被执行,即从库不能同步,主从数据库出现差异

replicate_ignore_db=mysql
use mysql;
update test.table1 set ......
第二句会被忽略执行,即从库不能同步,主从数据库出现差异

原因是设置binlog-do-db、binlog-ignore-db、replicate_do_db或replicate_ignore_db后,MySQL执行sql前检查的是当前默认数据库,所以跨库更新语句被忽略。

2、安装准备

写好配置文件重启数据库
service mysqld restart

同步数据库
可通过 tcpdump


分别在master、slave上添加同步帐号
mysql>grant replication slave on *.* to zsz@'%' identified by 'zzzzzzz';

3、设置主从

show master status;


mysql druid_linux

在slave 执行:

mysql>change master to master_host='192.168.1.71',master_user='zsz', master_password='zzzzzzz',master_log_file='mysql-bin.000007',master_log_pos=107;

注:master_log_file='mysql-bin.000007',master_log_pos=107 为master status中对应的内容。

mysql> slave start
mysql> show slave status\G;


mysql druid_mysql_02

其中 Slave_IO_Running: Yes,Slave_SQL_Running: Yes 表示设置成功。

测试:
在slave执行:
mysql> show databases;


mysql druid_keepalive 单点故障 VRRP_03

在master建立测试库,并插入数据:
mysql>create database zsz;
mysql>use zsz;
mysql>create table zsz
(id int(5) not null auto_increment primary key,
name char(10) not null,
qqgroup int(10)
)type=innodb;

mysql>show databases;
mysql> show databases;


mysql druid_linux_04

在从库执行:

mysql > show databases;


mysql druid_优化_05


第一个为master建立数据库前,第二个为建立后。从图可以看出一切ok。

4、设置双主

mysql> show master status;


mysql druid_优化_06

在master执行:
mysql>change master to master_host='192.168.1.70',master_user='zsz', master_password='zzzzzzz',master_log_file='mysql-bin.000005',master_log_pos=107;

注:master_log_file='mysql-bin.000005',master_log_pos=107 为master status中对应的内容。

mysql> slave start

mysql> show slave status\G;

mysql druid_mysql druid_07

其中 Slave_IO_Running: Yes,Slave_SQL_Running: Yes 表示设置成功。


测试:


在master执行;


mysql> use zsz;

Database changed

mysql> select * from zsz;


Empty set (0.00 sec)

关闭master
service mysqld stop

在slave执行:

mysql> use zsz;

mysql> insert into zsz(name,qqgroup) values('秦汉唐宋元','31013074');

mysql> select * from zsz;

mysql druid_mysql druid_08


 

在master执行:

service mysqld start

mysql -uroot

mysql> use zsz;
mysql> select * from zsz;


mysql druid_linux_09

ok,一切成功。

三、keepalive高可用配置

1、keepalive安装

分别在master,slave上安装keepalive

cd /usr/local/src
wget http://www.keepalived.org/software/keepalived-1.1.5.tar.gz
tar zxvf keepalived-1.1.5.tar.gz
cd keepalived-1.1.5
./configure --prefix=/usr/local/keepalived

make
make install

[root@master ~]# cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/ 
[root@master ~]# cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/ 
[root@master ~]# mkdir /etc/keepalived/ 
[root@master ~]# cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/ 
[root@master ~]# cp /usr/local/keepalived/sbin/keepalived /usr/sbin/

分别在master,slave上新建检查脚本

vim /root/check_mysql.sh

内容如下

1. #!/bin/bash  
2. MYSQL=/usr/local/mysql-5.5.21/bin/mysql  
3. MYSQL_HOST=localhost
4. MYSQL_USER=root
5. MYSQL_PASSWORD=  
6. CHECK_TIME=3  
7. #mysql  is working MYSQL_OK is 1 , mysql down MYSQL_OK is 0  
8. MYSQL_OK=1
9. function check_mysql_health (){  
10. $MYSQL -h $MYSQL_HOST -u $MYSQL_USER -e "show status;" >/dev/null 2>&1  
11. if [ $? = 0 ] ;then  
12. MYSQL_OK=1
13. else  
14. MYSQL_OK=0
15. fi  
16.      return $MYSQL_OK  
17. }  
18. while [ $CHECK_TIME -ne 0 ]  
19. do  
20. -=1"  (王俊小提示这里我们采用的是let进行整数的运算当然您可以用expr,感觉let省去了$比较方便)
21.      check_mysql_health  
22. MYSQL_OK = 1
23. CHECK_TIME=0
24.           exit 0  
25.      fi  
26.  
27.      if [ $MYSQL_OK -eq 0 ] &&  [ $CHECK_TIME -eq 0 ]  
28.      then  
29.           /etc/init.d/keepalived stop  
30.      exit 1   
31.      fi  
32.      sleep 1  
33. done

chmod +x /root/check_mysql.sh

2、编写配置文件

vim /usr/local/keepalived/etc/keepalived/keepalived.conf

master配置内容:
###########################master##########################

! Configuration File for keepalived
 global_defs {
     router_id zsz
 }
 vrrp_script check_run {
     script "/root/check_mysql.sh"
     interval 5
 }
 vrrp_sync_group VG1 {
      group {
         VI_1
      }
 }
 vrrp_instance VI_1 {
      state MASTER
      interface eth0
      virtual_router_id 11
      priority 100
      advert_int 1
      nopreempt
      authentication {
          auth_type PASS
          auth_pass zzzzzzz
      }
      track_script {
          check_run
      }
      virtual_ipaddress {
          192.168.1.60 dev eth0 label eth0:0
      }
 }


##########################end##########################

slave配置内容:
#########################backup##########################

! Configuration File for keepalived
 global_defs {
     router_id zsz
 }
 vrrp_script check_run {
     script "/root/check_mysql.sh"
     interval 5
 }
 vrrp_sync_group VG1 {
      group {
        VI_1
      }
 }
 vrrp_instance VI_1 {
      state BACKUP
      interface eth0
      virtual_router_id 11
      priority 80
      advert_int 1
      authentication {
          auth_type PASS
          auth_pass zzzzzzz
      }
      track_script {
          check_run
      }
      virtual_ipaddress {
          192.168.1.60 dev eth0 label eth0:0
      }
 }


################end####################################


3、测试

在master上建立测试帐号:
mysql> grant all privileges on *.* to 'master'@'%' identified by 'zzzzzzz';
mysql> flush privileges;

在slave上建立测试帐号:
mysql> grant all privileges on *.* to 'slave'@'%' identified by 'zzzzzzz';
mysql> flush privileges;


分别启动master、slave的keepalived进程
service keepalived start

ifconfig

mysql druid_mysql_10


 

ifconfig


mysql druid_keepalive 单点故障 VRRP_11

用一台同网段的机器访问通过vip数据库:


mysql druid_keepalive 单点故障 VRRP_12

service mysqld stop

ifconfig

mysql druid_linux_13

ifconfig


mysql druid_mysql_14

用一台同网段的机器访问通过vip数据库:


mysql druid_mysql druid_15

通过此图可以看出此时反问的是slave(上文中master、slave帐号设置不同)

测试 成功。

接下来是一个实例进行说明他在生产中的实际应用

Keepalived双机热备

这里我们仅仅只利用Keepalive做双机热备,也就是保证服务器的高可用性,其他的不用管。可能您会说这样在实际应用中很少会这样用,这您可就错了,Keepalived仅仅做双机热备的情况还是有的,我就碰到过几次这样的案例,下面就我碰到的几个案例做个小结



一,Keepalived双机热备的应用场景



1,网站流量不高,压力不大,但是对服务器的可靠性要求极其高,例如实时在线OA系统,政府部门网站系统,医院实时报医系统,公安局在线报案系统,股市后台网站系统等等,他们的压力不是很大,但是对可靠性要求是非常高的



2,有钱没地方花的,典型的政府企业,公办学校等等



二,Keepalived双机热备的特性以及优缺点



特性:


1,至少需要两台服务器,其中一台为master始终提供服务,另外一台作为backup始终处于空闲状态,只有在主服务器挂掉的时候他就来帮忙了,这是典型的双击热备



2,能根据需求判断服务是否可用,在不可用的时候要即使切换


优缺点:



优点:数据同步非常简单,不像负载均衡对数据一致性要求非常高,实现起来相对复杂维护也颇为不便,双机热备用rsync就可以实现了操作和维护非常简单



缺点:服务器有点浪费,始终有一台处于空闲状态




三,Keepalived双机热备的配置


首先画个双机热备拓扑图吧:



这里我只写最终实现的配置,至于Keepalived的理论知识请参考《 Keepalived原理与实战精讲 》



1,本例通过Keepalived来实现两台LNMP(也就是linux+nginx+mysql+php)架构服务器的双机热备



LNMP的配置请参考:《 Lnmp配置精讲第一版 》



2,Keepalived配置双机安装配置



1》Keepalived安装



keepalived官方地址: http://www.keepalived.org/download.html ,大家可以到这里下载最新版本的keepalived



操作系统:centos 5.5 32bit


系统安装:最小化安装,也就是去掉所有组件


环境配置:安装make 和 gcc openssl openssl-devel等等

  1. yum -y install gcc make openssl openssl-devel wget kernel-devel
  2. mkdir -p /usr/local/src/hasoft
  3. cd /usr/local/src/hasoft
  4. wget http://www.keepalived.org/software/keepalived-1.2.2.tar.gz
  5. tar -zxvf keepalived-1.2.2.tar.gz
  6. cd keepalived-1.2.2
  7. ./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/2.6.18-238.19.1.el5-i686/

复制代码 预编译后出现:

1.  Keepalived configuration
2.  ------------------------
3.  Keepalived version       : 1.2.2
4.  Compiler                 : gcc
5.  Compiler flags           : -g -O2 -DETHERTYPE_IPV6=0x86dd
6.  Extra Lib                : -lpopt -lssl -lcrypto
7.  Use IPVS Framework       : Yes
8.  IPVS sync daemon support : Yes
9.  IPVS use libnl           : No
10.  Use VRRP Framework       : Yes
11.  Use Debug flags          : No

复制代码

  1. make && make install

复制代码 这里注意哦,我上面是指通用的安装方法,如果你没有用到LVS可以把lvs去掉即


./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/2.6.18-238.19.1.el5-i686/ --disable-lvs-syncd --disable-lvs



但这个没有影响,就按照我的来配置吧,不过如果你要是集成了LVS,那么就不可加这两个参数了哦



整理管理文件:


cp /usr/local/keepalived/sbin/keepalived /usr/sbin/


cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/


cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/


建立配置文件目录(注意:keepalived的配置文件默认在/etc/keepalived/目录)


mkdir -p /etc/etc/keepalived/



两台服务器(两个节点)都这样安装即可



2》配置



节点A配置如下:


vi /etc/keepalived/keepalived.conf


1.  global_defs
2.  {
3.  notification_email
4.  {
5.  admin@example.com
6.  admin@
7.  }
8.  notification_email_from admin@example.com
9.  smtp_server 127.0.0.1
10.  stmp_connect_timeout 30
11.  router_id lnmp_node1
12.  }
13.  
14.  vrrp_instance lnmp {
15.  state MASTER
16.  interface eth0
17.  virtual_router_id 100
18.  priority 200
19.  advert_int 5
20.  track_interface {
21.  eth0
22.  eth1
23.  }
24.  authentication {
25.  auth_type PASS
26.  auth_pass 123456
27.  }
28.  virtual_ipaddress {
29.  192.168.17.200
30.  }
31.  }

复制代码


节点B配置如下:


vi /etc/keepalived/keepalived.conf



1.  global_defs
2.  {
3.  notification_email
4.  {
5.  admin@example.com
6.  admin@
7.  }
8.  notification_email_from admin@example.com
9.  smtp_server 127.0.0.1
10.  stmp_connect_timeout 30
11.  router_id lnmp_node1
12.  }
13.  
14.  vrrp_instance lnmp {
15.  state MASTER
16.  interface eth0
17.  virtual_router_id 100
18.  priority 150
19.  advert_int 5
20.  track_interface {
21.  eth0
22.  eth1
23.  }
24.  authentication {
25.  auth_type PASS
26.  auth_pass 123456
27.  }
28.  virtual_ipaddress {
29.  192.168.17.200
30.  }
31.  }

复制代码 四,启动调试


在节点A上启动


/usr/local/keepalived/sbin/keepalived



启动日志:


Sep  8 18:26:02 centosa Keepalived_vrrp: Registering Kernel netlink reflector


Sep  8 18:26:02 centosa Keepalived_vrrp: Registering Kernel netlink command channel


Sep  8 18:26:02 centosa Keepalived_vrrp: Registering gratutious ARP shared channel


Sep  8 18:26:02 centosa Keepalived_vrrp:  Opening file '/etc/keepalived/keepalived.conf'.


Sep  8 18:26:02 centosa Keepalived_vrrp: Configuration is using : 36076 Bytes


Sep  8 18:26:02 centosa Keepalived_vrrp: Using LinkWatch kernel netlink reflector...


Sep  8 18:26:02 centosa Keepalived: Starting VRRP child process, pid=5606


Sep  8 18:26:07 centosa Keepalived_vrrp:  VRRP_Instance(lnmp) Transition to MASTER STATE


Sep  8 18:26:12 centosa Keepalived_vrrp:  VRRP_Instance(lnmp) Entering MASTER STATE


Sep  8 18:26:12 centosa avahi-daemon[2528]: Registering new address record for 192.168.17.200 on eth0.




在节点B上启动


/usr/local/keepalived/sbin/keepalived



开机自动启动


echo /usr/local/keepalived/sbin/keepalived >> /etc/rc.local



启动日志:


Sep  8 18:30:02 centosb Keepalived: Starting Keepalived v1.2.2 (09/08,2011)


Sep  8 18:30:02 centosb Keepalived: Starting Healthcheck child process, pid=5837


Sep  8 18:30:02 centosb Keepalived_vrrp: Registering Kernel netlink reflector


Sep  8 18:30:02 centosb Keepalived_vrrp: Registering Kernel netlink command channel


Sep  8 18:30:02 centosb Keepalived_vrrp: Registering gratutious ARP shared channel


Sep  8 18:30:02 centosb Keepalived: Starting VRRP child process, pid=5839


Sep  8 18:30:02 centosb kernel: IPVS: Registered protocols (TCP, UDP, AH, ESP)


Sep  8 18:30:02 centosb kernel: IPVS: Connection hash table configured (size=4096, memory=32Kbytes)


Sep  8 18:30:02 centosb kernel: IPVS: ipvs loaded.


Sep  8 18:30:02 centosb Keepalived_healthcheckers: Registering Kernel netlink reflector


Sep  8 18:30:02 centosb Keepalived_healthcheckers: Registering Kernel netlink command channel


Sep  8 18:30:02 centosb Keepalived_healthcheckers: Opening file '/etc/keepalived/keepalived.conf'.


Sep  8 18:30:02 centosb Keepalived_vrrp:  Opening file '/etc/keepalived/keepalived.conf'.


Sep  8 18:30:02 centosb Keepalived_vrrp: Configuration is using : 36252 Bytes


Sep  8 18:30:02 centosb Keepalived_vrrp: Using LinkWatch kernel netlink reflector...


Sep  8 18:30:02 centosb Keepalived_healthcheckers: Configuration is using : 6271 Bytes


Sep  8 18:30:02 centosb Keepalived_healthcheckers: Using LinkWatch kernel netlink reflector...


Sep  8 18:30:02 centosb Keepalived_vrrp:  VRRP_Instance(lnmp) Entering BACKUP STATE



从日志可以看出,启动都没有问题,并且安装我给的优先级完成了竞选,各自成就了各自的状态



关闭节点A的网卡测试切换是否正常


ifdown eth0



观察节点B的日志:


Sep  8 18:32:55 centosb Keepalived_vrrp: VRRP_Instance(lnmp) Transition to MASTER STATE


Sep  8 18:33:00 centosb Keepalived_vrrp: VRRP_Instance(lnmp) Entering MASTER STATE


Sep  8 18:33:00 centosb avahi-daemon[2531]:  Registering  new address record for 192.168.17.200 on eth0.




启动节点A的网卡测试切换是否正常


ifup eth0


观察节点B的日志:


Sep  8 18:33:31 centosb Keepalived_vrrp: VRRP_Instance(lnmp) Received higher prio advert


Sep  8 18:33:31 centosb Keepalived_vrrp: VRRP_Instance(lnmp) Entering BACKUP STATE


Sep  8 18:33:31 centosb avahi-daemon[2531]:  Withdrawing  address record for 192.168.17.200 on eth0.



Received higher prio advert:表示接收到更高优先级的公告(advert公告的意思)


Withdrawing: 撤回的意思,可以看出切换过程一目了然




OK,到这里我们的安装部分完成,下面我们来看看如何监控服务吧,我们这里仅仅是监控了网络故障和keepalived本身进程,在网络或者keepalived进程出现问题的时候会切换,但是我的节点A里面还有很多服务呢,例如nginx,PHP,mysql进程出问题或高负载的时候相应过慢怎么办,怎么切换的呢,这时就要用到脚本了,下面我们来看看keepalived是如何控制脚本来实现对服务器的监控和切换的



写个脚本来实时监控三个服务,若有一个出现问题遍切换mkdir /root/shell/


cd /root/shell


vi


1.  #!/bin/bash
2.  while  :
3.  do
4.  mysqlcheck=`/usr/local/lnmp/mysql/bin/mysqladmin -uroot ping 2>&1`
5.  mysqlcode=`echo $?`
6.  phpcheck=`ps -C php-fpm --no-header | wc -l`
7.  nginxcheck=`ps -C nginx --no-header | wc -l`
8.  keepalivedcheck=`ps -C keepalived --no-header | wc -l`
9.  if [ $nginxcheck -eq 0 ]|| [ $phpcheck -eq 0 ]||[ $mysqlcode -ne 0 ];then
10.                  if [ $keepalivedcheck -ne 0 ];then
11.                     killall -TERM keepalived
12.                  else
13.                     echo "keepalived is stoped"
14.                  fi
15.          else
16.                  if [ $keepalivedcheck -eq 0 ];then
17.                     /etc/init.d/keepalived start
18.                  else
19.                     echo "keepalived is running"
20.                  fi
21.  fi
22.  sleep 5
23.  done

复制代码 注意,用 /etc/init.d/keepalived start如果起不来,可以用/usr/local/keepalived/sbin/keepalived二进制文件直接执行启动即可


启动脚本:


  1. chmod +x /root/shell/
  2. nohup sh /root/shell/ &

复制代码 节点B也用这个脚本



写入/etc/rc.local开机自动启动



  1. echo "nohup sh /root/shell/ &" >> /etc/rc.loal

复制代码 可以测试了