ubuntu下基于keepalived 搭建 mysql主备集群

2016/7/12 posted in  linux

mysql集群的几种方式

Mysql集群,总得来说方法比较多,而且由于是各种开源商提供的,所以每个集群方式同样各有利弊。大概的总结归纳一下:

LVS+Keepalived+MySQL
DRBD+Heartbeat+MySQL
MySQL Proxy
MySQL Cluster
MySQL + MHA
MySQL + MMM
淘宝的Cola
变形虫Amoeba
等等方案

参考别人的一些小建议:
1.若是双主复制的模式,不用做数据拆分,那么就可以选择MHA或 Keepalive 或 heartbeat
2.若是双主复制,还做了数据的拆分,则可以考虑采用Cobar;
3.若是双主复制+Slave,还做了数据的拆分,需要读写分类,可以考虑Amoeba;

上述所有的内容都要依据公司内部的业务场景、数据量、访问量、并发量、高可用的要求、DBA人群的数量等 综合权衡

主要有 keepalived+双主,MHA,MMM,Heartbeat+DRBD,PXC,Galera Cluster

比较常用的是keepalived+双主,MHA和PXC。

后面再对每种有时间做一些详细的研究,当前由于对于其他的需求不高,先使用最快速的keepalived+mysql复制的方式来制作主备模式

mysql keepalived 主备集群方法

对于小型的公司,较小型的系统,维护人员不多,但又为了保证基本的服务持久性,还是建议可以使用keepalived的方式来部署,这种方式比较简单,而且对于运维人员的不多的时候,也较容易定位问题

当前部署就用测试环境上面的内容

VIP 192.168.11.140
master1 192.168.11.133
master2 192.168.11.134

安装mysql 服务等

安装mysql就不多说了,这里做demo,简单的采用apt-get安装就可以

    sudo apt-get update
    sudo apt-get install mysql-server
修改数据库配置参数

ubuntu安装后数据库配置文件在/etc/mysql/my.cnf

修改主备上的配置文件。

master1

    [mysqld]
    log-bin=mysql-bin
    server-id=1
    log_slave_updates=1

master2

    [mysqld]
    log-bin=mysql-bin
    server-id=2
    log_slave_updates=1
    read_only=1

如果需要远程访问的话,这个文件中的bind-address也记得修改一下,否则可能无法访问。把bind-address注释掉表示可以允许所有的连接访问。但是这样的安全性会比较低,在里面也可以使用通配符来进行匹配

创建数据复制用户

我们使用mysql自带的数据复制方式来进行基于日志的数据复制,在master上修改之后会立即同步到slave上。

首先要创建相关复制用户,这个用户可以不需要用于登陆,专门用于在两个数据库之间复制数据。

master1:

    CREATE USER 'firephoenix'@'192.168.11.134' IDENTIFIED BY '123456';
    GRANT REPLICATION SLAVE ON *.* TO 'firephoenix'@'192.168.11.134';

master2:

    CREATE USER 'firephoenix'@'192.168.11.133' IDENTIFIED BY '123456';
    GRANT REPLICATION SLAVE ON *.* TO 'firephoenix'@'192.168.11.133';

tips: 使用mysql -uroot -p123456 可以直接登陆mysql,而不需要交互密码。这也是某次在使用shell连接数据库的时候一直希望解决的一个问题,终于在这里找到了相关的解决办法。

创建复制集群

如果是从头搭建的话,就不需要获取全局锁来得到二进制文件的位置,直接通过show master status 就可以看到了

可以看到其中的File就是日志文件名称,Position就是日志文件当前的位置

我们需要在mysql 中执行同步到另外一边的相关file 和 postion

master1:

    CHANGE MASTER TO
    MASTER_HOST='192.168.11.134',
    MASTER_USER='firephoenix',
    MASTER_PASSWORD='123456',
    MASTER_LOG_FILE='mysql-bin.000037',
    MASTER_LOG_POS=335;

master2:

    CHANGE MASTER TO
    MASTER_HOST='192.168.11.133',
    MASTER_USER='firephoenix',
    MASTER_PASSWORD='123456',
    MASTER_LOG_FILE='mysql-bin.000007',
    MASTER_LOG_POS=107;

其中MASTER_HOST为对端IP值,后面是同步的用户名和密码。 MASTER_LOG_FILE 为对端的日志文件名称和位置,这里可以使用show master status来查询。

把这两个执行完成之后,在主、备上分别执行 start slave; 就可以启动

可以通过show slave status\G来查询主备同步的状态,其中比较重要的字段就是

    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes

如果这里是connecting ,则说明配置里面有问题,一般的情况下都是由于主备mysql之间无法通信造成的,一般是网络或者密码问题。

这里配置完成之后,就可以试试看数据库的主从了,在一边创建数据库、表、值,都可以同步到另外一边。

安装keepalived

安装也不太多的说明了,这里比较简化的直接使用apt-get安装即可

keepalived主要处理主备间切换时候的VRRP的浮动ip的处理。

keepalived配置文件

keepalived会自动去读取_etc_keepalived/文件夹下面的配置文件,所以在该文件夹下面直接创建keepalived.conf文件即可,文件内容如下

master1:

    global_defs {
        route_id MYSQL_MASTER
    }
    vrrp_instance VI_1 {
        state BACKUP       #通过下面的priority来区分MASTER和BACKUP,也只有如此,底下的nopreempt才有效
        interface eth0
        virtual_router_id 133
        priority 101
        advert_int 1
        nopreempt           #防止切换到从库后,主keepalived恢复后自动切换回主库
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
            192.168.11.140
        }
    }
    virtual_server 192.168.11.140 3306 {
        delay_loop 2
        lb_algo rr
        lb_kind DR
        persistence_timeout 50
        protocol TCP
        real_server 192.168.11.133 3306 {
            weight 3
            notify_down /etc/keepalived/mysql.sh
            TCP_CHECK {
                connect_port 3306
                connect_timeout 3
                nb_get_retry 2
                delay_before_retry 1
            }   
        }
    }

master2:

    bal_defs {
        route_id MYSQL_MASTER
    }
    vrrp_instance VI_1 {
        state BACKUP       #通过下面的priority来区分MASTER>和BACKUP,也只有如此,底下的nopreempt才有效
        interface eth0
        virtual_router_id 133
        priority 50
        advert_int 1
        nopreempt           #防止切换到从库后,主keepalived恢复后自动切换回主库
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
            192.168.11.140
        }
    }
    virtual_server 192.168.11.140 3306 {
        delay_loop 2
        lb_algo rr
        lb_kind DR
        persistence_timeout 50
        protocol TCP
        real_server 192.168.11.134 3306 {
            weight 3
            notify_down /etc/keepalived/mysql.sh
            TCP_CHECK {
                connect_port 3306
                connect_timeout 3
                nb_get_retry 2
                delay_before_retry 1
            }
        }
    }

将两个的state都设置为backup,好处是当主机出现故障,切到备机后,主机重启能够通过优先级重新成为主机,保证主备的服务循环。

privority 主机的优先级需要高于备机的优先级。

在最下面会加上virtual_server来判断相关的虚拟服务,并且在其中添加如果跳转到真是服务器,会去执行/etc/keepalived/mysql.sh这一段脚本,这里的意思是,如果发生了主备切换,那么我们应该杀掉所有的keepalived的进程。

/etc/keepalived/mysql.sh文件内容

    #!/bin/bash
    pkill keepalived

同时增加这个文件的执行权限到755

启动数据库和keepalived

接下来顺序启动这两个服务,主备服务就配置好了。

    service mysql start
    service keepalived start

启动完成后可以通过ip的状态来查看主备情况,浮动ip 现在在那边

主机上面会有192.168.11.140的浮动ip,备机上面没有。

此时用这个ip来连接数据库就可以。

测试主备切换

首先使用service mysql stop 来停止主机上面的 数据库服务。来模拟主机数据库服务异常。

这时浮动ip会切换到备机上,同时备机提供服务。使用远程访问,浮动ip依然可以访问成功。此时可以在向备机中插入数据。主机暂时无法访问。同时主机访问ps -ef|grep keepalived可以看到主机的keepalived服务已经停止了。

然后启动主机的mysql服务,此时数据会进行同步。然后再启动主机的service keepalived start,这是可以看到浮动ip 过一下又会浮动到主机上面来。说明此时主机启动后,由于优先级较高,抢占了master。但是此时好像备机的浮动ip在ip端还是会显示,这里应该是一个bug,在重启网卡/etc/init.d/networking restart之后会没有。

总结

这里测试完成了主备切换,是可用的。但是当前的方案下,主机恢复之后,可以将主机的mysql和keepalived服务加到开启重启,那么重启之后就可以自恢复了。

所以这种主备的情况是,当主出现问题切换到备的时候,我们需要立即有通知机制告知,否则在主未启动的情况下面,备在挂掉,则就会出现数据库丢失。

但是这种对于小型的网站做冗余已经非常好了。