美文网首页
DBA数据库笔记之(十)双主+keepalived,Orches

DBA数据库笔记之(十)双主+keepalived,Orches

作者: Mr培 | 来源:发表于2024-01-25 14:47 被阅读0次

MySQL主流高可用方案

主从或主主+Keepalived

主从或主主+Keepalived.jpg

MHA

MHA.jpg

PXC

PXC.jpg

InnoDB Cluster

InnoDB Cluster.jpg

Xenon

Xenon.jpg

Orchestrator

Orchestrator.jpg

双主+keepalived部署

环境准备

  • 修改参数
# 161,162两台机器作为双主
# 第一台机器修改配置文件
vim /data/mysql/conf/my.conf
# 查看binlog是否开启,需要开启
# 查看server_id是否配置,需要配置
# 第二台机器修改配置文件
vim /data/mysql/conf/my.conf
# 查看binlog是否开启,server_id需要不一样

#两台机器修改参数,机器内存的60%~80%
innodb_buffer_pool_size = 1G
# 开启两台机器的GTID
gtid_mode=on
# 不允许事务违反gtid一致性
enforce_gtid_consistency=on

# 重启两台MySQL
/etc/init.d/mysql.server restart

# 关闭两台机器的防火墙
systemctl stop firewalld
# 开启禁用防火墙
systemctl disable firewalld
# 查看SELinux是否关闭,如果开启启动keepalived将执行不了校验脚本,双主+keepalived部署需要关闭SELinux
sestatus
# 编辑配置文件
vim /etc/selinux/config
SELINUX=disabled
# 再两台重启机器
  • 创建用户并赋予权限
# 在两台MySQL内执行
# 创建复制的用户
create user 'repl'@'%' identified with mysql_native_password by '123456';
grant replication slave on *.* to 'repl'@'%';
# 创建心跳检测的用户
create user 'keepalived_r'@'%' identified with mysql_native_password by '123456';
grant select slave on *.* to 'keepalived_r'@'%';
  • 让主从数据一致
# 随便一台机器执行
cd /data/backup/
# 执行备份语句
mysqldump -uroot -p --single-transaction --all-databases --master-data=2 --set-gtid-purged=on > alldb_bak_for_gtid.sql
# 将备份传到从库
scp alldb_bak_for_gtid.sql 192.168.12.162:/data/backup

# 在从库
#清空master
reset master;
# 再导入备份
cd /data/backup/
mysql -uroot -p < alldb_bak_for_gtid.sql

建立双主复制关系

  • 建立A到B的复制关系
# 在B(从)上
stop slave;
reset slave;
# 新建复制关系
change master to master_host='192.168.12.161',master_user='repl',master_password='123456',master_auto_position=1;
# 开启复制
start slave;
# 查看复制状态
show slave status\G;
  • 建立B到A的复制关系
# 在A(主)上
stop slave;
reset slave;
change master to master_host='192.168.12.162',master_user='repl',master_password='123456',master_auto_position=1;
# 开启复制
start slave;
# 查看复制状态
show slave status\G;
# 双向复制创建成功,数据测试
... ...

安装配置keepalived

  • 安装keepalived
# 在两台机器安装
yum install -y keepalived
# 将keepalived添加到开机启动里面
systemctl enable keepalived.server
  • 在A机器上修改keepalived文件
vim /etc/keepalived/keepalived.conf
# 删除默认配置,粘贴新配置
global_defs {
# 本机的ip地址
    router_id 192.168.12.161
}

# keepalived用来校验MySQL的脚本
vrrp_script check_mysql {
    script "/home/mysql/bin/checkmysql.sh /tmp/mysql.sock"
    # 每隔3秒执行一次脚本
    interval 3
    weight 2
}

vrrp_instance MYSOL_MM2{
    state BACKUP
    # 网卡的名字,与机器一致
    interface ens33
    # 建议设置为vip的位数,主从需要一样
    virtual_router_id 100
    priority 99
    nopreempt
    advert_int 2
    
    authentication{
        auth_type PASS
        auth_pass xxx
    }
    track_script {
        check_mysql
    }
    unicast_peer {
    # 同一组另外一台机器的ip地址
        192.168.12.162
    }
    virtual_ipaddress{
    # 虚拟ip,同一网段随便设置,且未被使用
        192.168.12.100
    }
    # ens33 网卡名字,192.168.12.100虚拟ip,192.168.12.2网关
    notify_master "/sbin/arping -I ens33 -c3 -s192.168.12.100 192.168.12.1 > /tmp/arping.log;"
}

# 查看网卡名字
ip a
# 查看网关
route -n
  • 在B机器上修改keepalived文件
vim /etc/keepalived/keepalived.conf
# 删除默认配置,粘贴新配置
global_defs {
# 本机的ip地址
    router_id 192.168.12.162
}

# keepalived用来校验MySQL的脚本
vrrp_script check_mysql {
    script "/home/mysql/bin/checkmysql.sh"
    # 每隔3秒执行一次脚本
    interval 3
    weight 2
}

vrrp_instance MYSOL_MM2{
    state BACKUP
    # 网卡的名字,与机器一致
    interface ens33
    # 建议设置为vip的位数,主从需要一样
    virtual_router_id 100
    priority 99
    nopreempt
    advert_int 2
    
    authentication{
        auth_type PASS
        auth_pass xxx
    }
    track_script {
        check_mysql
    }
    unicast_peer {
    # 同一组另外一台机器的ip地址
        192.168.12.161
    }
    virtual_ipaddress{
    # 虚拟ip,同一网段随便设置,且未被使用
        192.168.12.100
    }
    # ens33 网卡名字,192.168.12.100虚拟ip,192.168.12.2网关
    notify_master "/sbin/arping -I ens33 -c3 -s192.168.12.100 192.168.12.2 > /tmp/arping.log;"
}

配置检测脚本

  • 编写脚本
# 在两台机器执行

mkdir -p /home/mysql/bin
mkdir -p /home/mysql/log/
# 编辑校验脚本
vim /home/mysql/bin/checkmysql.sh

PATH=$PATH:/usr/local/mysql/bin
if  [[ -n $1]]
then
    MYSQL_SOCK="$1"
else
    MYSQL_SOCK="/tmp/mysql.sock"
fi
MYSQL_USERNAME="keepalived_r"
MYSQL_PASSWORD="123456"

for i in 1 2 3
do
    alivel=`mysqladmin -S $MYSQL_SOCK -u$MYSQL_USERNAME -p$MYSQL_PASSWORD ping | grep -c  alive `
    if  [$alivel -eq 1]
    then 
        echo "alive"
        exit 0;
    else
        if  [[$i -eq 3]]
        then
            systemctl restart keepalived
            echo "$(date + "%Y%m%d %H:%M:%S") keepalived restart" >> /home/mysql/log/keepalived.log
        else
            sleep 0.9
        fi
    fi
done

# 保存退出,赋予执行权限
chmod 700 /home/mysql/bin/checkmysql.sh
  • 启动keepalived
# 两台机器启动keepalived
# 优先作为主库的机器就先启动keepalived
service keepalived start
# 查看是否生成了vip(虚拟ip)
ip a
  • 测试通过VIP连接MySQL

上线前测试高可用是否正常,比如关闭一台机器看keepalived是否正常切换

双主+keepalived测试

编写持续写入MySQL数据的Go程序

  • 创建测试用户测试表
create user 'go_rw'@'%' identified with mysql_native_password by '123456';
grant insert,delete,select,update on martin.* to 'go_rw'@'%';
create table user_info(
    id int auto_increment primary key,
    name varchar(255),
    age int,
    create_at datetime not null default current_timestamp
);
# 查看两台机器复制状态是否正常
show slave status\G;
  • 通过ChatGPT编写MySQL数据写入的程序

MySQL的IP为:192.168.12.100,用户名是go_rw,密码是xxx,
编写一个Go程序,每隔一秒往MySQL的martin库user_info写入一行数据,
并输出当前时间和写入成功
user_info表结构如下:
create table user_info(
id int auto_increment primary key,
name varchar(255),
age int,
create_at datetime not null default current_timestamp
);

  • 运行程序
# 查看MySQL数据是否写入成功
use martin;
select * from user_info;

停MySQL服务测试高可用

  • 停掉有VIP的MySQL实例A
ip a
/etc/init.d/mysql.server stop
# 观察程序写入是否正常
# 在两台机器查看虚拟ip是否完成切换
ip a
  • 启动A上的MySQL
/etc/init.d/mysql.server start
  • 停掉新主的MySQL实例B
/etc/init.d/mysql.server stop
# 观察程序写入是否正常
# 在两台机器查看虚拟ip是否完成切换
ip a

重启MySQL所在的机器测试高可用

  • 重启有VIP的MySQL机器A
ip a
reboot
# 观察程序写入是否正常
# 查看服务器是否启动,mysql,keepalived是否启动正常
ps -ef | grep mysql
ps -ef | grep keepalived
  • 重启新主的MySQL机器B
ip a
reboot
# 观察程序写入是否正常
# 查看服务器是否启动,mysql,keepalived是否启动正常
ps -ef | grep mysql
ps -ef | grep keepalived

Orchestrator

Orchestrator github地址

Orchestrator的优势

  1. 可视化
  2. 复杂拓扑管理
  3. 拓扑发现
  4. 自身高可用
  5. 灵活的恢复选项
  6. 安全
  7. 精准
  8. 高效
  9. 快速
  10. API接口

Orchestrator集群的快速部署

Orch常用架构介绍

Orch常用架构介绍.jpg

要部署的架构介绍

要部署的架构介绍.jpg

安装和配置Orch

  • 安装Orch
# 在三台机器操作
cd /usr/src/
wget https://github.com/openark/orchestrator/releases/download/v3.2.6/orchestrator-3.2.6-1.x86_64.rpm
yum install orchestrator-3.2.6-1.x86_64.rpm -y
# 查看是否安装成功
rpm -qa | grep orch
# 每一台安装orch的机器都要安装一台MySQL
  • 配置Orch的元数据库
# 在每一台MySQL创建orch的用户
create user 'orc_server_user'@'127.0.0.1' identified by '123456';
grant all privileges on `orchestrator`.* to 'orc_server_user'@'127.0.0.1';
  • 配置Orch
# 在每一台机器

cd /usr/local/orchestrator/
mkdir -p {log,conf,raftdata}
# 复制配置文件
cp orchestrator-sample.conf.json ./conf/orchestrator.conf.json
# 编辑配置文件
vim ./conf/orchestrator.conf.json
# 需要修改的参数
"MySQLTopologyUser":"orc_client_user",
"MySQLTopologyPassword":"123456",

"MySOLOrchestratorHost": "127.0.0.1",
"MySOLOrchestratorPort":3306,
"MySOLOrchestratorDatabase":"orchestrator",
"MySQLOrchestratorUser":"orc_server_user",
"MySQLOrchestratorPassword":"123456",

# 配置认证方式,开启orchestrator页面和命令行,api都需要通过用户密码才能访问,一般建议开启
"AuthenticationMethod":"basic",
"HTTPAuthUser":"admin",
"HTTPAuthPassword":"123456",
# 在这下面添加参数
“RaftEnabled":true,
"RaftDataDir":"/usr/local/orchestrator/raftdata",
# 本机的ip地址
"RaftBind":"192.168.12.161",
"DefaultRaftPort":10008,
# orchestrator三个节点的ip
"RaftNodes":[
"192.168.12.161"
"192.168.12.162"
"192.168.12.163"
],

# 修改参数
# 如果再次发生故障,多少秒之内不会再次转移
"RecoveryPeriodBlockSeconds":60,
# 恢复会忽略的主机
"RecoveryIgnoreHostnameFilters":[],
# 表示只在匹配正则表达式模式集群上进行主 恢复
"RecoverMasterClusterFilters":["*"],
"RecoverIntermediateMasterClusterFilters":["*"]

部署测试高可用的MySQL拓扑

  • 启动三个新的MySQL
  • 从主库备份数据传到从库
# 在主库
cd /data/backup/
# 执行备份语句
mysqldump -uroot -p --single-transaction --all-databases --master-data=2 --set-gtid-purged=on > alldb_bak_for_gtid.sql
# 将备份传到从库
scp alldb_bak_for_gtid.sql 192.168.12.166:/data/backup
scp alldb_bak_for_gtid.sql 192.168.12.167:/data/backup

# 在两台从库上
reset master;
cd /data/backup/
# 导入数据
mysql -uroot -p < alldb_bak_for_gtid.sql
  • 配置一主两从架构
# 保证三台机器server-id不一致
vim /data/mysql/conf/my.cnf
# 一般建议为ip的后两段
server-id=12165

# 删除三台机器的cnf
rm /data/mysql/data/auto.cnf
# 重启三台机器的MySQL
/etc/init.d/mysql.server restart

# 在第二台,第三台机器建立复制关系
stop slave;
reset slave;
change master to master_host='192.168.12.166',master_user='repl',master_password='123456',master_auto_position=1;
# 开启复制
start slave;
# 查看复制状态
show slave status\G;

将测试高可用的MySQL配置到Orch中

  • 在测试高可用的MySQL中创建Orch连接用户
# 也就是
# "MySQLTopologyUser":"orc_client_user",
# "MySQLTopologyPassword":"123456",
# 这个账号和密码

# 在主库上创建用户
create user 'orc_client_user'@'192.168.12.%' identified by '123456';
grant super,process,replication slave,reload on *.* to 'orc_client_user'@'192.168.12.%';
grant select on mysql.slave_master_info to 'orc_client_user'@'192.168.12.%';

# 在三台Orch机器和三台测试高可用的MySQL上增加host信息
vim /etc/hosts
# 三台机器都需要增加参数 ip 机器名字
192.168.12.165 martin-05
192.168.12.166 martin-06
192.168.12.167 martin-07
  • 启动Orch
# 在三台机器操作
cd /usr/local/orchestrator
/usr/local/orchestrator/orchestrator -config /usr/local/orchestrator/conf/orchestrator.conf.json http >> /usr/local/orchestrator/log/orchestrator.log 2 > &1 &
# 判断是否启动成功
ps -ef | grep orch

# 游览器登录管理界面
192.168.12.161:3000
# 查看密码
cat /usr/local/orchestrator/conf/orchestrator.conf.json
"HTTPAuthUser":"admin",
"HTTPAuthPassword":"123456",
  • 将业务MySQL添加到Orch中

管理界面点击 cluster -> discover
输入要监控的MySQL拓扑的随便一个实例

查看集群的拓扑,点击cluster -> Dashboard

Orchestrator实现MySQL故障切换实验

故障切换演示:关闭主实例

  • 关闭主实例
/etc/init.d/mysql.server stop
  • 在管理页面上确定是否发生了拓扑切换
  • 在MySQL里面验证复制关系
show slave status\G

旧主恢复之后的拓扑

  • 启动原来的主实例
/etc/init.d/mysql.server start
  • 在管理页面上确定新的拓扑
  • 在MySQL里面验证复制关系
show slave status\G
  • 再到页面上把复制关系改成一主两从

在管理页面上拓扑关系,直接拖拽的方式修改

故障切换演示:关闭主实例所在的机器

  • 关闭主实例所在的机器
power
  • 在管理页面上确定拓扑是否发生了切换
  • 在MySQL里面验证复制关系
# 有一个连接不上主
show slave status\G
  • 启动机器,查看MySQL是否正常开机启动
  • 再到页面上把复制关系改成一主两从

Orch常见命令行操作

安装配置Orchestrator客户端命令

  • 下载客户端
cd /usr/src/
wget https://github.com/openark/orchestrator/releases/download/v3.2.6/orchestrator-client-3.2.6-1.x86_64.rpm
# 安装
yum install orchestrator-client-3.2.6-1.x86_64.rpm -y
  • 配置环境变量
export ORCHESTRATOR_API="192.168.12.161:3000/api 192.168.12.162:3000/api 192.168.12.163:3000/api"
export ORCHESTRATOR_AUTH_USER=admin
export ORCHESTRATOR_AUTH_PASSWORD=123456
  • 测试客户端命令
# 查看当前集群
orchestrator-client -c clusters

使用客户端命令进行实例管理

  • 查看当前管理的所有实例
orchestrator-client -c all-instances
  • 删除一个实例
# martin-07:3306 实例名称
orchestrator-client -c forget -i martin-07:3306
  • 新增一个实例
orchestrator-client -c discover -i martin-07:3306

使用客户端命令进行集群拓扑管理

  • 查看某个集群的拓扑结构
# martin-05:3306 集群名字
orchestrator-client -c topology -i martin-05:3306
  • 主从切换自动选主
orchestrator-client -c graceful-master-takeover-auto -i martin-05:3306
  • 指定新主,切换后不启动旧主的复制线程
# martin-07:3306 新主
orchestrator-client -c graceful-master-takeover -i martin-06:3306 -d martin-07:3306
# 查看集群拓扑信息
orchestrator-client -c topology -i martin-05:3306
  • 指定新主,切换后启动旧主的复制线程
orchestrator-client -c graceful-master-takeover-auto -i martin-06:3306 -d martin-07:3306
# 查看集群拓扑信息
orchestrator-client -c topology -i martin-05:3306
  • 把一个实例接到另外一个实例下进行复制
# martin-07:3306 接到 martin-06:3306 下复制,就会变成级联架构
orchestrator-client -c relocate -i martin-07:3306 -d martin-06:3306
# 查看拓扑信息
orchestrator-client -c topology -i martin-05:3306
  • 设置节点读写
orchestrator-client -c set-writeable -i martin-06:3306 
# 查看拓扑信息
orchestrator-client -c topology -i martin-05:3306

# 设置节点只读
orchestrator-client -c set-read-only -i martin-06:3306 

Orchestrator Hook

准备

  • 修改参数
# 三个节点都要修改
vim /usr/local/orchestrator/conf/orchestrator.conf.json
# 线上建议设置为true
"MasterFailoverDetachReplicaMasterHost":true
  • 在主库上添加VIP
ip addr add 192.168.12.200/24 dev ens33
# 查看网卡名字
ip a
  • 建立Orch到业务MySQL机器的互信
# 生成公式钥
ssh-keygen
# martin-05业务MySQL/测试MySQL拓扑三台机器的ip,查看vim /etc/hosts
ssh-copy-id root@martin-05

# 测试,在三台机器都测试一下
ssh root@martin-05 "ls"
ssh root@martin-05 "ip a"
ssh root@martin-06 "ip a"
ssh root@martin-07 "ip a"

增加Hook配置

  • 修改配置文件
# 在三台机器都需要修改
vim /usr/local/orchestrator/conf/orchestrator.conf.json
# 需要在 PostFailoverProcesses 里添加一行配置
"PostFailoverProcesses":[
    "默认配置,不动",
    "/usr/local/orchestrator/shell/orch_hook.sh {failureType} {failureClusterAlias} {failedHost} {successorHost} >> /tmp/orch.log"
] 
  • 重启Orch
# 在三台机器重启
ps -ef | grep orch
kill -9 4366
/usr/local/orchestrator/orchestrator -config /usr/local/orchestrator/conf/orchestrator.conf.json http >> /usr/local/orchestrator/log/orchestrator.log 2 > &1 &
  • 编辑Hook脚本
# 在三台机器
mkdir -p /usr/local/orchestrator/shell/
vim /usr/local/orchestrator/shell/orch_hook.sh

#!/bin/bash

# 脚本接收的参数
FAILURE_TYPE=$1
CLUSTER_ALIAS=$2
FAILED_HOST=$3
SUCCESSOR_HOST=$4
# VIP 地址和网络接口配置
VIP='192.168.12.200'    # 替换为您的 VIP 地址
INTERFACE='ens33'       # 替换为您的网络接口名称

# 日志文件路径,自定义
LOG_FILE="/tmp/vip_migration.log"

# 函数:在指定主机上添加或删除 VIP
update_vip(){
    local host=$1
    local action=$2 #"add"或"del"
    
    echo "$(date): Updating VIp ($VIP) on $host: $action" >> $LOG_FILE
    
    # SSH 到指定主机执行 IP 地址的添加或删除
    ssh root@$host "ip addr $action $VIP/24 dev $INTERFACE" 2>>$LOG_FILE
    
    if [ $? -eq 0 ]; then
        echo "$(date): VIp $action operation successful on $host" >> $LOG_FILE
    else
        echo "$(date): Error during VIP $action operation on $host" >> $LOG_FILE
    fi
}

# 主逻辑
echo "$(date):0rchestrator hook triggered" >> $LOG_FILE 
echo "$(date): Failure Type: $FAILURE_TYPE,Cluster:$CLUSTER_ALIAS,Failed Host: $FAILED_HOST,Successor Host: $SUCCESSOR_HOST" >> $LOG_FILE

# 检查是否为主库故障转移
if [ "$FAILURE_TYPE" == "DeadMaster"]; then
    # 从失败的主机删除 VIP
    update_vip $FAILED_HOST "del"
    # 在后续主机上添加VIP
    update_vip $SUCCESSOR_HOST "add"
else
    echo "$(date):No action taKen, Not a master failure." >> $LOG_FILE
fi

# 赋予可执行权限
chmod +x orch_hook.sh

测试高可用

  • 程序连接VIP写数据

运行之前的程序,一直往数据库写入数据

  • 关闭主库,查看高可用性
/etc/init.d/mysql.server stop

# 查看程序是否写入正常
# 查看拓扑信息
orchestrator-client -c topology -i martin-05:3306
orchestrator-client -c topology -i martin-06:3306

# 启动
/etc/init.d/mysql.server start
# 手动把启动的MySQL添加到集群,在MySQL内
stop slave;
reset slave;
change master to master_host='192.168.12.167',master_user='repl',master_password='123456',master_auto_position=1;
start slave;
show slave status\G
  • 页面修改拓扑,查看VIP是否切换

在管理页面直接拖拽修改主库,然后查看主库是否有VIP

ip a

Orch故障恢复及选主逻辑

  • 切换逻辑
  1. Orch连不上主
  2. Orch能连上从,并且这写从也不能连上主
  3. 发起选主
  • 选主逻辑
  1. binlog位置靠前的优先
  2. 打开了log_slave_updates的优先
  3. 新的2MySQL版本优先
  4. Binlog格式:row>mixed>statement
  5. 同机房优先
  6. 无gtid_errant优先
  7. 通过参数DetectPromotionRuleQuery指定的
  • 有些情况不会进行恢复
  1. 这个集群不在自动恢复的列表里面
  2. 管理员制定了,不应该在特定服务器上进行恢复
  3. 管理员用户已全局禁用恢复
  4. 集群内部不久前刚完成了一次恢复
  5. 故障类型被认为不需要恢复
  • 给定拓扑中主实例如何发现从实例


    给定拓扑中主实例如何发现从实例.jpg

相关文章

网友评论

      本文标题:DBA数据库笔记之(十)双主+keepalived,Orches

      本文链接:https://www.haomeiwen.com/subject/stdvodtx.html