zoukankan      html  css  js  c++  java
  • keepalived+mysql实现双主高可用

    环境:

    DB1:centos6.8、mysql5.5、192.168.2.204  hostname:bogon

    DB2:centos6.8、mysql5.5、192.168.2.205  hostname:localhost.localdomain

    vip:192.168.2.33

    一、先配置DB1和DB2的双主热备

    1、分别在DB1和DB2上安装mysql,我这里是用的ansible自动部署

    [root@www ansible]# ansible-playbook lnmp.yml 
    
    PLAY [new] *********************************************************************
    
    TASK [setup] *******************************************************************
    ok: [192.168.2.205]
    ok: [192.168.2.204]
    
    TASK [mysql : Create backup folder] ********************************************
    ok: [192.168.2.204]
    ok: [192.168.2.205]
    
    TASK [mysql : create log folder] ***********************************************
    changed: [192.168.2.204]
    changed: [192.168.2.205]
    
    TASK [mysql : copy mysql_tar_gz to client] *************************************
    changed: [192.168.2.204]
    changed: [192.168.2.205]
    
    TASK [mysql : copy install_script to client] ***********************************
    changed: [192.168.2.204]
    changed: [192.168.2.205]
    
    TASK [mysql : copy my.cnf to /data/backup] *************************************
    changed: [192.168.2.204]
    changed: [192.168.2.205]
    
    TASK [mysql : install mysql] ***************************************************
    changed: [192.168.2.204]
    changed: [192.168.2.205]
    
    PLAY RECAP *********************************************************************
    192.168.2.204              : ok=7    changed=5    unreachable=0    failed=0   
    192.168.2.205              : ok=7    changed=5    unreachable=0    failed=0   

    2、修改mysql的配置文件

    首先修改DB1主机的配置文件,在/etc/my.cnf文件中的[mysqld]段添加以下内容

    [root@bogon ~]# vim /etc/my.cnf
    server-id = 1    #节点标示,主从节点不能相同,必须全局唯一
    log-bin=mysql-bin  #开启mysql的binlog日志功能
    relay-log = mysql-relay-bin   #开启relay-log日志,relay-log日志记录的是从服务器I/O线程将主服务器的二进制日志读取过来记录到从服务器本地文件,然后SQL线程会读取relay-log日志的内容并应用到从服务器
    replicate-wild-ignore-table=mysql.%  #复制过滤选项
    replicate-wild-ignore-table=test.%
    replicate-wild-ignore-table=information_schema.%

    然后修改DB2主机的配置文件,

    [root@localhost ~]# vim /etc/my.cnf
    server-id = 2
    log-bin=mysql-bin
    relay-log = mysql-relay-bin
    replicate-wild-ignore-table=mysql.%
    replicate-wild-ignore-table=test.%
    replicate-wild-ignore-table=information_schema.%

    最后分别重启DB1和DB2使配置生效

    3、创建复制用户并授权

    注:在执行主主互备之前要保证两台server上数据一致

    首先在DB1的mysql库中创建复制用户

    mysql> grant replication slave on *.* to 'repl_user'@'192.168.2.205' identified by 'repl_passwd';
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> show master status;
    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000004 |      271 |              |                  |
    +------------------+----------+--------------+------------------+
    1 row in set (0.00 sec)

    然后在DB2的mysql库中将DB1设为自己的主服务器

    mysql> change master to 
        -> master_host='192.168.2.204',  
        -> master_user='repl_user',
        -> master_password='repl_passwd',
        -> master_log_file='mysql-bin.000004',  
        -> master_log_pos=271;
    Query OK, 0 rows affected (0.07 sec)

    这里需要注意master_log_file和master_log_pos两个选项,这两个选项的值是在DB1上通过“show master status” 查询到的结果

    接着在DB2上启动slave服务

    mysql> start slave;
    Query OK, 0 rows affected (0.01 sec)

    下面查看DB2上slave的运行状态,

    mysql> show slave statusG
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.2.204
                      Master_User: repl_user
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000005
              Read_Master_Log_Pos: 271
                   Relay_Log_File: mysql-relay-bin.000002
                    Relay_Log_Pos: 253
            Relay_Master_Log_File: mysql-bin.000005
                 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: mysql.%,test.%,information_schema.%  #跳过的表
                       Last_Errno: 0
                       Last_Error: 
                     Skip_Counter: 0
              Exec_Master_Log_Pos: 271
                  Relay_Log_Space: 409
                  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: 1
    1 row in set (0.00 sec)

    到这里,从DB1到DB2的mysql主从复制已经完成。接下来开始配置从DB2到DB1的mysql主从复制

    在DB2的mysql库中创建复制用户

    mysql> grant replication slave on *.* to 'repl_user'@'192.168.2.204' identified by 'repl_passwd';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> show master status;
    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000005 |      271 |              |                  |
    +------------------+----------+--------------+------------------+
    1 row in set (0.00 sec)

    然后在DB1的mysql库中将DB2设为自己的主服务器

    mysql> change master to 
        -> master_host='192.168.2.205',
        -> master_user='repl_user',
        -> master_password='repl_passwd',
        -> master_log_file='mysql-bin.000005',
        -> master_log_pos=271;
    Query OK, 0 rows affected (0.07 sec)

    最后,在DB1上启动slave服务

    mysql> start slave;
    Query OK, 0 rows affected (0.01 sec)

    查看DB1上slave的运行状态

    mysql> show slave statusG
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.2.205
                      Master_User: repl_user
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000005
              Read_Master_Log_Pos: 271
                   Relay_Log_File: mysql-relay-bin.000002
                    Relay_Log_Pos: 253
            Relay_Master_Log_File: mysql-bin.000005
                 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: mysql.%,test.%,information_schema.%
                       Last_Errno: 0
                       Last_Error: 
                     Skip_Counter: 0
              Exec_Master_Log_Pos: 271
                  Relay_Log_Space: 409
                  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: 2
    1 row in set (0.00 sec)

    二、配置keepalived实现mysql双主高可用

    1、安装keepalived

    [root@bogon src]# tar zxf keepalived-1.2.24.tar.gz 
    [root@bogon src]# cd keepalived-1.2.24
    [root@bogon keepalived-1.2.24]# ./configure --sysconf=/etc --with-kernel-dir=/lib/modules/2.6.32-642.3.1.el6.x86_64/
    [root@bogon keepalived-1.2.24]# make && make install
    [root@bogon keepalived-1.2.24]# ln -s /usr/local/sbin/keepalived /sbin/
    [root@bogon keepalived-1.2.24]# chkconfig --add keepalived
    [root@bogon keepalived-1.2.24]# chkconfig --level 35 keepalived on
    [root@bogon keepalived-1.2.24]# yum  -y install ipvsadm ####之前没安装ipvsadm,导致 keepalived配置中lvs配置部分不生效,其中定义的notify_down 字段死活不生效,查了好久在发现是没安装ipvsadm导致的,泪奔!!!
    [root@bogon keepalived-1.2.24]# ipvsadm

    2、配置keepalived

    DB1上keepalived.conf配置为

    [root@bogon keepalived-1.2.24]# cat /etc/keepalived/keepalived.conf 
    ! Configuration File for keepalived
    
    global_defs {
       notification_email {
         acassen@firewall.loc
         failover@firewall.loc
         sysadmin@firewall.loc
       }
       notification_email_from Alexandre.Cassen@firewall.loc
       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 HA_1 {
        state BACKUP    #在DB1和DB2上均配置为BACKUP
        interface eth1
        virtual_router_id 90 
        priority 100
        advert_int 1
        nopreempt    #不抢占模式,只有优先级高的机器上设置即可,优先级低的机器可不设置
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
        192.168.2.33
        }
    }
    
    virtual_server 192.168.2.33 3306 {
         delay_loop 2
         lb_algo wrr
         lb_kind DR
         persistence_timeout 60  #会话保持时间 
         protocol TCP
         real_server 192.168.2.204 3306 {
             weight 3
             notify_down /root/shutdown.sh  #检测到服务down后执行的脚本 
             TCP_CHECK {
                 connect_timeout 10  #连接超时时间
                 nb_get_retry 3    #重连次数
                 delay_before_retry 3   #重连间隔时间  
                 connect_port 3306     #健康检查端口
             } 
         }
    }

    DB2上keepalived.conf配置为

    [root@localhost keepalived-1.2.24]# cat /etc/keepalived/keepalived.conf 
    ! Configuration File for keepalived
    
    global_defs {
       notification_email {
         acassen@firewall.loc
         failover@firewall.loc
         sysadmin@firewall.loc
       }
       notification_email_from Alexandre.Cassen@firewall.loc
       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 HA_1 {
        state BACKUP
        interface eth1
        virtual_router_id 90 
        priority 90
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
        192.168.2.33
        }
    }
    
    virtual_server 192.168.2.33 3306 {
         delay_loop 2
         lb_algo wrr
         lb_kind DR
         persistence_timeout 60
         protocol TCP
         real_server 192.168.2.205 3306 {
             weight 3
             notify_down /root/shutdown.sh
             TCP_CHECK {
                 connect_timeout 10
                 nb_get_retry 3
                 delay_before_retry 3
                 connect_port 3306
             } 
         }
    }

    编写检测服务down后所要执行的脚本shutdown.sh

    [root@bogon ~]# cat /root/shtdown.sh 
    #!/bin/bash
    killall keepalived

    注:此脚本是上面配置文件notify_down选项所用到的,keepalived使用notify_down选项来检查real_server的服务状态,当发现real_server服务故障时,便触发此脚本;我们可以看到,脚本就一个命令,通过killall keepalived强制杀死keepalived进程,从而实现了MySQL故障自动转移。另外,我们不用担心两个MySQL会同时提供数据更新操作,因为每台MySQL上的keepalived的配置里面只有本机MySQL的IP+VIP,而不是两台MySQL的IP+VIP

    启动keepalived并查看日志

    [root@bogon keepalived-1.2.24]# chmod 755 /etc/init.d/keepalived 
    [root@bogon keepalived-1.2.24]# service keepalived start
    正在启动 keepalived:                                      [确定]
    [root@bogon keepalived-1.2.24]# tail -f /var/log/messages
    Oct 24 22:37:35 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:35 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:35 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:35 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: VRRP_Instance(HA_1) Sending/queueing gratuitous ARPs on eth1 for 192.168.2.33
    Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33

    三、测试功能

    1、在远程客户端通过vip登陆测试

    [root@www ansible]# mysql -h 192.168.2.33 -uroot -p
    Enter password: 
    Welcome to the MySQL monitor.  Commands end with ; or g.
    Your MySQL connection id is 2372
    Server version: 5.5.37-log Source distribution
    
    Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
    
    mysql>

      mysql> show variables like "%hostname%"
      -> ;
      +---------------+-------+
      | Variable_name | Value |
      +---------------+-------+
      | hostname | bogon |
      +---------------+-------+
      1 row in set (0.00 sec)

    从sql输出结果看,可以通过vip登陆,并且登陆了DB1服务器

    2、创建一个数据库,然后在这个库重创建一个表,并插入数据

    mysql> create database repldb;
    Query OK, 1 row affected (0.02 sec)
    
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | repldb             |
    | test               |
    +--------------------+
    5 rows in set (0.06 sec)
    
    mysql> use repldb;
    Database changed
    mysql> create table repl_table(id int,email varchar(80),password varchar(40) not null);
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> show tables;
    +------------------+
    | Tables_in_repldb |
    +------------------+
    | repl_table       |
    +------------------+
    1 row in set (0.01 sec)
    
    mysql> insert into repl_table(id,email,password) values(1,"master@163.com","qweasd");
    Query OK, 1 row affected (0.00 sec)

    登陆DB2主机的mysql,可数据是否复制成功

    mysql> show variables like "%hostname%";
    +---------------+-----------------------+
    | Variable_name | Value                 |
    +---------------+-----------------------+
    | hostname      | localhost.localdomain |
    +---------------+-----------------------+
    1 row in set (0.01 sec)
    
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | repldb             |
    | test               |
    +--------------------+
    5 rows in set (0.05 sec)
    
    mysql> use repldb;
    Database changed
    mysql> show tables;
    +------------------+
    | Tables_in_repldb |
    +------------------+
    | repl_table       |
    +------------------+
    1 row in set (0.00 sec)
    
    
    mysql> select * from repl_table;
    +------+----------------+----------+
    | id   | email          | password |
    +------+----------------+----------+
    |    1 | master@163.com | qweasd   |
    +------+----------------+----------+
    1 row in set (0.08 sec)

    3、停止DB1主机上的mysql,查看故障是否自动转移

    [root@bogon ~]# service mysqld stop
    Shutting down MySQL.. SUCCESS! 

     登陆192.168.2.33查看:

    mysql> show variables like "%hostname%";
    ERROR 2006 (HY000): MySQL server has gone away
    No connection. Trying to reconnect...
    Connection id:    610
    Current database: repldb
    
    +---------------+-----------------------+
    | Variable_name | Value                 |
    +---------------+-----------------------+
    | hostname      | localhost.localdomain |
    +---------------+-----------------------+
    1 row in set (0.01 sec)

    可以看到现在登陆的是DB2 故障自动切换成功

    接着,插入数据看DB1是否能复制

    mysql> insert into repl_table(id,email,password) values(2,"slave@163.com","qweasd");
    Query OK, 1 row affected (0.06 sec)
    
    mysql> use repldb;
    Database changed
    mysql> select * from repl_table;
    +------+----------------+----------+
    | id   | email          | password |
    +------+----------------+----------+
    |    1 | master@163.com | qweasd   |
    |    2 | slave@163.com  | qweasd   |
    +------+----------------+----------+
    2 rows in set (0.00 sec)

    登陆DB1查看表数据

    [root@bogon ~]# service mysqld start
    Starting MySQL. SUCCESS! 
    [root@bogon ~]# mysql -uroot -p
    Enter password: 
    Welcome to the MySQL monitor.  Commands end with ; or g.
    Your MySQL connection id is 4
    Server version: 5.5.37-log Source distribution
    
    Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
    
    mysql> use repldb;
    Database changed
    mysql> select * from repl_table;
    +------+----------------+----------+
    | id   | email          | password |
    +------+----------------+----------+
    |    1 | master@163.com | qweasd   |
    |    2 | slave@163.com  | qweasd   |
    +------+----------------+----------+
    2 rows in set (0.02 sec)

    复制成功!

    到此全部完成!!!

  • 相关阅读:
    笔试:一个逻辑题
    jmeter,学这些重点就可以了
    性能测试:通过一个案例(等待锁超时)告诉你,性能到底要不要熟悉业务逻辑?
    源码解读:webdriver client的原理 (面试自动化:如果你认为知道18种定位方式就算会自动化,那就太low了)
    测试必备:jmeter测试http协议接口的各种传参方式
    Vue笔记:封装 axios 为插件使用
    Vue笔记:使用 axios 发送请求
    Tomcat笔记:Tomcat的执行流程解析
    Git笔记:Git介绍和常用命令汇总
    Spring Boot使用Shiro实现登录授权认证
  • 原文地址:https://www.cnblogs.com/liuyisai/p/5998110.html
Copyright © 2011-2022 走看看