黑帽联盟

标题: keepalived+mysql实现双主高可用 [打印本页]

作者: 定位    时间: 2017-6-23 15:41
标题: 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自动部署
  1. [root@www ansible]# ansible-playbook lnmp.yml

  2. PLAY [new] *********************************************************************

  3. TASK [setup] *******************************************************************
  4. ok: [192.168.2.205]
  5. ok: [192.168.2.204]

  6. TASK [mysql : Create backup folder] ********************************************
  7. ok: [192.168.2.204]
  8. ok: [192.168.2.205]

  9. TASK [mysql : create log folder] ***********************************************
  10. changed: [192.168.2.204]
  11. changed: [192.168.2.205]

  12. TASK [mysql : copy mysql_tar_gz to client] *************************************
  13. changed: [192.168.2.204]
  14. changed: [192.168.2.205]

  15. TASK [mysql : copy install_script to client] ***********************************
  16. changed: [192.168.2.204]
  17. changed: [192.168.2.205]

  18. TASK [mysql : copy my.cnf to /data/backup] *************************************
  19. changed: [192.168.2.204]
  20. changed: [192.168.2.205]

  21. TASK [mysql : install mysql] ***************************************************
  22. changed: [192.168.2.204]
  23. changed: [192.168.2.205]

  24. PLAY RECAP *********************************************************************
  25. 192.168.2.204              : ok=7    changed=5    unreachable=0    failed=0   
  26. 192.168.2.205              : ok=7    changed=5    unreachable=0    failed=0
复制代码
2、修改mysql的配置文件

首先修改DB1主机的配置文件,在/etc/my.cnf文件中的[mysqld]段添加以下内容
  1. [root@bogon ~]# vim /etc/my.cnf
  2. server-id = 1    #节点标示,主从节点不能相同,必须全局唯一
  3. log-bin=mysql-bin  #开启mysql的binlog日志功能
  4. relay-log = mysql-relay-bin   #开启relay-log日志,relay-log日志记录的是从服务器I/O线程将主服务器的二进制日志读取过来记录到从服务器本地文件,然后SQL线程会读取relay-log日志的内容并应用到从服务器
  5. replicate-wild-ignore-table=mysql.%  #复制过滤选项
  6. replicate-wild-ignore-table=test.%
  7. replicate-wild-ignore-table=information_schema.%
复制代码
然后修改DB2主机的配置文件
  1. [root@localhost ~]# vim /etc/my.cnf
  2. server-id = 2
  3. log-bin=mysql-bin
  4. relay-log = mysql-relay-bin
  5. replicate-wild-ignore-table=mysql.%
  6. replicate-wild-ignore-table=test.%
  7. replicate-wild-ignore-table=information_schema.%
复制代码
最后分别重启DB1和DB2使配置生效



3、创建复制用户并授权

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

首先在DB1的mysql库中创建复制用户
  1. mysql> grant replication slave on *.* to 'repl_user'@'192.168.2.205' identified by 'repl_passwd';
  2. Query OK, 0 rows affected (0.04 sec)

  3. mysql> show master status;
  4. +------------------+----------+--------------+------------------+
  5. | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
  6. +------------------+----------+--------------+------------------+
  7. | mysql-bin.000004 |      271 |              |                  |
  8. +------------------+----------+--------------+------------------+
  9. row in set (0.00 sec)
复制代码
然后在DB2的mysql库中将DB1设为自己的主服务器
  1. mysql> change master to \
  2.     -> master_host='192.168.2.204',  
  3.     -> master_user='repl_user',
  4.     -> master_password='repl_passwd',
  5.     -> master_log_file='mysql-bin.000004',  
  6.     -> master_log_pos=271;
  7. Query OK, 0 rows affected (0.07 sec)
复制代码
这里需要注意master_log_file和master_log_pos两个选项,这两个选项的值是在DB1上通过“show master status” 查询到的结果

接着在DB2上启动slave服务
  1. mysql> start slave;
  2. Query OK, 0 rows affected (0.01 sec)
复制代码
下面查看DB2上slave的运行状态
  1. mysql> show slave status\G
  2. *************************** 1. row ***************************
  3.                Slave_IO_State: Waiting for master to send event
  4.                   Master_Host: 192.168.2.204
  5.                   Master_User: repl_user
  6.                   Master_Port: 3306
  7.                 Connect_Retry: 60
  8.               Master_Log_File: mysql-bin.000005
  9.           Read_Master_Log_Pos: 271
  10.                Relay_Log_File: mysql-relay-bin.000002
  11.                 Relay_Log_Pos: 253
  12.         Relay_Master_Log_File: mysql-bin.000005
  13.              Slave_IO_Running: Yes    #重点
  14.             Slave_SQL_Running: Yes    #重点
  15.               Replicate_Do_DB:
  16.           Replicate_Ignore_DB:
  17.            Replicate_Do_Table:
  18.        Replicate_Ignore_Table:
  19.       Replicate_Wild_Do_Table:
  20.   Replicate_Wild_Ignore_Table: mysql.%,test.%,information_schema.%  #跳过的表
  21.                    Last_Errno: 0
  22.                    Last_Error:
  23.                  Skip_Counter: 0
  24.           Exec_Master_Log_Pos: 271
  25.               Relay_Log_Space: 409
  26.               Until_Condition: None
  27.                Until_Log_File:
  28.                 Until_Log_Pos: 0
  29.            Master_SSL_Allowed: No
  30.            Master_SSL_CA_File:
  31.            Master_SSL_CA_Path:
  32.               Master_SSL_Cert:
  33.             Master_SSL_Cipher:
  34.                Master_SSL_Key:
  35.         Seconds_Behind_Master: 0
  36. Master_SSL_Verify_Server_Cert: No
  37.                 Last_IO_Errno: 0
  38.                 Last_IO_Error:
  39.                Last_SQL_Errno: 0
  40.                Last_SQL_Error:
  41.   Replicate_Ignore_Server_Ids:
  42.              Master_Server_Id: 1
  43. row in set (0.00 sec)
复制代码
到这里,从DB1到DB2的mysql主从复制已经完成。接下来开始配置从DB2到DB1的mysql主从复制

在DB2的mysql库中创建复制用户
  1. mysql> grant replication slave on *.* to 'repl_user'@'192.168.2.204' identified by 'repl_passwd';
  2. Query OK, 0 rows affected (0.00 sec)

  3. mysql> show master status;
  4. +------------------+----------+--------------+------------------+
  5. | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
  6. +------------------+----------+--------------+------------------+
  7. | mysql-bin.000005 |      271 |              |                  |
  8. +------------------+----------+--------------+------------------+
  9. row in set (0.00 sec)
复制代码
然后在DB1的mysql库中将DB2设为自己的主服务器
  1. mysql> change master to \
  2.     -> master_host='192.168.2.205',
  3.     -> master_user='repl_user',
  4.     -> master_password='repl_passwd',
  5.     -> master_log_file='mysql-bin.000005',
  6.     -> master_log_pos=271;
  7. Query OK, 0 rows affected (0.07 sec)
复制代码
最后,在DB1上启动slave服务
  1. mysql> start slave;
  2. Query OK, 0 rows affected (0.01 sec)
复制代码
查看DB1上slave的运行状态
  1. mysql> show slave status\G
  2. *************************** 1. row ***************************
  3.                Slave_IO_State: Waiting for master to send event
  4.                   Master_Host: 192.168.2.205
  5.                   Master_User: repl_user
  6.                   Master_Port: 3306
  7.                 Connect_Retry: 60
  8.               Master_Log_File: mysql-bin.000005
  9.           Read_Master_Log_Pos: 271
  10.                Relay_Log_File: mysql-relay-bin.000002
  11.                 Relay_Log_Pos: 253
  12.         Relay_Master_Log_File: mysql-bin.000005
  13.              Slave_IO_Running: Yes
  14.             Slave_SQL_Running: Yes
  15.               Replicate_Do_DB:
  16.           Replicate_Ignore_DB:
  17.            Replicate_Do_Table:
  18.        Replicate_Ignore_Table:
  19.       Replicate_Wild_Do_Table:
  20.   Replicate_Wild_Ignore_Table: mysql.%,test.%,information_schema.%
  21.                    Last_Errno: 0
  22.                    Last_Error:
  23.                  Skip_Counter: 0
  24.           Exec_Master_Log_Pos: 271
  25.               Relay_Log_Space: 409
  26.               Until_Condition: None
  27.                Until_Log_File:
  28.                 Until_Log_Pos: 0
  29.            Master_SSL_Allowed: No
  30.            Master_SSL_CA_File:
  31.            Master_SSL_CA_Path:
  32.               Master_SSL_Cert:
  33.             Master_SSL_Cipher:
  34.                Master_SSL_Key:
  35.         Seconds_Behind_Master: 0
  36. Master_SSL_Verify_Server_Cert: No
  37.                 Last_IO_Errno: 0
  38.                 Last_IO_Error:
  39.                Last_SQL_Errno: 0
  40.                Last_SQL_Error:
  41.   Replicate_Ignore_Server_Ids:
  42.              Master_Server_Id: 2
  43. row in set (0.00 sec)
复制代码
二、配置keepalived实现mysql双主高可用

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

DB1上keepalived.conf配置为
  1. [root@bogon keepalived-1.2.24]# cat /etc/keepalived/keepalived.conf
  2. ! Configuration File for keepalived

  3. global_defs {
  4.    notification_email {
  5.      root<span id="kM0.39992083176707727">@localhost</span>
  6.    }
  7.    notification_email_from keepalived<span id="kM0.17554743406903328">@localhost</span>
  8.    smtp_server 192.168.200.1
  9.    smtp_connect_timeout 30
  10.    router_id LVS_DEVEL
  11.    vrrp_skip_check_adv_addr
  12.    vrrp_strict
  13.    vrrp_garp_interval 0
  14.    vrrp_gna_interval 0
  15. }


  16. vrrp_instance HA_1 {
  17.     state BACKUP    #在DB1和DB2上均配置为BACKUP
  18.     interface eth1
  19.     virtual_router_id 90
  20.     priority 100
  21.     advert_int 1
  22.     nopreempt    #不抢占模式,只有优先级高的机器上设置即可,优先级低的机器可不设置
  23.     authentication {
  24.         auth_type PASS
  25.         auth_pass 1111
  26.     }
  27.     virtual_ipaddress {
  28.     192.168.2.33
  29.     }
  30. }

  31. virtual_server 192.168.2.33 3306 {
  32.      delay_loop 2
  33.      lb_algo wrr
  34.      lb_kind DR
  35.      persistence_timeout 60  #会话保持时间
  36.      protocol TCP
  37.      real_server 192.168.2.204 3306 {
  38.          weight 3
  39.          notify_down /root/shutdown.sh  #检测到服务down后执行的脚本
  40.          TCP_CHECK {
  41.              connect_timeout 10  #连接超时时间
  42.              nb_get_retry 3    #重连次数
  43.              delay_before_retry 3   #重连间隔时间  
  44.              connect_port 3306     #健康检查端口
  45.          }
  46.      }
  47. }
复制代码
DB2上keepalived.conf配置为
  1. [root@localhost keepalived-1.2.24]# cat /etc/keepalived/keepalived.conf
  2. ! Configuration File for keepalived

  3. global_defs {
  4.    notification_email {
  5. root<span id="kM0.5718797554368988">@localhost</span>
  6.    }
  7.    notification_email_from keepalived<span id="kM0.2670048335059181">@localhost</span>
  8.    smtp_server 192.168.200.1
  9.    smtp_connect_timeout 30
  10.    router_id LVS_DEVEL
  11.    vrrp_skip_check_adv_addr
  12.    vrrp_strict
  13.    vrrp_garp_interval 0
  14.    vrrp_gna_interval 0
  15. }

  16. vrrp_instance HA_1 {
  17.     state BACKUP
  18.     interface eth1
  19.     virtual_router_id 90
  20.     priority 90
  21.     advert_int 1
  22.     authentication {
  23.         auth_type PASS
  24.         auth_pass 1111
  25.     }
  26.     virtual_ipaddress {
  27.     192.168.2.33
  28.     }
  29. }

  30. virtual_server 192.168.2.33 3306 {
  31.      delay_loop 2
  32.      lb_algo wrr
  33.      lb_kind DR
  34.      persistence_timeout 60
  35.      protocol TCP
  36.      real_server 192.168.2.205 3306 {
  37.          weight 3
  38.          notify_down /root/shutdown.sh
  39.          TCP_CHECK {
  40.              connect_timeout 10
  41.              nb_get_retry 3
  42.              delay_before_retry 3
  43.              connect_port 3306
  44.          }
  45.      }
  46. }
复制代码
编写检测服务down后所要执行的脚本shutdown.sh
  1. [root@bogon ~]# cat /root/shtdown.sh
  2. #!/bin/bash
  3. 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并查看日志
  1. [root@bogon keepalived-1.2.24]# chmod 755 /etc/init.d/keepalived
  2. [root@bogon keepalived-1.2.24]# service keepalived start
  3. 正在启动 keepalived:                                      [确定]
  4. [root@bogon keepalived-1.2.24]# tail -f /var/log/messages
  5. Oct 24 22:37:35 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
  6. Oct 24 22:37:35 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
  7. Oct 24 22:37:35 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
  8. Oct 24 22:37:35 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
  9. Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
  10. Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: VRRP_Instance(HA_1) Sending/queueing gratuitous ARPs on eth1 for 192.168.2.33
  11. Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
  12. Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
  13. Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
  14. Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
复制代码
三、测试功能

1、在远程客户端通过vip登陆测试
  1. [root@www ansible]# mysql -h 192.168.2.33 -uroot -p
  2. Enter password:
  3. Welcome to the MySQL monitor.  Commands end with ; or \g.
  4. Your MySQL connection id is 2372
  5. Server version: 5.5.37-log Source distribution

  6. Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

  7. Oracle is a registered trademark of Oracle Corporation and/or its
  8. affiliates. Other names may be trademarks of their respective
  9. owners.

  10. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

  11. mysql>
  12.   mysql> show variables like "%hostname%"
  13.   -> ;
  14.   +---------------+-------+
  15.   | Variable_name | Value |
  16.   +---------------+-------+
  17.   | hostname      | bogon |
  18.   +---------------+-------+
  19. row in set (0.00 sec)
复制代码
从sql输出结果看,可以通过vip登陆,并且登陆了DB1服务器

2、创建一个数据库,然后在这个库重创建一个表,并插入数据
  1. mysql> create database repldb;
  2. Query OK, 1 row affected (0.02 sec)

  3. mysql> show databases;
  4. +--------------------+
  5. | Database           |
  6. +--------------------+
  7. | information_schema |
  8. | mysql              |
  9. | performance_schema |
  10. | repldb             |
  11. | test               |
  12. +--------------------+
  13. rows in set (0.06 sec)

  14. mysql> use repldb;
  15. Database changed
  16. mysql> create table repl_table(id int,email varchar(80),password varchar(40) not null);
  17. Query OK, 0 rows affected (0.03 sec)

  18. mysql> show tables;
  19. +------------------+
  20. | Tables_in_repldb |
  21. +------------------+
  22. | repl_table       |
  23. +------------------+
  24. row in set (0.01 sec)

  25. mysql> insert into repl_table(id,email,password) values(1,"master@163.com","qweasd");
  26. Query OK, 1 row affected (0.00 sec)
复制代码
登陆DB2主机的mysql,可数据是否复制成功
  1. mysql> show variables like "%hostname%";
  2. +---------------+-----------------------+
  3. | Variable_name | Value                 |
  4. +---------------+-----------------------+
  5. | hostname      | localhost.localdomain |
  6. +---------------+-----------------------+
  7. row in set (0.01 sec)

  8. mysql> show databases;
  9. +--------------------+
  10. | Database           |
  11. +--------------------+
  12. | information_schema |
  13. | mysql              |
  14. | performance_schema |
  15. | repldb             |
  16. | test               |
  17. +--------------------+
  18. rows in set (0.05 sec)

  19. mysql> use repldb;
  20. Database changed
  21. mysql> show tables;
  22. +------------------+
  23. | Tables_in_repldb |
  24. +------------------+
  25. | repl_table       |
  26. +------------------+
  27. row in set (0.00 sec)


  28. mysql> select * from repl_table;
  29. +------+----------------+----------+
  30. | id   | email          | password |
  31. +------+----------------+----------+
  32. |    1 | master@163.com | qweasd   |
  33. +------+----------------+----------+
  34. row in set (0.08 sec)
复制代码
3、停止DB1主机上的mysql,查看故障是否自动转移
  1. [root@bogon ~]# service mysqld stop
  2. Shutting down MySQL.. SUCCESS!
复制代码
登陆192.168.2.33查看:
  1. mysql> show variables like "%hostname%";
  2. ERROR 2006 (HY000): MySQL server has gone away
  3. No connection. Trying to reconnect...
  4. Connection id:    610
  5. Current database: repldb

  6. +---------------+-----------------------+
  7. | Variable_name | Value                 |
  8. +---------------+-----------------------+
  9. | hostname      | localhost.localdomain |
  10. +---------------+-----------------------+
  11. row in set (0.01 sec)
复制代码
可以看到现在登陆的是DB2 故障自动切换成功

接着,插入数据看DB1是否能复制
  1. mysql> insert into repl_table(id,email,password) values(2,"slave@163.com","qweasd");
  2. Query OK, 1 row affected (0.06 sec)

  3. mysql> use repldb;
  4. Database changed
  5. mysql> select * from repl_table;
  6. +------+----------------+----------+
  7. | id   | email          | password |
  8. +------+----------------+----------+
  9. |    1 | master@163.com | qweasd   |
  10. |    2 | slave@163.com  | qweasd   |
  11. +------+----------------+----------+
  12. rows in set (0.00 sec)
复制代码
登陆DB1查看表数据
  1. [root@bogon ~]# service mysqld start
  2. Starting MySQL. SUCCESS!
  3. [root@bogon ~]# mysql -uroot -p
  4. Enter password:
  5. Welcome to the MySQL monitor.  Commands end with ; or \g.
  6. Your MySQL connection id is 4
  7. Server version: 5.5.37-log Source distribution

  8. Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

  9. Oracle is a registered trademark of Oracle Corporation and/or its
  10. affiliates. Other names may be trademarks of their respective
  11. owners.

  12. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

  13. mysql> use repldb;
  14. Database changed
  15. mysql> select * from repl_table;
  16. +------+----------------+----------+
  17. | id   | email          | password |
  18. +------+----------------+----------+
  19. |    1 | master@163.com | qweasd   |
  20. |    2 | slave@163.com  | qweasd   |
  21. +------+----------------+----------+
  22. rows in set (0.02 sec)
复制代码
复制成功!


到此全部完成!!


作者: feihu    时间: 2017-6-26 15:36
keepalived是啥东西啊




欢迎光临 黑帽联盟 (https://bbs.cnblackhat.com/) Powered by Discuz! X2.5