第16章、MySQL高可用和读写分离架构

内容分享2天前发布
0 0 0

第16章、MySQL高可用和读写分离架构

1.MHA高可用架构部署

。准备环境(必须配置好1主2从开启GTID)

。上传文件到主从库/server/tools,三个节点都必须

mha4mysql-manager-0.56-0.el6.noarch.rpm

mha4mysql-node-0.56-0.el6.noarch.rpm

。配置关键程序软连接(所有节点)

因为mha只能从/usr/bin中进行调用

ln -s /application/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog

ln -s /application/mysql/bin/mysql /usr/bin/mysql

。配置各节点互信

db01:

rm -rf /root/.ssh

ssh-keygen

cd /root/.ssh

mv id_rsa.pub authorized_keys

scp -r /root/.ssh root@192.168.58.52:/root #linux用户的密码

scp -r /root/.ssh root@192.168.58.53:/root #linux用户的密码

。各节点验证

db01:

ssh 192.168.58.51 date

ssh 192.168.58.52 date

ssh 192.168.58.53 date

db02:

ssh 192.168.58.51 date

ssh 192.168.58.52 date

ssh 192.168.58.53 date

db03:

ssh 192.168.58.51 date

ssh 192.168.58.52 date

ssh 192.168.58.53 date

。安装软件

下载mha软件

mha官网:https://code.google.com/archive/p/mysql-master-ha/

github下载地址:https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads


# 安装扩展源(已经有yum源的可忽略)
wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm 
rpm -ivh epel-release-latest-7.noarch.rpm 
# 安装依赖包
yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel- ForkManager -y 
# 安装node包v0.58
wget https://github.com/yoshinorim/mha4mysql- node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm 
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm 
# 安装manager包v0.58
wget https://github.com/yoshinorim/mha4mysql- manager/releases/download/v0.58/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm 
rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

所有节点安装Node软件依赖包

cd /server/tools

yum install perl-DBD-MySQL -y

rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm

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

。在db01主库中创建mha需要的用户(由于是主从复制,其他主机上也都会安装)

create user mha@‘192.168.58.%’ identified by ‘123456’;


grant all privileges on *.* to mha@'192.168.58.%';

。配置文件准备(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=/application/mysql/data/logs

user=mha

password=123456

ping_interval=2

repl_password=123456

repl_user=repl

ssh_user=root

[server1]

hostname=192.168.58.51

port=3306

[server2]

hostname=192.168.58.52

port=3306

[server3]

hostname=192.168.58.53

port=3306

EOF

。状态检查(db03)

masterha_check_ssh –conf=/etc/mha/app1.cnf #互信检查

All SSH connection tests passed successfully.正常,互信成功

masterha_check_repl –conf=/etc/mha/app1.cnf #主从复制检查

MySQL Replication Health is OK. 主从复制关系正常

。开启MHA(db03):

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 &

。查看MHA状态(db03)

masterha_check_status –conf=/etc/mha/app1.cnf

app1 (pid:1912) is running(0:PING_OK), master:192.168.58.51 (mha高可用架构搭建成功)

2.主库宕机故障模拟及处理

。停主库db01:

观察manager 日志 tail -f /var/log/mha/app1/manager

末尾必须显示successfully,才算正常切换成功。

。修复故障库:

启动故障数据库

mysqld –defaults-file=/data/mysql/mysql3306/my3306.cnf &

恢复主从结构

db01:

CHANGE MASTER TO

MASTER_HOST=‘192.168.58.52’,

MASTER_PORT=3306,

MASTER_USER=‘repl’,

MASTER_PASSWORD=‘123456’,

MASTER_AUTO_POSITION=1;

start slave ;

。修改配置文件 (db03)

vim /etc/mha/app1.cnf

[server1]

hostname=192.168.58.51

port=3306

检查

masterha_check_ssh –conf=/etc/mha/app1.cnf #互信检查

All SSH connection tests passed successfully.正常,互信成功

masterha_check_repl –conf=/etc/mha/app1.cnf #主从复制检查

MySQL Replication Health is OK. 主从复制关系正常

。启动MHA(db03)

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 &

。查看MHA状态(db03)

masterha_check_status –conf=/etc/mha/app1.cnf

app1 (pid:19347) is running(0:PING_OK), master:192.168.58.52

关闭:masterha_stop –conf=/etc/mha/app1.cnf

3.MHA VIP自动切换


db03操作:
vim  /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.58.59/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$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
";
}

dos2unix /usr/local/bin/master_ip_failover 让文件适合linux系统

chmod +x /usr/local/bin/master_ip_failover

更改manager配置文件:

vim /etc/mha/app1.cnf

添加:在【serverdefault中】

master_ip_failover_script=/usr/local/bin/master_ip_failover

在主库上,手工生成第一个vip地址

手工在主库上绑定vip,注意一定要和配置文件中的ethN一致,我的是eth0:1(1是key指定的值)

ifconfig eth0:1 192.168.58.59/24

如果指定错误 用此命令ifconfig eth0:1 down

重启mha 【db03】

masterha_stop –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 &

[root@db03 ~]# masterha_check_status –conf=/etc/mha/app1.cnf

app1 (pid:19347) is running(0:PING_OK), master:192.168.58.52

4.MHA主从数据自动补足

Binlog Server(db03)

选择一个专门保存主库 binlog的服务器,必须要有mysqlbinlog命令,我们选择db03

创建目录用于存放二进制目录(db03)

mkdir -p /data/mha/binlog

chown -R mysql.mysql /data/*

cd /data/mha/binlog

mysqlbinlog -R –host=192.168.58.51 –user=mha –password=123456 –raw –stop-never mysql-bin.000001 &

vim /etc/mha/app1.cnf

[binlog1]

no_master=1

hostname=192.168.58.53

master_binlog_dir=/data/mha/binlog

注意:

拉取日志的起点,需要按照目前从库的已经获取到的二进制日志点为起点

重启MHA

masterha_stop –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 &

masterha_check_status –conf=/etc/mha/app1.cnf

5.Atlas读写分离高性能架构

第16章、MySQL高可用和读写分离架构

①Atlas部署读写分离架构(在db03配置)

rz 上传所需rpm文件

rpm -ivh Atlas-2.2.1.el6.x86_64.rpm

cd /usr/local/mysql-proxy/conf

mv test.cnf test.cnf.bak

cat > test.cnf <<EOF

[mysql-proxy]

admin-username = user

admin-password = pwd

proxy-backend-addresses = 192.168.58.59:3306

proxy-read-only-backend-addresses = 192.168.58.51:3306,192.168.58.53:3306

pwds = repl:/iZxz+0GRoA=,mha:/iZxz+0GRoA=

daemon = true

keepalive = true

event-threads = 8

log-level = message

log-path = /usr/local/mysql-proxy/log

sql-log=ON

proxy-address = 0.0.0.0:33060

admin-address = 0.0.0.0:2345

charset=utf8

EOF
第16章、MySQL高可用和读写分离架构

*注解:

/usr/local/mysql-proxy/bin/encrypt 123456 密码加密

*atlas的管理用户(管理员使用的用户)

admin-username = user

admin-password = pwd

*写节点(也就是主库提供写操作)

proxy-backend-addresses = 192.168.58.55:3306

*读节点

proxy-read-only-backend-addresses = 192.168.58.51:3306,192.168.58.53:3306

*应用用户和管理用户

pwds = repl:3yb5jEku5h4=,mha:O2jBXONX098=

/usr/local/mysql-proxy/bin/encrypt 123456 —->制作加密密码

*其他

daemon = true 后台运行

keepalive = true 心跳检测

event-threads = 8 开启线程

log-level = message 日志级别

log-path = /usr/local/mysql-proxy/log 日志目录

sql-log=ON 记录sql语句

proxy-address = 0.0.0.0:33060 代理地址(对外提供服务)

admin-address = 0.0.0.0:2345 管理员使用的端口

charset=utf8 字符集

启动atlas

/usr/local/mysql-proxy/bin/mysql-proxyd test start

stop 关闭

ps -ef |grep proxy

6.读写分离架构应用

①Atlas功能测试

测试读操作:

登录atlas所在的数据库。客户端也需要这样配置数据库信息

mysql -umha -p123456 -h 192.168.58.53 -P 33060 必须经过atlas才能进行读写分离

测试读写是否分离:

db03 [(none)]>select @@server_id;

测试写操作:

mysql> begin;select @@server_id;commit;

②创建应用用户 zhangsan( select update insert) 密码123456

1. 在主库中,创建用户

grant select ,update,insert on . to zhangsan@‘192.168.58.%’ identified by ‘123456’;

2. 在atlas中添加生产用户

/usr/local/mysql-proxy/bin/encrypt 123456 —->制作加密密码

3. 改配置文件

vim test.cnf

pwds = repl:3yb5jEku5h4=,mha:O2jBXONX098=,zhangsan:/iZxz+0GRoA=

/usr/local/mysql-proxy/bin/mysql-proxyd test restart

[root@db03 conf]# mysql -uzhangsan -p123456 -h 192.168.58.53 -P 33060

7.Atlas在线管理

连接管理接口

远程 mysql -uuser -ppwd -h 192.168.58.53 -P2345

本地 mysql -uuser -ppwd -h127.0.0.1 -P2345

打印帮助:

mysql> select * from help;

查询后端所有节点信息:

mysql> SELECT * FROM backends;

临时关闭节点和启动

SET OFFLINE $backend_id

SET ONLINE $backend_id

动态添加删除节点

REMOVE BACKEND 3;

动态添加从库节点

ADD SLAVE 192.168.58.53:3306;

保存配置到配置文件

SAVE CONFIG;

8.读写分离避坑指南

主从延迟,主库是最新数据,从库是旧数据;

方案一:将这类查询,强制走主库进行读取数据,对于可以返回旧数据的查询走从库;

方案二:先判断主从是不是有延迟;

​ Seconds_Behind_Master: 0

​ Retrieved_Gtid_Set对比Executed_Gtid_Set


© 版权声明

相关文章

暂无评论

none
暂无评论...