MySQL高可用之——keepalived+互为主从

目标:配置一个keepalived双机热备架构,并配置主从复制


规划:
master1     zlm177     192.168.17.177
master2     zlm188     192.168.17.188
vip                             192.168.17.166


环境: Red Hat Enterprise Linux 6.4
            Percona Server 5.6.15


一、软件安装


能够去官网http://www.keepalived.org/software/下载最新版本号的keepalived。眼下最新的是1.2.13版,例如以下:
keepalived-1.2.13.tar


cp keepalived-1.2.13.tar /usr/local/src
cd /usr/local/src
tar zxvf keepalived-1.2.13.tar -C /opt/
cd /opt/keepalived-1.2.13
./configure --prefix=/usr/local/keepalived
make;makeinstall 或 make && makeinstall


注意,在编译过程中会提示缺少gcc和openssl包,用yum install装一下就能够了
RHEL6.4也能够配置CentOS的yum,详细方法这里就不讲了
yum install gcc
yum install openssl openssl-devel
还会提示xxx依赖包也须要安装,一并装上,用yum的优点就是安装方便。让系统自己主动推断须要哪些包,自己主动下载并安装。完毕编译以后,软件安装就结束了


二、配置软件參数(VRRP)


装完软件后,默认会配置文件的路径为:
/usr/local/keepalived/etc/keepalived/keepalived.conf


在主端打开该配置文件。把原有内容清空。再加入下面内容:


! Configuration File for keepalived


global_defs { --全局配置
   notification_email {
     aaron8219@xxx.xxx --接收通知的邮箱
   }
   router_id aaron8219 --能够用字母。也能够使数字。能够一致。也能够不一致,仅仅是一个标识
}


vrrp_instance my_177 {
    state BACKUP --BACKUP从端模式
    interface eth0
    virtual_router_id 88 --默觉得51。取值范围在1~255的整数,主从两端必须一致。才表示是同一个组
    priority 90
    advert_int 1 --检查间隔,默认1s
    nopreempt --设置非抢占模式,
    authentication {
        auth_type PASS
        auth_pass 1234
    }
    virtual_ipaddress { --指定vip,
        192.168.17.166
    }
}


##关于vip的说明:vip随着state的变化而添加删除,当state为master的时候就加入。当state为backup的时候删除。主要是由优先级来决定的,和state设置的值没有多大关系(state同样的情况下),至于vip究竟在主端还是从端,还和nopreempt有关,这里vip能够设置多个IP地址


##关于nopreempt的说明:仅仅能设置在state为backup的节点上。且这个节点的优先级必须比另外的高


virtual_server 192.168.17.166 3306 { --虚拟服务器ip和port
    delay_loop 2
    lb_algo wrr --带有权重的轮询
    lb_kind DR
    persistence_timeout 60
    protocol TCP


    real_server 192.168.17.177 3306 { --真实服务器ip和port
        weight 3 --权重为3
        notify_down /opt/mysql/mysql.sh  --指定自杀脚本的路径
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
}


从端的配置文件大同小异,仅仅要把IP和实例名改成自己的就能够了,而且设置从端的priority为90,而主端为100
有一点要注意的是,主从两端的state,都配置成了backup,由于使用了nopreempt,即非抢占模式


举个样例,当主端先启动mysql实例和keepalived后,假设此时从端也启动了mysql实例和keepalived。那么vip不会跳到从端上去。即使它的优先级为100。要大于主端的90
而假设不设置nopreempt。那么这个时候。又分2种情况:


1.state同样,即都是master或都是backup
优先级高的,会占有vip。和角色无关


2.state不同。即master->backup或backup->master
优先级高的。会占有vip,和角色无关


前提不同。结果都是一样的,即优先级是主导,谁的优先级高。vip就漂到谁那里


创建一个自杀脚本来推断mysql进程是否启动
touch /opt/mysql/mysql.sh
加入下面内容:
#!/bin.sh
pkill keepalived  --表示kill掉keepalived进程


三、执行測试


/usr/local/keepalived/sbin/keepalived -f /usr/local/keepalived/etc/keepalived/keepalived.conf -D


-f 指定keepalived的參数文件
-D 表示在操作系统日志里显示具体记录


推断keepalived进程是否正常启动,仅仅要查看/var/log/messages里的日志就能够了
tail -30f /var/log/message
注意。假设没有启动mysql而先启动了keepalived。那么之前notify_down參数中指定的脚本就会被运行,表示没有找到mysql进程,把keeplied自己的进程给kill掉。


Jul 25 02:51:22 zlm188 Keepalived[3440]: Starting Keepalived v1.2.13 (07/22,2014)
Jul 25 02:51:22 zlm188 Keepalived[3441]: Starting Healthcheck child process, pid=3442
Jul 25 02:51:22 zlm188 Keepalived[3441]: Starting VRRP child process, pid=3443
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Netlink reflector reports IP 192.168.17.188 added
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Netlink reflector reports IP 192.168.17.188 added
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Netlink reflector reports IP fe80::a00:27ff:fe71:6b7b added
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Registering Kernel netlink reflector
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Netlink reflector reports IP fe80::a00:27ff:fe71:6b7b added
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Registering Kernel netlink command channel
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Registering Kernel netlink reflector
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Registering Kernel netlink command channel
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Registering gratuitous ARP shared channel
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Opening file '/usr/local/keepalived/etc/keepalived/keepalived.conf'.
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Opening file '/usr/local/keepalived/etc/keepalived/keepalived.conf'.
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Configuration is using : 11566 Bytes
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Configuration is using : 62964 Bytes
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Using LinkWatch kernel netlink reflector...
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: VRRP_Instance(my_178) Entering BACKUP STATE
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: VRRP sockpool: [ifindex(2), proto(112), unicast(0), fd(10,11)]
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Using LinkWatch kernel netlink reflector...
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Activating healthchecker for service [192.168.17.188]:3306
Jul 25 02:51:25 zlm188 Keepalived_healthcheckers[3442]: TCP connection to [192.168.17.188]:3306 failed !!!
Jul 25 02:51:25 zlm188 Keepalived_healthcheckers[3442]: Removing service [192.168.17.188]:3306 from VS [192.168.17.166]:3306
Jul 25 02:51:25 zlm188 Keepalived_healthcheckers[3442]: Executing [/opt/mysql/mysql.sh] for service [192.168.17.188]:3306 in VS [192.168.17.166]:3306
Jul 25 02:51:25 zlm188 Keepalived_healthcheckers[3442]: Lost quorum 1-0=1 > 0 for VS [192.168.17.166]:3306
Jul 25 02:51:25 zlm188 Keepalived[3441]: Stopping Keepalived v1.2.13 (07/22,2014)


在从端启动keepalived,跟踪日志文件能够发现,跑了一遍以后自己主动stopping了。这也说明。之前的配置是ok的了,否则就要检查一下。哪里配置有误,尤其要注意virtual_route_id必须保持一致,而route_id则不强行要求一致。实例名也不要反复


1.检验vip的情况
#ip address show或ip a show


2.用vip登录mysql数据库(前提是已开启了mysqld和keepalived进程)
#mysql -h192.168.17.166 -uaaron8219 -pzlm


3.关闭某一端网卡后,測试vip的去向。以及能否通过vip正常登陆
#ifdown eth0
#ip a show
#mysql -h192.168.17.166 -uaaron8219 -pzlm


4.重新启动某一端(主机模拟主机故障),測试vip的去向,以及能否通过vip正常登陆
#init 6
#ip a show
#mysql -h192.168.17.166 -uaaron8219 -pzlm


5.直接kill掉keepalived进程。測试vip的去向,以及能否通过vip正常登陆
#pkill keepalived
#ip a show
#mysql -h192.168.17.166 -uaaron8219 -pzlm


四、配置数据库同步


安装完keepalived。仅仅是保证了mysql数据库的高可用性,可是要真正做到互为主从,还须要配置MySQL主从复制模式,使数据库能够达到一致性状态


1.两端配置同步所需參数
确保server-id与slave不一致,通常server-id的格式能够设置成ip末尾2-3位+port号
比方我的环境master的ip是192.168.17.177,port是3306
那么server-id能够设置成1773306,对应地。slave就设置成1883306
下面參数都是在/etc/my.cnf文件里配置
server-id=1773306
log-bin=percona-bin --启用binlog
set-variable=binlog-ignore-db=mysql --不记录数据库mysql的更新日志,避免了Master上的权限设置等被同步到Slave上


2.两端加入复制用户
mysql> grant repliecation slave on *.* to 'rep'@'192.168.17.%' identified by 'rep';


假设想要在Slave上有权限运行 "LOAD TABLE FROM MASTER" 或 "LOAD DATA FROM MASTER" 语句的话,必须授予全局的 FILE 和 Select 权限:
mysql> GRANT FILE,Select,REPLICATION SLAVE ON *.* TO 'rep'@'%' IDENTIFIED BY 'rep';


3.设置同步
假设是新库,两边直接重置master的binlog
mysql> reset master;


(否则,须要把master的库用mysqldump导出(或直接打包压缩)。再拷贝到从库主机,大致过程例如以下:

①mysql> flush tables with read lock;



②mysql> mysqldump -uroot -p --all-databases -l -F >full_db.sql
scp full_db.sql root@192.168.17.188:/data/mysql/percona_3306/data

②cd /data/mysql/percona_3306
tar zcvf data.tar.gz ./data
scp data.tar.gz root@192.168.17.188


③mysql> unlock tables;
从库导入主库的数据库
mysql> mysql -uroot -p </data/mysql/percona_3306/data/full_db.sql

mysql> source /data/mysql/percona_3306/data/full_db.sql
)


4.主库查询日志状态
mysql> show master statusG


5.从库依据主库的binlog位置和position来运行同步

mysql> change master to master_host='192.168.17.177',master_user='rep',master_password='rep',

master_log_file='percona-bin.000001',master_log_pos='120';



6.启动slave
mysql> start slave;


启动后报错
Slave I/O: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work. Error_code: 1593


由于从库是直接通过虚拟机拷贝镜像的方式创建的。所以UUID反复了,UUID是存放在
/data/mysql/percona_3306/data/auto.cnf文件里的

能够把这个文件直接删除。或者编辑该文件,改动里面的UUID和主库不同就可以,正常以后。应该是下面的状态:


(testing)root@localhost [(none)]> show slave statusG
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.17.177
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: percona-bin.000011
          Read_Master_Log_Pos: 540
               Relay_Log_File: node78-relay-bin.000018
                Relay_Log_Pos: 285
        Relay_Master_Log_File: percona-bin.000011
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 540
              Relay_Log_Space: 459
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 773306
                  Master_UUID: 917ecbfc-10dc-11e4-b624-080027267b03
             Master_Info_File: /data/mysql/percona_3306/data/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0


7.測试
主库測试数据库zlm的tb_zlm表中运行插入一行数据:


(testing)root@localhost [(none)]> select * from zlm.tb_zlm;
+------+-----------+
| id   | name      |
+------+-----------+
|    1 | aaron8219 |
|    2 | zlm       |
|    3 | abc       |
+------+-----------+
3 rows in set (0.00 sec)


(testing)root@localhost [(none)]> insert into zlm.tb_zlm values(4,'def');
Query OK, 1 row affected (0.03 sec)


从库查询zlm.tb_zlm表:


(testing)root@localhost [(none)]> select * from zlm.tb_zlm;
+------+-----------+
| id   | name      |
+------+-----------+
|    1 | aaron8219 |
|    2 | zlm       |
|    3 | abc       |
|    4 | def       |
+------+-----------+
4 rows in set (0.00 sec)


从库上也进行相同的配置,就可以完毕互为主从,仅仅要从对应的master的binlog的pos位置開始change maseter就能够了


结论:仅仅要配置的VRRP组里面有一台机器开启了mysqld和keepalived进程,不论什么通过vip实现的数据库连接訪问,都是正常的。这样不管是哪个节点down掉了,都不会影响mysql数据库的可用性,是一个最简单的mysql高可用架构。自此,通过keepalived来实现互为主从的双机热备架构就完毕了,假设再复杂一点。安装lvpsadm来实现虚拟server的配置,那么就是一个经典的keepalived+lvs架构



原文地址:https://www.cnblogs.com/yxysuanfa/p/6856870.html