zoukankan      html  css  js  c++  java
  • 采用keepalived施工可用性MySQL-HA


    描述了使用keepalived施工可用性MySQL-HA,两个保证MySQL数据一致性,然后,keepalived虚拟IP,经keepalived内置的在线监测功能来实现MySQL。

    AD:


    关于MySQL-HA,眼下有多种解决方式。比方heartbeat、drbd、mmm、共享存储,可是它们各有优缺点。

    heartbeat、drbd配置较为复杂,须要自己写脚本才干实现MySQL自己主动切换,对于不会脚本语言的人来说,这无疑是一种脑裂问题。对于mmm,生产环境中非常少有人用,且mmm 管理端须要单独执行一台server上,要是想实现高可用,就得对mmm管理端做HA,这样无疑又添加了硬件开支;对于共享存储,个人认为MySQL数据还是放在本地较为安全。存储设备毕竟存在单点隐患。

    使用MySQL双master+keepalived是一种非常好的解决方式,在MySQL-HA环境中,MySQL互为主从关系,这样就保证了两台MySQL数据的一致性。然后用keepalived实现虚拟IP,通过keepalived自带的服务监控功能来实现MySQL故障时自己主动切换。

    以下。我把即将上线的一个生产环境中的架构与大家分享一下。看一下这个架构中,MySQL-HA是怎样实现的,环境拓扑例如以下

    MySQL-VIP192.168.1.90  

    MySQL-master1192.168.1.91  

    MySQL-master2192.168.1.92  

     

    OS版本号:CentOS 5.4  

    MySQL版本号:5.0.89  

    Keepalived版本号:1.1.20 

    一、MySQL master-master配置

    [root@localhost ~]# mysql -uroot

    Welcome to the MySQL monitor.  Commands end with ; or g.

    Your MySQL connection id is 4

    Server version: 5.0.77 Source distribution

     

    Type 'help;' or 'h' for help. Type 'c' toclear the buffer.

     

    mysql> GRANT ALL PRIVILEGES ON *.* TOroot@'%';

    Query OK, 0 rows affected (0.01 sec)

     

    mysql> use mysql;

    Reading table information for completion oftable and column names

    You can turn off this feature to get aquicker startup with -A

     

    Database changed

    mysql> update user setPassword=password('bee') where user='root';

    Query OK, 4 rows affected (0.01 sec)

    Rows matched: 4  Changed: 4 Warnings: 0

    mysql> show  master status;

    +------------------+----------+--------------+------------------+

    | File             | Position | Binlog_Do_DB |Binlog_Ignore_DB |

    +------------------+----------+--------------+------------------+

    | MySQL-bin.000001 |      328 |              |                  |

    +------------------+----------+--------------+------------------+

    1 row in set (0.00 sec)

    1、改动MySQL配置文件

    [mysqld]

    log-bin=MySQL-bin

    datadir=/var/lib/mysql

    socket=/var/lib/mysql/mysql.sock

    user=mysql

    server-id = 2

    replicate-same-server-id = 0

    auto-increment-increment = 2

    auto-increment-offset = 2

     

    replicate-ignore-db=test

    replicate-ignore-db=mysql

    slave-skip-errors=all

    # Default to using old password format forcompatibility with mysql 3.x

    # clients (those using the mysqlclient10compatibility package).

    old_passwords=1

     

    # Disabling symbolic-links is recommended toprevent assorted security risks;

    # to do so, uncomment this line:

    # symbolic-links=0

    [replication]

    master-host=192.168.1.91

    master-user=replication

    master-password=replication

    master-port=3306

    master-connect-retry=60

     

    [mysqld_safe]

    log-error=/var/log/mysqld.log

    pid-file=/var/run/mysqld/mysqld.pid

    两台MySQL均如要开启binlog日志功能。开启方法:在MySQL配置文件[MySQLd]段中加上log-bin=MySQL-bin选项

    两台MySQL的server-ID不能一样。默认情况下两台MySQL的serverID都是1,需将当中一台改动为2就可以

    2、将192.168.1.201设为192.168.1.202的主server

    在192.168.1.201上新建授权用户

    MySQL> grant replication slave on *.* to 'replication'@'%' identified by 'replication'; 

    Query OK, 0 rows affected (0.00 sec) 

     

    MySQL> show master status;  

    +------------------+----------+--------------+------------------+ 

    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | 

    +------------------+----------+--------------+------------------+ 

    | MySQL-bin.000003 |      374 |              |                  |  

    +------------------+----------+--------------+------------------+ 

    1 row in set (0.00 sec) 

    在192.168.1.202上将192.168.1.201设为自己的主server

    MySQL> change master to master_host='192.168.1.201',master_user='replication',master_password='replication',master_log_file='MySQL-bin.000003',master_log_pos=374;  

    Query OK, 0 rows affected (0.05 sec) 

     

    MySQL> start slave;  

    Query OK, 0 rows affected (0.00 sec) 

     

    MySQL> show slave statusG  

    *************************** 1. row *************************** 

                 Slave_IO_State: Waiting for master to send event 

                    Master_Host: 192.168.1.201 

                    Master_User: replication 

                    Master_Port: 3306 

                  Connect_Retry: 60 

                Master_Log_File: MySQL-bin.000003 

            Read_Master_Log_Pos: 374 

                 Relay_Log_File: MySQL-master2-relay-bin.000002 

                  Relay_Log_Pos: 235 

          Relay_Master_Log_File: MySQL-bin.000003 

               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: 374 

                Relay_Log_Space: 235 

                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 

    1 row in set (0.00 sec) 

    3、将192.168.1.202设为192.168.1.201的主server

    在192.168.1.202上新建授权用户

    MySQL> grant replication slave on *.* to 'replication'@'%' identified by 'replication';  

    Query OK, 0 rows affected (0.00 sec)  

     

    MySQL> show master status; 

    +------------------+----------+--------------+------------------+ 

    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | 

    +------------------+----------+--------------+------------------+ 

    | MySQL-bin.000003 |      374 |              |                  |  

    +------------------+----------+--------------+------------------+ 

    1 row in set (0.00 sec) 

    在192.168.1.201上,将192.168.1.202设为自己的主server

    MySQL> change master to master_host='192.168.1.202',master_user='replication',master_password='replication',master_log_file='MySQL-bin.000003',master_log_pos=374;  

    Query OK, 0 rows affected (0.05 sec)  

     

    MySQL> start slave;  

    Query OK, 0 rows affected (0.00 sec)  

     

    MySQL> show slave statusG 

    *************************** 1. row *************************** 

                 Slave_IO_State: Waiting for master to send event  

                    Master_Host: 192.168.1.202 

                    Master_User: replication 

                    Master_Port: 3306 

                  Connect_Retry: 60 

                Master_Log_File: MySQL-bin.000003 

            Read_Master_Log_Pos: 374 

                 Relay_Log_File: MySQL-master1-relay-bin.000002 

                  Relay_Log_Pos: 235 

          Relay_Master_Log_File: MySQL-bin.000003 

               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: 374 

                Relay_Log_Space: 235 

                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 

    1 row in set (0.00 sec) 

    4、MySQL同步測试

    如上述均正确配置。如今不论什么一台MySQL上更新数据都会同步到还有一台MySQL,MySQL同步在此不再演示

    二、keepalived安装及配置

    1、192.168.1.201server上keepalived安装及配置

    安装keepalived

    #tar zxvf keepalived-1.1.20.tar.gz 

    #cd keepalived-1.1.20  

    #./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/2.6.18-164.el5-i686  

    (注意这里2.6.18-164.el5-i686版本号自己到server的/usr/src/kernels文件夹下去看,写当前server中存在的版本号)

    #make && make install

    [root@master2 ~]#/usr/local/keepalived/sbin/keepalived -D

    [root@master2 ~]# ps -aux|grep keepalived

    Warning: bad syntax, perhaps a bogus '-'?See /usr/share/doc/procps-3.2.7/FAQ

    root     4101  0.3  0.1 35828   632 ?        Ss  15:41   0:00/usr/local/keepalived/sbin/keepalived -D

    root     4102  0.7  0.4 39988  1620 ?        S   15:41   0:00/usr/local/keepalived/sbin/keepalived -D

    root     4103  0.5  0.3 39988  1092 ?        S   15:41   0:00/usr/local/keepalived/sbin/keepalived -D

    root     4106  0.0  0.2 61136   716 pts/0    R+  15:41   0:00 grep keepalived

    配置keepalived

    ln -sv /usr/src/kernels/2.6.18-194.el5-x86_64/ /usr/src/linux

    我们自己在新建一个配置文件,默认情况下keepalived启动时会去/etc/keepalived文件夹下找配置文件

    #mkdir /etc/keepalived  

    #vi /etc/keepalived/keepalived.conf 

    ! Configuration File for keepalived 

    global_defs {  

         notification_email { 

         luwenju@live.cn 

         }  

         notification_email_from luwenju@live.cn 

         smtp_server 127.0.0.1 

         smtp_connect_timeout 30 

         router_id MySQL-ha 

         }  

     

    vrrp_instance VI_1 {  

         state BACKUP   #两台配置此处均是BACKUP  

         interface eth0  #网卡,可使用ifconfig查看

         virtual_router_id 51 

         priority 100   #优先级,还有一台改为90  

         advert_int 1 

         nopreempt  #不抢占,仅仅在优先级高的机器上设置就可以。优先级低的机器不设置  

         authentication { 

         auth_type PASS 

         auth_pass 1111 

         }  

         virtual_ipaddress { 

         192.168.1.200 

         }  

         }  

     

    virtual_server 192.168.1.200 3306 { 

         delay_loop 2   #每一个2秒检查一次real_server状态  

         lb_algo wrr   #LVS算法  

         lb_kind DR    #LVS模式  

         persistence_timeout 60   #会话保持时间  

         protocol TCP 

         real_server 192.168.1.201 3306 { 

         weight 3 

         notify_down /usr/local/MySQL/bin/MySQL.sh  #检測到服务down后运行的脚本  

         TCP_CHECK { 

         connect_timeout 10    #连接超时时间  

         nb_get_retry 3       #重连次数  

         delay_before_retry 3   #重连间隔时间  

         connect_port 3306   #健康检查端口  

         }  

         } 

    编写检測服务down后所要运行的脚本

    #vi /usr/local/MySQL/bin/MySQL.sh  

    #!/bin/sh  

    pkill keepalived  

    #chmod +x /usr/local/MySQL/bin/MySQL.sh 

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

    启动keepalived

    #/usr/local/keepalived/sbin/keepalived –D 

    #ps -aux | grep keepalived 

    測试

    找一台局域网PC,然后去ping  MySQL的VIP,这时候MySQL的VIP是能够ping的通的

    停止MySQL服务。看keepalived健康检查程序是否会触发我们编写的脚本

    2、192.168.1.202上keepalived安装及配置

    安装keepalived

    #tar zxvf keepalived-1.1.20.tar.gz 

    #cd keepalived-1.1.20  

    #./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/2.6.18-164.el5-i686  

    #make && make install 

    配置keepalived

    这台配置和上面基本一样,但有三个地方不同:优先级为90、无抢占设置、real_server为本机IP

    #mkdir /etc/keepalived  

    #vi /etc/keepalived/keepalived.conf 

    ! Configuration File for keepalived 

    global_defs {  

         notification_email { 

         luwenju@live.cn 

         }  

         notification_email_from luwenju@live.cn 

         smtp_server 127.0.0.1 

         smtp_connect_timeout 30 

         router_id MySQL-ha 

         }  

     

    vrrp_instance VI_1 {  

         state BACKUP 

         interface eth0 

         virtual_router_id 51 

         priority 90 

         advert_int 1 

         authentication { 

         auth_type PASS 

         auth_pass 1111 

         }  

         virtual_ipaddress { 

         192.168.1.200 

         }  

         }  

     

    virtual_server 192.168.1.200 3306 { 

         delay_loop 2 

         lb_algo wrr 

         lb_kind DR 

         persistence_timeout 60 

         protocol TCP 

         real_server 192.168.1.202 3306 { 

         weight 3 

         notify_down /usr/local/MySQL/bin/MySQL.sh 

         TCP_CHECK { 

         connect_timeout 10 

         nb_get_retry 3 

         delay_before_retry 3 

         connect_port 3306 

         }  

         } 

    编写检測服务down后所要运行的脚本

    #vi /usr/local/MySQL/bin/MySQL.sh  

    #!/bin/sh  

    pkill keepalived  

    #chmod +x /usr/local/MySQL/bin/MySQL.sh 

     

    启动keepalived  

    #/usr/local/keepalived/sbin/keepalived –D 

    #ps -aux | grep keepalived 

    測试

    停止MySQL服务。看keepalived健康检查程序是否会触发我们编写的脚本

    三、測试

    MySQL远程登录測试

    我们找一台安装有MySQLclient的windows。然后登录VIP,看能否登录,在登录之两台MySQLserver都要授权同意从远程登录

    MySQL> grant all privileges on *.* to 'root'@'%' identified by '123456'; 

    Query OK, 0 rows affected (0.00 sec) 

     

    MySQL> flush privileges;  

    Query OK, 0 rows affected (0.00 sec) 

    使用client登录VIP測试

    C:MySQLin>MySQL.exe -uroot -p123456 -h192.168.1.200 -P3306 

    Welcome to the MySQL monitor.  Commands end with ; or g. 

    Your MySQL connection id is 224 

    Server version: 5.0.89-log Source distribution 

     

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

     

    MySQL> 

    ● keepalived故障转移測试

    ※在windowsclient一直去ping  VIP。然后关闭192.168.1.201上的keepalived,正常情况下VIP就会切换到192.168.1.202上面去

    ※开启192.168.1.201上的keepalived,关闭192.168.1.202上的keepalived,看能否自己主动切换。正常情况下VIP又会属于192.168.1.201

    注:keepalived切换速度还是很块的。整个切换过程仅仅需1-3秒

    ● MySQL故障转移測试

    ※在192.168.1.201上关闭MySQL服务,看VIP是否会切换到192.168.1.202上

    ※开启192.168.1.201上的MySQL和keepalived。然后关闭192.168.1.202上的MySQL。看VIP是否会切换到192.168.1.201上

    以下是用windowsclient连接的MySQL的VIP。在切换时我运行了一个MySQL查询命令,从运行show databases到显示出结果时间为3-5秒(大家能够看到上面有个错误提示,只是不用操心,由于我们的keepalived切换大概为3秒左右,这3秒左右VIP是谁都不属于的)

    MySQL> show databases;  

    ERROR 2006 (HY000): MySQL server has gone away 

    No connection. Trying to reconnect... 

    Connection id:    592 

    Current database: *** NONE *** 

     

    +--------------------+  

    | Database           | 

    +--------------------+  

    | information_schema |  

    | MySQL              | 

    | test               | 

    +--------------------+  

    3 rows in set (9.01 sec) 

    后话:世间万事万物,都不具备绝对的完美,就像上面的MySQL-HA一样,keepalived仅仅能做到对3306的健康检查,可是做不到比方像MySQL复制中的slave-SQL、slave-IO进程的检查。所以要想做到一些仔细的健康检查,还得须要借助额外的监控工具,比方nagios。然后用nagios实现短信、邮件报警,从而可以有效地解决这个问题。

    mysql> GRANT REPLICATION SLAVE ON *.*

       -> TO 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepass';

    假设你没有备份主server。这里是一个创建备份的高速程序。全部步骤都应该在主server主机上运行。

    1.   发出该语句:

        mysql> FLUSH TABLES WITH READ LOCK。

    2.   仍然加锁时,运行该命令(或它的变体):

        shell> tar zcf /tmp/backup.tar.gz /var/lib/mysql

    3.   发出该语句而且确保记录了以后用到的输出:

        mysql>SHOW MASTER STATUS;

    4.   释放锁:

        mysql> UNLOCK TABLES;

    一个可选择的方法是。转储主server的SQL来取代前面步骤中的二进制复制。

    要这样做,你能够在主server上使用mysqldump --master-data。以后装载SQL转储到到你的从server。

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    一致性哈希算法
    Discourse 的标签(Tag)只能是小写的原因
    JIRA 链接 bitbucket 提示错误 Invalid OAuth credentials
    JIRA 如何连接到云平台的 bitbucket
    Apache Druid 能够支持即席查询
    如何在 Discourse 中配置使用 GitHub 登录和创建用户
    Apache Druid 是什么
    Xshell 如何导入 PuTTYgen 生成的 key
    windows下配置Nginx支持php
    laravel连接数据库提示mysql_connect() :Connection refused...
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4885693.html
Copyright © 2011-2022 走看看