zoukankan      html  css  js  c++  java
  • 8.MHA高可用集群+Atlas读写分离

    所有软件下载地址:链接:https://share.weiyun.com/QEgshNc8 密码:hg8mnz

    MHA修复流程说明

    (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     #不管这台机器和主库相差多少数据,都忽略
    	算法二:
    	自动判断所有从库的日志量.将最接近主库数据的从库作为新主.
    	算法三:
    	按照配置文件先后顺序的进行选新主.
    (6) 数据补偿 
            判断主库SSH的连通性
            情况一: SSH能连
            调用 save_binary_logs脚本,立即保存缺失部分的binlog到各个从节点,恢复
            情况二: SSH无法连接
            调用 apply_diff_relay_logs 脚本,计算从库的relaylog的差异,恢复到2号从库
            情况三:提供额外的binlog-server
    (7) 解除从库身份
    (8) 剩余从库和新主库构建主从关系
    (9) 应用透明  @@
    (10) 故障节点自愈(待开发...)@@
    (11) 故障提醒@
    (12) 手动修复故障主库,并将故障主库身份转换成从库,修改MHA管理端配置文件,修改binlog server指向的地址

    MHA搭建环境前提条件
    1.最少三台MySQL服务器,1主2从。
    2.MHA管理端不能放在MySQL主服务器上。
    3.MHA为一次性环境,故障处理完毕后需要手动调整
    4.在搭建MHA之前,三台数据库需要同时有MHA管理用户和mysql复制用户
    5.MHA可以同时管理多个不同的mysql集群,启动MHA管理端时指定不同的配置文件即可

    开始搭建

    • 1.准备3三台mysql服务器,搭建好主从环境,所有节点都需要开启bin_log,额外准备一台MHA管理服务器,一共四台服务器
    • 2.所有Mysql3台节点创建MHA需要用到的软连接,源节点根据软件安装情况更改,目标节点必须在/usr/bin下(就算mysql命令在环境变量中也需要链接到该目录下)
    ln -s /application/mysql/bin/mysqlbinlog    /usr/bin/mysqlbinlog
    ln -s /application/mysql/bin/mysql          /usr/bin/mysql
    
    • 3.所有主机进行免密认证
    # ssh-keygen
    # ssh-copy-id
    
    #各节点验证,避免出现输入yes的情况
    
    • 4.在mysql主库创建MHA用户(这个用户在三台mysql服务器上都需要创建,如果提前做好了主从,只需要在主库创建这个用户)
    mysql> grant all privileges on *.* to mha@'%' identified by 'mha';
    • 5.所有节点安装节点软件包(四个节点都装)
    #安装依赖
    yum install perl-DBD-MySQL -y
    #安装节点包
    rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm
    
    • 6.MHA管理节点安装管理软件(只有MHA管理节点安装)
    #安装依赖
    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
    
    • 7.创建MHA节点配置文件(只有MHA管理节点需要这个配置文件)
    #创建配置文件目录
    mkdir -p /etc/mha
    #创建日志目录,可以同时管理多个节点
    mkdir -p /var/log/mha/app1
    
    #编辑mha配置文件,针对app1集群的配置
    cat > /etc/mha/app1.cnf <<EOF
    [server default]
    #日志文件名称,程序运行日志,排错都在这里面看
    manager_log=/var/log/mha/app1/manager        
    #工作目录
    manager_workdir=/var/log/mha/app1            
    #mysql数据库存放binlog位置,mha会监控这个日志
    master_binlog_dir=/var/lib/mysql       
    #mha管理用户名
    user=mha        
    #mha管理用户密码                           
    password=mha    
    #心跳检测间隔时间                           
    ping_interval=2
    #mysql复制用户密码
    repl_password=123
    #MySQL复制用户名
    repl_user=repl
    #ssh用户
    ssh_user=root    
    #高可用IP漂移脚本,下面会给出配置 
    master_ip_failover_script=/usr/local/bin/master_ip_failover                          
    #故障切换完成后发送邮件的脚本
    report_script=/usr/local/bin/send
    
    #管理的mysql实例位置,故障选主时,从上至下顺序选主
    [server1]                                   
    hostname=192.168.2.3
    port=3306                                  
    [server2]            
    hostname=192.168.2.4
    port=3306
    [server3]
    hostname=192.168.2.5
    port=3306
    
    #数据补偿服务器,强制不能成为主库,二进制日志保存路径不能和mysql服务器二进制日志保存路径相同
    [binlog1]
    no_master=1
    hostname=192.168.2.5
    master_binlog_dir=/data/mysql/binlog
    EOF
    
      • 7.1主从切换脚本

    这个脚本由perl语言编写,只需要对应更改下面内容,脚本文件放在MHA管理端配置文件master_ip_failover_script=/usr/local/bin/master_ip_failover对应位置,需要添加+x执行权限

    my $vip = '192.168.3.88/24';     #高可用出来的VIP
    my $key = '1';             #子网卡序号,例如eth0:1
    my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";    #开启vip,对应改网卡名
    my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";  #关闭vip,对应改网卡名

    [root@nginx ~]# cat /usr/local/bin/master_ip_failover
    #!/usr/bin/env perl
    
    use strict;
    use warnings FATAL => 'all';
    
    use Getopt::Long;
    
    my (
        $command,          $ssh_user,        $orig_master_host, $orig_master_ip,
        $orig_master_port, $new_master_host, $new_master_ip,    $new_master_port
    );
    
    my $vip = '192.168.3.88/24';
    my $key = '1';
    my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
    my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";
    
    GetOptions(
        'command=s'          => $command,
        'ssh_user=s'         => $ssh_user,
        'orig_master_host=s' => $orig_master_host,
        'orig_master_ip=s'   => $orig_master_ip,
        'orig_master_port=i' => $orig_master_port,
        'new_master_host=s'  => $new_master_host,
        'new_master_ip=s'    => $new_master_ip,
        'new_master_port=i'  => $new_master_port,
    );
    
    exit &main();
    
    sub main {
    
        print "
    
    IN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===
    
    ";
    
        if ( $command eq "stop" || $command eq "stopssh" ) {
    
            my $exit_code = 1;
            eval {
                print "Disabling the VIP on old master: $orig_master_host 
    ";
                &stop_vip();
                $exit_code = 0;
            };
            if ($@) {
                warn "Got Error: $@
    ";
                exit $exit_code;
            }
            exit $exit_code;
        }
        elsif ( $command eq "start" ) {
    
            my $exit_code = 10;
            eval {
                print "Enabling the VIP - $vip on the new master - $new_master_host 
    ";
                &start_vip();
                $exit_code = 0;
            };
            if ($@) {
                warn $@;
                exit $exit_code;
            }
            exit $exit_code;
        }
        elsif ( $command eq "status" ) {
            print "Checking the Status of the script.. OK 
    ";
            exit 0;
        }
        else {
            &usage();
            exit 1;
        }
    }
    
    sub start_vip() {
        `ssh $ssh_user@$new_master_host " $ssh_start_vip "`;
    }
    sub stop_vip() {
         return 0  unless  ($ssh_user);
        `ssh $ssh_user@$orig_master_host " $ssh_stop_vip "`;
    }
    
    sub usage {
        print
        "Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port
    ";
    }
    
      • 7.2故障修复后发送邮件程序

    三个文件如下,放在服务器上之后都需要有执行权限,脚本必须放在/usr/local/bin下

    只需要修改testpl配置文件中的内容,MHA管理端只会调用send脚本,后续操作都有send脚本自行操作。(文件需要对应修改邮箱密码信息)

    [root@nginx ~]# vim /usr/local/bin/testpl 
    #!/bin/bash
    /usr/local/bin/sendEmail -o tls=no -f 发送邮件邮箱@126.com -t 接收邮件邮箱@qq.com -s smtp.126.com:25 -xu 发送邮箱的用户 -xp 发送邮箱的认证码 -u "MHA Waring" -m "YOUR MHA MAY BE FAILOVER" &>/tmp/sendmail.log  
      • 7.3数据补偿服务器
    [binlog1]
    no_master=1
    hostname=192.168.2.5
    master_binlog_dir=/data/mysql/binlog
    

    MHA管理端的这三条配置是binlog-server的配置,需要在对应服务器上创建该目录,并手动拉取数据。
    MHA完成故障切换后,拉取二进制日志的主机需要重新配置mysql主库地址

    #创建必要目录
    mkdir -p /data/mysql/binlog
    chown -R mysql.mysql /data/*
    
    #手动拉取主库binlog日志
    cd /data/mysql/binlog    #必须进入到自己创建好的目录
    mysqlbinlog  -R --host=10.0.0.51 --user=mha --password=mha --raw  --stop-never mysql-bin.000001 &
    
    #注意:拉取日志的起点 mysql-bin.000001,需要按照目前主库正在使用的binlog为起点.
    • 8.MHA管理端进行状态检查(只有MHA管理端有这个命令)
    #检查主机ssh状况
    masterha_check_ssh  --conf=/etc/mha/app1.cnf 
    #出现下面状态代表ssh状态正常
    #[info] All SSH connection tests passed successfully.
    
    #检查mysql复制状况
    masterha_check_repl  --conf=/etc/mha/app1.cnf 
    #出现下面状态代表mysql复制状态正常
    #MySQL Replication Health is OK.
    
    • 9.第一次开启MHA前,需要手动在mysql主库服务器上添加VIP,后续漂移VIP是由MHA自动完成
    /sbin/ifconfig ens33:1 192.168.2.88/24 up 
    • 10.检查顺利完成后,MHA节点开启管理端(MHA管理程序会以守护进程运行)
    nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover  &> /var/log/mha/app1/manager.log  &
    
    #--conf:指定配置文件
    #--remove_dead_master_conf:mysql主库故障时,MHA自动从配置文件中移除坏掉的master
    #--ignore_last_failover:MHA切换主从后的8个小时内,如果mysql主库再次出现故障,MHA不会进行切换,加上ignore_last_failover,MHA不会管上一次切换是什么时候,只要mysql主库出现故障,就会切换
    • 11.查看MHA状态
    masterha_check_status --conf=/etc/mha/app1.cnf
    #出现如下状态代表正常
    #app1 (pid:8050) is running(0:PING_OK), master:192.168.2.3
    • 12.MHA日志
    #MHA的工作日志,下面是个日志文件,不是目录
    manager_log=/var/log/mha/app1/manager
    • 13.其他命令
    masterha_manger             启动MHA 
    masterha_check_ssh      	检查MHA的SSH配置状况 
    masterha_check_repl         检查MySQL复制状况 
    masterha_master_monitor     检测master是否宕机 
    masterha_check_status       检测当前MHA运行状态 
    masterha_master_switch  	控制故障转移(自动或者手动)
    masterha_conf_host      	添加或删除配置的server信息 
    • 14.其他参数
    candidate_master=1  #强制选主
    check_repl_delay=0   #不管和主库相差多少数据,都忽略  

    模拟故障

    • 停掉mysql主库
    systemctl stop mysqld
    
    • 查看MHA日志信息
      1.原主库挂掉。
      2.其中一台从库晋升为主库
      3.另一台从库复制到新的主库上
      4.成功发送邮件
    ----- Failover Report -----
    
    app1: MySQL Master failover 192.168.3.156(192.168.3.156:3306) to 192.168.3.157(192.168.3.157:3306) succeeded
    
    Master 192.168.3.156(192.168.3.156:3306) is down!
    
    Check MHA Manager logs at nginx:/var/log/mha/app1/manager for details.
    
    Started automated(non-interactive) failover.
    Invalidated master IP address on 192.168.3.156(192.168.3.156:3306)
    The latest slave 192.168.3.157(192.168.3.157:3306) has all relay logs for recovery.
    Selected 192.168.3.157(192.168.3.157:3306) as a new master.
    192.168.3.157(192.168.3.157:3306): OK: Applying all logs succeeded.
    192.168.3.157(192.168.3.157:3306): OK: Activated master IP address.
    192.168.3.161(192.168.3.161:3306): This host has the latest relay log events.
    Generating relay diff files from the latest slave succeeded.
    192.168.3.161(192.168.3.161:3306): OK: Applying all logs succeeded. Slave started, replicating from 192.168.3.157(192.168.3.157:3306)
    192.168.3.157(192.168.3.157:3306): Resetting slave info succeeded.
    Master failover to 192.168.3.157(192.168.3.157:3306) completed successfully.
    Tue May 12 13:26:13 2020 - [info] Sending mail..
    
    • 查看VIP漂移情况:发现VIP顺利漂移到新的主库
    • 查看binlog-server:发现复制二进制日志的守护进程已经自动结束
    • 查看MHA管理端配置文件信息:发现原mysql主库配置已经被移除

    故障修复  

    • 1.查看原主库上的VIP是否已经漂移到新主库上
    • 2.更改原主库为从
      • 查看MHA日志文件中,有一句是改主命令
    [root@nginx ~]# grep CHANGE /var/log/mha/app1/manager
    Tue May 12 13:26:10 2020 - [info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='192.168.3.157', MASTER_PORT=3306, MASTER_LOG_FILE='mysql2-binlog.000006', MASTER_LOG_POS=154, MASTER_USER='repl', MASTER_PASSWORD='xxx';
    Tue May 12 13:26:12 2020 - [info]  Executed CHANGE MASTER.
    
      • 启动原主库,在原主库上执行CHANGE MASTER TO命令到新的主库,复制账号的密码要对应修改
    mysql> CHANGE MASTER TO MASTER_HOST='192.168.3.157', MASTER_PORT=3306, MASTER_LOG_FILE='mysql2-binlog.000006', MASTER_LOG_POS=154, MASTER_USER='repl', MASTER_PASSWORD='xxx';
    mysql> START SLAVE;
    
    • 3.恢复MHA管理端配置文件(将主库迁移时,自动删除的配置补上)
    [server1]
    hostname=192.168.2.3
    port=3306
    [server2]
    hostname=192.168.2.4
    port=3306
    [server3]
    hostname=192.168.2.5
    port=3306
    • 4.清理binlog-server上原有的二进制日志,并重新复制新的主库二进制日志。二进制日志名称可以在新主库上执行SHOW MASTER STATUS查看
    cd /data/mysql/binlog    
    rm -rf /data/mysql/binlog/*
    mysqlbinlog  -R --host=192.168.2.4 --user=mha --password=mha --raw  --stop-never mysql-bin.000001 &
    
    • 5.重新启动MHA管理端,并查看服务状态
    [root@nginx ~]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover  &>> /var/log/mha/app1/manager.log  &
    [root@nginx ~]# masterha_check_status --conf /etc/mha/app1.cnf   
    app1 (pid:19214) is running(0:PING_OK), master:192.168.2.4
    

      


     Atlas读写分离

    • 安装atlas软件包
    rpm -ivh Atlas-2.2.1.el6.x86_64.rpm
    
    • 修改配置文件,默认配置文件在/usr/local/mysql-proxy/conf下,配置文件中有详细的中文注释。
    [mysql-proxy]
    #管理接口的用户名
    admin-username = user
    #管理接口的密码
    admin-password = pwd
    #Atlas后端连接的MySQL主库的IP和端口,可设置多项,用逗号分隔
    proxy-backend-addresses = 10.0.0.55:3306
    #Atlas后端连接的MySQL从库的IP和端口,@后面的数字代表权重,用来作负载均衡,若省略则默认为1,可设置多项,用逗号分隔
    proxy-read-only-backend-addresses = 10.0.0.51:3306@1,10.0.0.53:3306@2
    #用户名与其对应的加密过的MySQL密码,密码使用PREFIX/bin目录下的加密程序encrypt加密,下行的user1和user2为示例,将其替换为你的MySQL的用户名和加密密码!
    pwds = repl:3yb5jEku5h4=,mha:O2jBXONX098=
    #设置Atlas的运行方式,设为true时为守护进程方式,设为false时为前台方式,一般开发调试时设为false,线上运行时设为true,true后面不能有空格。
    daemon = true
    #设置Atlas的运行方式,设为true时Atlas会启动两个进程,一个为monitor,一个为worker,monitor在worker意外退出后会自动将其重启,设为false时只有worker,没有monitor,一般开发调试时设为false,线上运行时设为true,true后面不能有空格。
    keepalive = true
    #工作线程数,对Atlas的性能有很大影响,可根据情况适当设置
    event-threads = 8
    #日志级别,分为message、warning、critical、error、debug五个级别
    log-level = message
    #日志存放的路径
    log-path = /usr/local/mysql-proxy/log
    #SQL日志的开关,可设置为OFF、ON、REALTIME,OFF代表不记录SQL日志,ON代表记录SQL日志,REALTIME代表记录SQL日志且实时写入磁盘,默认为OFF
    sql-log=ON
    #应用程序访问的端口
    proxy-address = 0.0.0.0:33060
    #管理员访问的端口
    admin-address = 0.0.0.0:2345
    #默认字符集,设置该项后客户端不再需要执行SET NAMES语句
    charset=utf8
    #允许连接Atlas的客户端的IP,可以是精确IP,也可以是IP段,以逗号分隔,若不设置该项则允许所有IP连接,否则只允许列表中的IP连接
    #client-ips = 127.0.0.1, 192.168.1
    
    • 启动atlas,启动命令中的test是根据配置文件名称来的。atlas可以有多个实例,根据配置文件来区别启动  
    [root@nginx mysql-proxy]# /usr/local/mysql-proxy/bin/mysql-proxyd test start
    OK: MySQL-Proxy of test is started
    
    • 测试atlas读写分离功能,这里连接的就是atlas的代理端口
    mysql -umha -pmha  -h 10.0.0.53 -P 33060
    #测试读操作:会发现语句会负载均衡到两台从库上 
    mysql> SELECT @@server_id;
    +-------------+
    | @@server_id |
    +-------------+
    |           1 |
    +-------------+
    1 row in set (0.02 sec)
    
    mysql> SELECT @@server_id;
    +-------------+
    | @@server_id |
    +-------------+
    |           3 |
    +-------------+
    1 row in set (0.01 sec)
    
    #测试写操作:会发现写操作在主库上
    mysql> begin;select @@server_id;commit;
    Query OK, 0 rows affected (0.01 sec)
    
    +-------------+
    | @@server_id |
    +-------------+
    |           2 |
    +-------------+  

    Atlas管理端口应用

    • 连接atlas管理端
    #用户名、密码和端口都在atlas配置文件中
    mysql -uuser -ppwd -h 192.168.1.92 -P 2345
    
    • 打印帮助信息
    MySQL [(none)]> SELECT * FROM HELP;
    
    • 查看所有后端节点
    MySQL [(none)]> SELECT * FROM backends;
    +-------------+--------------------+-------+------+
    | backend_ndx | address            | state | type |
    +-------------+--------------------+-------+------+
    |           1 | 192.168.3.88:3306  | up    | rw   |
    |           2 | 192.168.3.156:3306 | up    | ro   |
    |           3 | 192.168.3.161:3306 | up    | ro   |
    +-------------+--------------------+-------+------+
    3 rows in set (0.00 sec)
    
    • 下线一个节点(不是删除),请求就不会到这个后端
    MySQL [(none)]> SET OFFLINE 2;
    +-------------+--------------------+---------+------+
    | backend_ndx | address            | state   | type |
    +-------------+--------------------+---------+------+
    |           2 | 192.168.3.156:3306 | offline | ro   |
    +-------------+--------------------+---------+------+
    1 row in set (0.00 sec)
    
    • 上线一个节点
    MySQL [(none)]> SET ONLINE 2;
    +-------------+--------------------+---------+------+
    | backend_ndx | address            | state   | type |
    +-------------+--------------------+---------+------+
    |           2 | 192.168.3.156:3306 | unknown | ro   |
    +-------------+--------------------+---------+------+
    1 row in set (0.00 sec)
    
    • 添加一个slave节点(读节点)
    > add slave 127.0.0.1:3306
    
    • 删除一个节点
    > remove backend 1;
    或
    > remove client 192.168.1.2
    • 查询后端用户名密码
    MySQL [(none)]>  SELECT * FROM pwds;
    +----------+--------------+
    | username | password     |
    +----------+--------------+
    | repl     | /iZxz+0GRoA= |
    | mha      | /iZxz+0GRoA= |
    +----------+--------------+
    2 rows in set (0.00 sec)
    
    • 添加后端mysql服务器用户,注意!在mysql服务器中仍要手动创建对应用户
    MySQL [(none)]> ADD PWD lee:123456;
    Empty set (0.00 sec)
    
    • 保存配置到配置文件中,所有命令都是在内存中更改,使用一下命令会保存到配置文件中
    MySQL [(none)]> SAVE CONFIG;
    Empty set (0.00 sec)
    

      

      

      

    初学linux,每学到一点东西就写一点,如有不对的地方,恳请包涵!
  • 相关阅读:
    android开源项目汇总
    Java多线程与并发库高级应用之阻塞队列BlockingQueue
    Java多线程与并发库高级应用之线程数据交换Exchanger
    Java多线程与并发库高级应用之倒计时计数器
    Java多线程与并发库高级应用之信号量Semaphore
    Java多线程与并发库高级应用之公共屏障点CyclicBarrier
    DataGridView 绑定 List
    记录pygame在pycharm中添加不上,下载错误的问题
    MySQL用户操作勒
    mysql_secure_installation
  • 原文地址:https://www.cnblogs.com/forlive/p/12865458.html
Copyright © 2011-2022 走看看