zoukankan      html  css  js  c++  java
  • MHA高可用架构解决方案

    MHA高可用架构解决方案

    欢迎来到 来到大浪涛天的博客

    一、MHA高可用架构解决方案

    1. MHA的介绍

    • MHA(Master High Availability)目前在 MySQL 高可用方面是一个相对成熟的解决方案,它由日本 DeNA 公司的 youshimaton(现就职于 Facebook 公司)开发,是一套优秀的作为 MySQL 高可用性环境下故障切换和主从提升的高可用软件。
    • 在 MySQL 故障切换过程中,MHA 能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA 能在最大程度上保证数据的一致性,以达到真正意义上的高可用。
    • 该软件由两部分组成:MHA Manager(管理节点)和 MHA Node(数据节点)。MHA Manager 可以单独部署在一台独立的机器上管理多个 master-slave 集群,也可以部署在一台 slave 节点上。MHA Node 运行在每台 MySQL 服务器上,MHA Manager 会定时探测集群中的 master 节点,当 master 出现故障时,它可以自动将最新数据的 slave 提升为新的 master,然后将所有其他的 slave 重新指向新的 master。整个故障转移过程对应用程序完全透明。
    • 在 MHA 自动故障切换过程中,MHA 试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。例如,如果主服务器硬件故障或无法通过ssh访问,MHA 没法保存二进制日志,只进行故障转移而丢失了最新的数据,可以使用数据补偿模式,增加一个slave不用于切换只是用于拉取二进制日志。如果只有一个 slave 已经收到了最新的二进制日志,MHA 可以将最新的二进制日志应用于其他所有的 slave 服务器上,因此可以保证所有节点的数据一致性。
    • 目前 MHA 主要支持一主多从的架构,要搭建 MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当 master,一台充当备用 master,另外一台充当从库,因为至少需要三台服务器,出于机器成本的考虑,淘宝也在该基础上进行了改造,目前淘宝TMHA已经支持一主一从。

    2. MHA集群结构说明

    MHA一般至少是需要3台数据库服务器,而且额外还需要一台服务器来做为Manager端。如下图所示,一般的生产应用中,Manager是用来管理多个应用数据库集群的,它只是用来监测每个应用的master端是否故障,如果故障自动进行切换,因此资源占用并不高。
    MHA集群结构说明

    2-1. 服务角色

    2-1-1. MHA Manager:

    通常单独部署在一台独立机器上管理多个 master/slave 集群(组),每个 master/slave 集群称作一个 application,用来管理统筹整个集群。

    2-1-2. MHA node:

    主要是接收管理节点所发出指令的代理,代理需要运行在每一个 mysql 节点上。简单讲 node 就是用来收集从节点服务器上所生成的 bin-log 。对比打算提升为新的主节点之上的从节点的是否拥有并完成操作,如果没有发给新主节点在本地应用后提升为主节点。每个复制组内部和 Manager 之间都需要ssh实现无密码互连,只有这样,在 Master 出故障时, Manager 才能顺利的连接进去,实现主从切换功能。

    2-2. MHA提供的工具脚本

    MHA会提供诸多工具程序, 其常见的如下所示:
    Manager节点:mha4mysql-manager-0.56-0.el6.noarch.rpm

          masterha_check_ssh:MHA 依赖的 ssh 环境监测工具;
      masterha_check_repl:MYSQL 复制环境检测工具;
      masterga_manager:MHA 服务主程序;
      masterha_check_status:MHA 运行状态探测工具;
      masterha_master_monitor:MYSQL master 节点可用性监测工具;
      masterha_master_swith:master:节点切换工具;
      masterha_conf_host:添加或删除配置的节点;
      masterha_stop:关闭 MHA 服务的工具。

    Node节点:(这些工具通常由MHA Manager的脚本触发,无需人为操作)
    mha4mysql-node-0.56-0.el6.noarch.rpm

      save_binary_logs:保存和复制 master 的二进制日志;
      apply_diff_relay_logs:识别差异的中继日志事件并应用于其他 slave;
      purge_relay_logs:清除中继日志(不会阻塞 SQL 线程);

    自定义扩展:

      secondary_check_script:通过多条网络路由检测master的可用性;
      master_ip_failover_script:更新application使用的masterip;
      report_script:发送报告;
      init_conf_load_script:加载初始配置参数;
      master_ip_online_change_script;更新master节点ip地址。

    2-3. MHA工作原理

    MHA failover的过程
    MHA failover的过程

    2-3-1. MHA Failover实现方式

    (1) MHA通过masterha_manger脚本启动MHA的功能.
    
    (2) 在manager启动之前,会自动检查ssh互信(masterha_check_ssh)和主从状态(masterha_check_repl)
    
    (3) MHA-manager 通过 masterha_master_monitor脚本(每隔ping_interval秒)
    
    (4) masterha_master_monitor探测主库3次无心跳之后,就认为主库宕机了.
    
    (5) 进行选主过程
    	算法一: 
    	读取配置文件中是否有强制选主的参数?
    	candidate_master=1
    	check_repl_delay=0
    	算法二:
    	自动判断所有从库的日志量.将最接近主库数据的从库作为新主.
    	算法三:
    	按照配置文件先后顺序的进行选新主.

    2-4. candidate_master=1 应用场景

    (1) MHA+KeepAlive VIP(早期MHA架构)
    (2) 多地多中心

    2-5. 数据补偿

    判断主库SSH的连通性
    情况一: SSH能连
    调用 save_binary_logs脚本,立即保存缺失部分的binlog到各个从节点,恢复
    情况二: SSH无法连接
    调用 apply_diff_relay_logs 脚本,计算从库的relaylog的差异,恢复到2号从库

    2-6. MHA 应用透明(vip)

    1. MHA会根据配置文件调用master_ip_failover.txt脚本,实现VIP的浮动。
    2. 在 /etc/mha/app01.cnf中添加该脚本
      master_ip_failover_script=/usr/local/bin/master_ip_failover
    3. 第一次启动需要自己手动添加vip
     [root@db01 ~]# ifconfig eth0:1 10.211.55.85/24 
     4. 业务采用VIP,当主库down后,VIP会自己切换到选的下一个master上,这样对业务来说是透明的,因为ip都一样,业务不会知道已经切换到了另外一个库上。

    2-7. MHA 故障提醒

    1. MHA会根据配置文件调用/usr/local/bin/send脚本,实现有故障会主动发邮件通知。
    2. 在 /etc/mha/app01.cnf中添加该脚本
     report_script=/usr/local/bin/send

    2-8. 设置binlog server

    1. 为了最大减少数据丢失,我们可以选取一台服务器专门负责拉取主库二进制日志,而且该binlog server不进行选主,只是为了拉去binlog
    2. 在配置文件中添加binlog设置
      /etc/mha/app1.cnf 
    [binlog1]
    no_master=1
    hostname=10.0.0.53
    master_binlog_dir=/data/mysql/binlog
    3. 创建该目录,并赋予对应的权限
    mkdir -p /data/mysql/binlog
    chown -R mysql.mysql /data/*
    4. 拉取二进制日志
    cd /data/mysql/binlog     -----》必须进入到自己创建好的目录
    mysqlbinlog  -R --host=10.0.0.51 --user=mha --password=mha --raw  --stop-never mysql-bin.000001 &
    注意:
    拉取日志的起点,需要按照目前主库正在使用的binlog为起点.
    5.  修改完配置文件都需要进行重启mha服务
    [root@db03 bin]# masterha_stop --conf=/etc/mha/app1.cnf
    [root@db03 bin]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover  < /dev/null> /var/log/mha/app1/manager.log 2>&1 &

    3. MHA搭建配置

    3-1. MHA搭建环境

    为了节省虚拟机,因此规划3台虚拟机来搭建,分别为DB01和DB02及DB03,其中DB01为master,因为master压力较大,因此选DB03来安装mha manger,防止mha轻易挂掉,当然正常生产环境MHA管理节点应该是独立的一个主机,如图:
    MHA环境搭建

    3-1-1. MHA搭建具体实施步骤

    3-1-1-1. 配置关键程序软连接
    ln -s /application/mysql/bin/mysqlbinlog    /usr/bin/mysqlbinlog
    ln -s /application/mysql/bin/mysql          /usr/bin/mysql
    3-1-1-2. 配置互信
    #创建密钥对       如果没有该命令 yum -y install openssh-clients  安装
    [root@mysql-db03 ~]# ssh-keygen -t dsa -P "" -f ~/.ssh/id_dsa >/dev/null 2>&1
    #发送mysql-db03公钥,包括自己
    [root@mysql-db03 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.81
    [root@mysql-db03 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.82
    [root@mysql-db03 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.83
    #发送mysql-db02公钥,包括自己
    [root@mysql-db02 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.81
    [root@mysql-db02 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.82
    [root@mysql-db02 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.83
    #发送mysql-db01公钥,包括自己
    [root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.81
    [root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.82
    [root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.211.55.83
    3-1-1-3. 检查互信是否成功
    db01:
    ssh 10.211.55.81 hostname
    ssh 10.211.55.82 hostname
    ssh 10.211.55.83 hostname
    db02:
    ssh 10.211.55.81 hostname
    ssh 10.211.55.82 hostname
    ssh 10.211.55.83 hostname
    db03:
    ssh 10.211.55.81 hostname
    ssh 10.211.55.82 hostname
    ssh 10.211.55.83 hostname
    3-1-1-4. 安装软件包(所有节点)
    yum install perl-DBD-MySQL -y
    rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm
    3-1-1-5. 基于GTID配置主从同步:
    1. 准备环境
    pkill mysqld
    
    m -rf /data/mysql/data/*
    
    m -rf /data/binlog/*
    1. 准备配置文件

    主库db01:

    
    cat > /etc/my.cnf <<EOF
    [mysqld]
    basedir=/application/mysql/
    datadir=/data/mysql/data
    socket=/tmp/mysql.sock
    server_id=81
    port=3306
    secure-file-priv=/tmp
    autocommit=0
    log_bin=/data/binlog/mysql-bin
    binlog_format=row
    gtid-mode=on
    enforce-gtid-consistency=true
    log-slave-updates=1
    [mysql]
    prompt=db01 [\d]>
    EOF

    slave1(db02):

    cat > /etc/my.cnf <<EOF
    [mysqld]
    basedir=/application/mysql
    datadir=/data/mysql/data
    socket=/tmp/mysql.sock
    server_id=82
    port=3306
    secure-file-priv=/tmp
    autocommit=0
    log_bin=/data/binlog/mysql-bin
    binlog_format=row
    gtid-mode=on
    enforce-gtid-consistency=true
    log-slave-updates=1
    [mysql]
    prompt=db02 [\d]>
    EOF

    slave2(db03):

    cat > /etc/my.cnf <<EOF
    [mysqld]
    basedir=/application/mysql
    datadir=/data/mysql/data
    socket=/tmp/mysql.sock
    server_id=83
    port=3306
    secure-file-priv=/tmp
    autocommit=0
    log_bin=/data/binlog/mysql-bin
    binlog_format=row
    gtid-mode=on
    enforce-gtid-consistency=true
    log-slave-updates=1
    [mysql]
    prompt=db03 [\d]>
    EOF
    1. 创建用户
    useradd -s /sbin/nologin mysql
    1. 创建必须的目录
    mkdir -p /data/binlog/
    mkdir -p /data/mysql/data
    chown -R mysql.mysql /data
    1. 初始化数据
    mysqld --initialize-insecure --user=mysql --basedir=/application/mysql  --datadir=/data/mysql/data 
    1. 启动路径systemctl启动
    cat >/etc/systemd/system/mysqld.service <<EOF
       [Unit]
       Description=MySQL Server
       Documentation=man:mysqld(8)
       Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
       After=network.target
       After=syslog.target
       [Install]
       WantedBy=multi-user.target
       [Service]
       User=mysql
       Group=mysql
       ExecStart=/application/mysql/bin/mysqld --defaults-file=/etc/my.cnf
       LimitNOFILE = 5000
     EOF
    1. 复制启动脚本 /etc/init.d/mysqld start启动
     cp /application/mysql/support-files/mysql.server  /etc/init.d/mysqld
     修改一下
     basedir=/application/mysql
     datadir=/data/mysql/data
    1. 启动数据库
    /etc/init.d/mysqld start
    1. 构建主从:
    master:81
    slave:82,83
    
    81:
    grant replication slave  on *.* to repl@'10.211.55.%' identified by 'admin123';
    
    8283:
    change master to 
    master_host='10.211.55.81',
    master_user='repl',
    master_password='admin123' ,
    MASTER_AUTO_POSITION=1;
    start slave;
    3-1-1-6. 在db01主库中创建mha需要的用户
    grant all privileges on *.* to mha@'10.211.55.%' identified by 'mha';
    3-1-1-7. Manager软件安装(db03)
    yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
    rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm
    3-1-1-7-1. 配置文件准备(db03)
    	创建配置文件目录
     mkdir -p /etc/mha
    	创建日志目录
     mkdir -p /var/log/mha/app1
    	编辑mha配置文件
    cat > /etc/mha/app1.cnf <<EOF
    [server default]
    manager_log=/var/log/mha/app1/manager        
    manager_workdir=/var/log/mha/app1            
    master_binlog_dir=/data/binlog       
    user=mha                                   
    password=mha                               
    ping_interval=2
    repl_password=admin123
    repl_user=repl
    ssh_user=root                               
    [server1]                                   
    hostname=10.211.55.81
    port=3306                                  
    [server2]            
    hostname=10.211.55.82
    port=3306
    [server3]
    hostname=10.211.55.83
    port=3306
    EOF
    3-1-1-8. MHA 应用透明(vip)-db03
    cp /root/master_ip_failover.txt /usr/local/bin/master_ip_failover
    
    vim /usr/local/bin/master_ip_failover
    my $vip = '10.211.55.85/24';
    my $key = '1';
    my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
    my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
    
    [root@db03 bin]# chmod +x /usr/local/bin/master_ip_failover
    [root@db03 bin]# yum install -y  dos2unix
    [root@db03 bin]# dos2unix /usr/local/bin/master_ip_failover 
    
    [root@db03 bin]# vim /etc/mha/app1.cnf 
    master_ip_failover_script=/usr/local/bin/master_ip_failover
    
    db01:手工添加vip
    [root@db01 ~]# ifconfig eth0:1 10.211.55.85/24
    
    3-1-1-9. MHA 故障提醒
    [root@db03 ~]# cp -a email/* /usr/local/bin/
    [root@db03 ~]# cd /usr/local/bin/
    [root@db03 ]# chmod +x *
    
    [root@db03 bin]# vim /etc/mha/app1.cnf 
    report_script=/usr/local/bin/send
    3-1-1-10. 额外的数据补偿(binlog_server)
    找一台额外的机器,必须要有5.6以上的版本,支持gtid并开启,我们直接用的第二个slave(db03)
    
    vim /etc/mha/app1.cnf 
    [binlog1]
    no_master=1
    hostname=10.211.55.83
    master_binlog_dir=/data/mysql/binlog
    
    (2) 创建必要目录
    mkdir -p /data/mysql/binlog
    chown -R mysql.mysql /data/*
    
    (3) 拉取主库binlog日志
    
    cd /data/mysql/binlog     -----》必须进入到自己创建好的目录
    mysqlbinlog  -R --host=10.211.55.81 --user=mha --password=mha --raw  --stop-never mysql-bin.000002 &
    
    注意:
    拉取日志的起点,需要按照目前主库正在使用的binlog为起点.
    3-1-1-11. 状态检查及开启MHA(db03)
     masterha_check_ssh  --conf=/etc/mha/app1.cnf 
     masterha_check_repl  --conf=/etc/mha/app1.cnf 
     
    nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover  < /dev/null> /var/log/mha/app1/manager.log 2>&1 &
    
    3-1-1-12. 查看MHA状态
    [root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
    app1 (pid:10074) is running(0:PING_OK), master:10.211.55.81

    4. MHA故障模拟及恢复处理

    4-1. 宕掉 db01 数据库

    [root@db01 ~]# /etc/init.d/mysqld stop
    过了5秒后查看db02数据库看看vip是否已经飘过来了
    [root@db02 ~]# ifconfig -a |grep -A3 eth0:1
    eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 10.211.55.85  netmask 255.255.255.0  broadcast 10.211.55.255
            ether 00:1c:42:06:3d:8f  txqueuelen 1000  (Ethernet)

    4-2. 恢复故障

    4-2-1. 启动故障节点

    [root@db01 ~]# /etc/init.d/mysqld start

    4-2-2. 恢复1主2从(db01)

    在mha的管理日志中可以看到change master to的指令,直接把MASTER_PASSWORD密码改掉就可以直接用了
    [root@db03 bin]# grep "CHANGE MASTER TO"  /var/log/mha/app1/manager
    [info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx';
    
    db01执行完change master to后启动slave
    [root@db03 bin]# 
    db01 [(none)]>CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';
    db01 [(none)]>start slave;

    4-2-3. 恢复配置文件(db03)

    db03中恢复db01和binlog的配置文件

    [server1]
    hostname=10.0.0.51
    port=3306
    [server2]
    hostname=10.0.0.52
    port=3306
    [server3]
    hostname=10.0.0.53
    port=3306
    [binlog1]
    no_master=1
    hostname=10.211.55.83
    master_binlog_dir=/data/mysql/binlog

    恢复binlogserver

    cd /data/mysql/binlog    
    rm -rf /data/mysql/binlog/*
    mysqlbinlog  -R --host=10.0.0.52 --user=mha --password=mha --raw  --stop-never mysql-bin.000001 &

    4-2-4. 启动MHA

    [root@db03 bin]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover  < /dev/null> /var/log/mha/app1/manager.log 2>&1 &
    [1] 16543
    [root@db03 bin]# masterha_check_status --conf=/etc/mha/app1.cnf
    app1 (pid:16543) is running(0:PING_OK), master:10.0.0.52

    5. 总结

    1. MHA 是一次性的,当MHA自动恢复主库成功后,MHA的监控自动会断开,需要我们把环境重新整理好,比如修复之前down掉的master,修复binlogserver,修复好配置文件,再重新启动MHA服务 ,虽然麻烦,但是它能让业务透明的情况下0-30秒内切换自动切换主库,让全年可靠性达到99.9%,还是非常理想的。
    2. MHA是单活的一个集群系统,意味着只能让可靠性增强,而不能实现proxy这种均分压力的能力,因此一般配置MHA的情况下,如果压力繁忙,还会让MHA的环境搭建中间件(atlas,mycat等),完成读写分离或者分库,分表,来分担主库的压力。
  • 相关阅读:
    I.MX6 sdio 设备注册及识别
    linux串口查看命令
    连词
    相形-声似词汇
    replace A with B是用A代替B还是用B代替A?
    无监督、弱监督、半监督、强化、多示例学习是什么
    JS散度(Jensen-Shannon)
    embedding是什么
    httpclient: 设置请求的超时时间,连接超时时间等
    httpclient工具使用(org.apache.httpcomponents.httpclient)
  • 原文地址:https://www.cnblogs.com/chacha51/p/13819075.html
Copyright © 2011-2022 走看看