mysql集群高可用的实现

113 阅读7分钟

前言

此篇文章旨在让各个领域的人群了解现代数据存储方式,看懂此篇文章需对mysql有一定了解

正文

集群创建

mysql是一 CS 架构的软件,完整的mysql分为mysql 服务端和mysql客户端, 服务端用于网路通信, 因为服务端和客户端的存在, mysql 实现了跨网络数据的传输与存储。但我相信看此篇文章都是对mysql有一定了解的人群, 此集群和分布式存储实现将基于linux cenos7系统, 以及mysql8.0,keepalived和shardingsphare共同实现.

以下将会带领大家完成mysql集群以及高可用,且实现分库分表,希望大家也可以对我的不足之处提出指点,欢迎大家的宝贵意见

  • 准备工作

vmware-linux7 的安装以及配置

安装工作请大家自行安装,我将重点讲解如何部署

  • centos7 以及mysql 安装

强烈建议先安装centos7,之后再安装mysql8.0, 其他的实例将进行克隆

1、 下载镜像

下载地址:buildlogs.centos.org/centos/7/is…

2、 安装

在vmware中进行安装,注意两点,一是默认安装,二是选择网络自动连接.

如果有安装问题,我会单独写一篇文章单独介绍,此处就不介绍了。安装好后可以ping下百度,如果ping成功,则说明安装成功且成功接入网络

3、 开放22端口来允许tabby连接,tabby 连接可以允许复制粘贴, 会最大程度上节约敲命令时间。且开放3306端口

sudo firewall-cmd --zone=public --add-port=22/tcp --permanent
sudo firewall-cmd --zone=public --add-port=3306/tcp --permanent

会出现seccuss字样代表开放成功, 上面命令可以将光标指向 centos7 命令行的最后一行,然后点击vmware上方的编辑,进行粘贴。

4、 静态网络配置

1、 查看自己 ip 地址 ip addr 2、修改网络ip地址 vi /etc/sysconfig/network-scripts/ifcfg-ens33 如果你 ip 是192.168.【101】.123 ,一定记住保持ip与默认网关在同一网段, 例如此ip的默认网关是192.168.101.2(vmware 默认网关是网络位.2) 3、将网络配置文件进行修改 网络配置文件修改成以下状态

TYPE=Ethernet
BOOTPROTO=static      # 改为 static
NAME=ens33
DEVICE=ens33
ONBOOT=yes            # 开机自动启用

# 静态 IP 配置
IPADDR=192.168.101.[100]  # 你的静态 IP 地址
NETMASK=255.255.255.0 # 子网掩码
GATEWAY=192.168.101.2   # 网关(vmware 默认网关是最后一位是2)
DNS1=8.8.8.8          # 首选 DNS
DNS2=8.8.4.4          # 备用 DNS(可选)

5、 设置好后,记得重启网络服务

systemctl restart network

6、 三台机器一起安装mysql 8.0

mkdir -p /etc/yum.repos.d/backup
mv /etc/yum.repos.d/CentOS-* /etc/yum.repos.d/backup/

# 使用阿里云镜像源
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

# 清理缓存并重建
yum clean all
yum makecache

# 同步时间
yum install ntpdate -y # 安装同步时间工具
ntpdate ntp.aliyun.com # 获取更新后的时间
hwclock --systohc # 持久化磁盘
# 可以使用date 查看
date
# 一般显示格式是这样的
# 2025年 02月 14日 星期五 16:36:16 CST
 
# 尝试安装
yum install -y wget
wget https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm
rpm -ivh mysql80-community-release-el7-7.noarch.rpm
yum install mysql-community-server -y

# 若出现公钥尚未装配
yum install mysql-community-server -y --nogpgcheck

# 启动mysql服务端
systemctl start mysqld.service

grep password /var/log/mysqld.log # 查看密码

登录以及修改密码,初次登录,只有修改密码才能正常使用 mysql -uroot -p[‘查看的密码’] 这里我将最大可能降低新手的使用难度,请仅仅在测试场景使用,以下密码配置会绕过密码而直接使用mysql命令就可以登录,实际场景需要设置较高难度密码来提升安全性



-- 设置密码
-- 8.0初次需要设置较高难度密码才可降低mysql密码校验难度
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Az197410@';  
-- 设置密码最小长度为4
SET GLOBAL validate_password.length = 4;
-- 关闭大小写、数字、特殊字符要求
SET GLOBAL validate_password.mixed_case_count = 0;
SET GLOBAL validate_password.number_count = 0;
SET GLOBAL validate_password.special_char_count = 0;
-- 设置策略为LOW(仅检查长度)
SET GLOBAL validate_password.policy = LOW;
-- 修改密码为1234
ALTER USER 'root'@'localhost' IDENTIFIED BY '1234';

便捷登录,修改mysql 配置。 vi /etc/my.cnf 后面将以下内容粘贴到配置末尾

[mysql]
user=root 
password=1234

到此处你可以使用mysql 命令来直接登录,可以不输入密码 以上准备内容已经全部准备完毕 现在进入集群搭建

# 1、 修改主机名为mgr1,mgr2、mgr3
sudo hostnamectl set-hostname mgr1
# 2、 修改 hosts 文件
vim /etc/hosts
# 内容
192.168.101.100 mgr1
192.168.101.101 mgr2
192.168.101.102 mgr3

# 3、 集群搭建
wget https://downloads.mysql.com/archives/get/p/43/file/mysql-shell-8.0.34-1.el7.x86_64.rpm
yum install mysql-shell-8.0.34-1.el7.x86_64.rpm -y

mysqlsh -uroot -p1234

// 集群实例初始化(每台实例都需要执行)
dba.configureInstance()		// py:dba.configure_instance() 

// 创建集群(主节点执行), 删除集群信息: dba.dropMetadataSchema()	
var cluster = dba.createCluster('myCluster')	// py:cluster=dba.create_cluster('myCluster')
// 如创建过集群,请使用此命令
var cluster = dba.getCluster() // 如果没有任何反应,则说明执行成功

// 添加实例(主节点执行)
cluster.addInstance('mgr2:3306')	// py:cluster.add_instance()
cluster.addInstance("mgr3:3306")

# 查询集群成员及其状态
SELECT * FROM performance_schema.replication_group_members;

# 重启集群
dba.rebootClusterFromCompleteOutage('myCluster');

# 若出现某个节点宕机,使用以下命令加入集群
stop group_replication;
start group_replication;

集群一般是一主多辅,所以我们在主节点建立库表,就能在辅助节点创建对应的库表.这就能实现库表的备份 换句话说,我们实现了一个数据库在不同机器上的实时备份,这三个机器,仍然被看做是一个机器.

高可用实现

高可用是指减少服务器宕机的时间, 一般可以用keepalived 来和 虚拟ip 来实现服务器的高可用

实现ip漂移 主要是实现虚拟ip随主库的主机而变,也就是,谁是主机,谁后边有虚拟ip,实现这一点,虚拟ip需要与实际ip共用同一网段. 要做到这一点,需要脚本实时监控权重,当mysql宕机后,减权重,当mysql 是主节点就增加权重.通过权重来实现ip的漂移

yum install keepalived

# 修改配置文件
# 配置文件地址: /etc/keepalived/keepalived.conf
# 修改配置文件 
vim /etc/keepalived/keepalived.conf

# keepalived 如果有报错, 请在日志中进行查看错误来源

配置文件

主库使用100权重,其他库使用98、 96权重

! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

# mysql宕机检查
vrrp_script mysql_check {
    script "/usr/libexec/keepalived/mysql_check.sh"
    interval 2
    weight -5 # 异常退出时权重减5
    fall 2
    rise 1
}

# master主库检查
vrrp_script master_check {
    script "/usr/libexec/keepalived/master_check.sh"
    interval 2
    weight 10 # 正常退出权重加10
    fall 2
    rise 1
}

vrrp_instance VI_201 {
    state MASTER
    interface eth33
    virtual_router_id 201
    priority 100 # 虚拟ip权重
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 9999
    }
    virtual_ipaddress {
        192.168.101.201/24
    }
    track_script {
        mysql_check
        master_check
    }
}

脚本文件

脚本需要写到 /usr/libexec/keepalived/ 中

  • 1、 mysql 宕机检查,当mysql宕机就抛出异常状态1
  • mysql_check.sh
!/bin/bash
if [ "$(netstat -ant |grep :::3306)" == "" ];then
    exit 1
else
    exit 0
fi
# 宕机异常退出
  • 2、 是否主库检查,是主库正常退出
  • master_check.sh
#!/bin/bash
master_hostnama=$(mysql -uroot -p1234 -e'SELECT MEMBER_HOST FROM performance_schema.replication_group_members where MEMBER_ROLE="PRIMARY";'|awk "NR==2{print}")
if [ "$master_hostname" == "$(hostname)" ]
then
	exit 0
else
	exit 1
fi 
  • 在准备好后,需要放行vrrp协议并在selinux 上开放访问权限
sudo firewall-cmd --permanent --add-rich-rule='rule protocol value="vrrp" accept'
sudo firewall-cmd --reload
# selinux 开放权限
sudo setsebool -P keepalived_connect_any on
  • 安装抓包工具,查看心跳包
yum install tcpdump -y

# 进行抓包
tcpdump -i[网卡(如ens33等)] vrrp -n
  • 此时我们就实现了主库的ip 漂移,但从库的 ip 仍然不会漂移,也就是这种方式所有的增删改查,其压力都给到了主库
  • 实现从库的ip 漂移,只需增加两组虚拟 ip 即可,和设置一个是主库就减权重的脚本
  • master_minus_check.sh
#!/bin/bash
master_hostnama=$(mysql -uroot -p1234 -e'SELECT MEMBER_HOST FROM performance_schema.replication_group_members where MEMBER_ROLE="PRIMARY";'|awk "NR==2{print}")
if [ "$master_hostname" == "$(hostname)" ]
then
	exit 1
else
	exit 0
fi
  • mgr1 中设置三组虚拟ip,权重分别为100 98 96,mgr2 权重则可以为98 98 98 mgr3 则可以为96 98 100,
  • 第一组虚拟ip通过主库加权重和宕机减权重,第二三组虚拟ip通过主库减权重和宕机减权重来保证主库中的ip漂移时,其他ip也能进行自动化的漂移到非主库节点
  • 以下是mgr1的配置,其他配置请改变权重
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

# mysql宕机检查
vrrp_script mysql_check {
    script "/usr/libexec/keepalived/mysql_check.sh"
    interval 2
    weight -5
    fall 2
    rise 1
}

# master主库检查
vrrp_script master_check {
    script "/usr/libexec/keepalived/master_check.sh"
    interval 2
    weight 10
    fall 2
    rise 1
}

# master主库检查(减权重)
vrrp_script master_minus_check {
    script "/usr/libexec/keepalived/master_minus_check.sh"
    interval 2
    weight -5
    fall 2
    rise 1
}

vrrp_instance VI_201 {
    state MASTER
    interface ens33
    virtual_router_id 201
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 9999
    }
    virtual_ipaddress {
        192.168.101.201/24
    }
    track_script {
        mysql_check
        master_check
    }
}

vrrp_instance VI_202 {
    state MASTER
    interface ens33
    virtual_router_id 202
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 9999
    }
    virtual_ipaddress {
        192.168.101.202/24
    }
    track_script {
        mysql_check
        master_minus_check
    }
}

vrrp_instance VI_203 {
    state MASTER
    interface ens33
    virtual_router_id 203          
    priority 96
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 9999
    }
    virtual_ipaddress {
        192.168.101.203/24
    }
    track_script {
        mysql_check
        master_minus_check
    }
}
  • 这样实现的有一个问题,就是宕机之后,不能及时知道宕机,所以在宕机的时候,我们可以做一个邮件发送的功能
  • 使用mailx 来实现,在每一个虚拟ip模块组中加入这三行命令
notify_master "/usr/libexec/keepalived/send_email.sh 1684923397@qq.com add_203"
notify_backup "/usr/libexec/keepalived/send_email.sh 1684923397@qq.com remove_203"
notify_fault "/usr/libexec/keepalived/send_email.sh 1684923397@qq.com keepalived_fault"
# 例如


# 虚拟ip模块组如下配置 # 如果是202 201 请将所有的203改变为对应的202 201
vrrp_instance VI_203 {
    state MASTER
    interface ens33
    virtual_router_id 203          
    priority 96
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 9999
    }
    virtual_ipaddress {
        192.168.101.203/24
    }
    track_script {
        mysql_check
        master_minus_check
    }
    notify_master "/usr/libexec/keepalived/send_email.sh 1684923397@qq.com add_203"
    notify_backup "/usr/libexec/keepalived/send_email.sh 1684923397@qq.com remove_203"
    notify_fault "/usr/libexec/keepalived/send_email.sh 1684923397@qq.com keepalived_fault"
}

使用mailx

  • 安装mailx
yum install mailx

配置mailx
vim /etc/mail.rc

# 此处将一下配置增加到上面文件中
set  from=224******53@qq.com  # 请使用自己邮箱
set  smtp=smtp.qq.com
set  smtp-auth-user=224******53@qq.com  
set  smtp-auth-password=euia********chb  # 此处是qq邮箱验证码
set  smtp-auth=login
set  smtp-use-starttls
set  ssl-verify=ignore
set  nss-config- dir=/root/.certs1

# 并将命令粘贴到机器执行
#!/bin/bash
# 创建证书存储目录
mkdir -p /root/.certs
# 从QQ的SMTP服务器获取SSL证书并保存
echo -n | openssl s_client -connect smtp.qq.com:465 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /root/.certs/qq.crt
# 使用certutil工具将证书添加到证书数据库
certutil -A -n "GeoTrust SSL CA" -t "C,," -d /root/.certs -i /root/.certs/qq.crt
certutil -A -n "GeoTrust Global CA" -t "C,," -d /root/.certs -i /root/.certs/qq.crt
# 列出证书数据库中的证书列表
certutil -L -d /root/.certs
certutil -A -n "GeoTrust SSL CA - G3" -t "Pu,Pu,Pu"  -d ./ -i /root/.certs/qq.crt

# 这是用来获取许可证,具体可参考 https://developer.aliyun.com/article/504370
  • send_email.sh
  • 文件位置请配置在这里 /usr/libexec/keepalived/send_email.sh
#!/bin/bash
echo "$(hostname) $2"|mail -s "mgr-information" $1

到这里,已经初步完成了集群服务器的高可用以及自动邮件告警,我会在下一篇文章继续介绍集群的分布式处理,

感谢你看到这里,如有一些意见或者建议,请发送邮件到1684923397@qq.com. 我会在抖音频道发布视频演示.现在还为未更新。 下一篇网址:读写分离和分库分表的实现