本文为个人学习笔记整理,仅供交流参考,非专业教学资料,内容请自行甄别。
文章目录
概述
无论是Redis,Rabbit MQ还是Kafka等中间件,在生产环境下,都不太可能单机部署,而是以集群的形式部署。这也是面试中经常会问到的问题,为什么MySQL需要集群部署?(或者说常见中间件为什么需要集群部署)大概有以下几点:
- 防止单机模式下的故障,这是最主要的,如果只部署一台服务器,那么出现问题就是100%不可用。而集群的数据是在多实例之间进行同步,并且集群的服务器可以跨地区部署。
- 突破性能瓶颈,单机模式下,无论是读还是写,都会在同一台服务器上。无法践行
读写分离 + 负载均衡的设计思想。 - 突破存储瓶颈,单台服务器能存储的数据量也是有限的,并且随着数据量的增长,查询效率也会大大降低。而集群可以通过分片,将数据存储在不同的服务器上。
本篇将记录MySQL集群的搭建。
一、搭建MySQL集群
首先需要两台服务器,作为一主一从的架构。并且各自要安装好MySQL,这里安装8.0的版本,并且我的centos是9版本,版本不同会有差异!如果版本不一样,请自行查阅其他资料
MySQL 官方提供了适配 RHEL 9/CentOS 9 的仓库包,执行以下命令下载:
bash
wget https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm

安装仓库配置包:
bash
dnf install -y mysql80-community-release-el9-1.noarch.rpm

执行完上述的命令,在/etc/yum.repos.d/下会产生下图的三个.repo文件:

然后导入 MySQL GPG 密钥,解决 EL9 的密钥验证问题:
bash
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
安装MySQL服务器:
bash
dnf install -y mysql-community-server

启动并初始化 MySQL 服务,CentOS 9 使用systemd管理服务:
bash
systemctl start mysqld
设置开机自启:
bash
systemctl enable mysqld

查看MySQL服务器状态,active (running)为成功:
bash
systemctl status mysqld

MySQL 8.0 安装后会在/var/log/mysqld.log生成临时密码,查看临时密码:
bash
grep 'temporary password' /var/log/mysqld.log
登录MySQL并修改临时密码:
bash
mysql -uroot -p

修改 root 用户密码,MySQL 8.0 默认启用密码强度策略(至少 8 位,包含大小写字母、数字、特殊字符):
sql
ALTER USER 'root'@'localhost' IDENTIFIED BY '你自己的密码';
FLUSH PRIVILEGES;
配置 MySQL 远程访问:
sql
CREATE USER 'root'@'%' IDENTIFIED BY '你自己的密码';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
开放端口,或者直接禁用掉防火墙:
bash
firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload
关闭 SELinux,如果是临时关闭,直接执行以下命令:
bash
setenforce 0
如果永久关闭,则编辑/etc/selinux/config,将SELINUX=enforcing改为SELINUX=disabled,然后保存退出,并且重启服务器,这里的服务器指的是Linux服务器,不是MySQL服务器:
bash
reboot
服务器重启完成后,可执行以下命令确认 SELinux 已永久关闭,输出 Disabled 即表示配置生效。
bash
getenforce

验证安装成果:
bash
mysql -V

这样就可以用远程连接工具连接了,但是MySQL 8.0 默认使用的caching_sha2_password认证插件,我这里的navicat版本比较低,还需要进行额外的设置:
sql
-- 针对远程访问的root用户(@'%'对应任意IP)
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '你的密码';
-- 若本地也需要适配,补充修改localhost的root用户
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';
-- 刷新权限使配置生效
FLUSH PRIVILEGES;
连接成功:

二、搭建主从集群
通过以上的步骤,成功在两台服务器上搭建了MySQL服务,接下来需要组成集群
2.1、主节点配置
在/etc/my.cnf.d/mysql-server.cnf中加入以下的设置:
bash
# 开启二进制日志(主从复制核心依赖)
log_bin = /var/lib/mysql/mysql-bin
# 主节点唯一ID(不能与从节点重复)
server-id = 1
# 二进制日志格式(推荐ROW,支持更复杂的复制场景)
binlog_format = ROW
# 自动清理7天前的二进制日志(避免磁盘占满)
expire_logs_days = 7
# 允许从节点复制时记录自身的二进制日志(级联复制需开启,主从场景可选)
log_slave_updates = 1

重启MySQL服务器:
bash
systemctl restart mysqld
在主节点终端登录 MySQL,执行 SQL 创建用于从节点复制的用户(仅允许从节点访问),并授权复制权限:
sql
-- 创建复制用户(用户名:repl,密码:ReplPass@123,允许131访问)
CREATE USER 'repl'@'从节点' IDENTIFIED WITH mysql_native_password BY 'ReplPass@123';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'从节点';
-- 刷新权限
FLUSH PRIVILEGES;
查看主节点的binlog,其中的Binlog_Do_DB和Binlog_Ignore_DB代表了需要记录binlog的库以及不需要记录binlog的库。
bash
SHOW MASTER STATUS;

2.2、从节点配置
在/etc/my.cnf中加入以下的设置:

重启 MySQL 服务使配置生效
bash
systemctl restart mysqld
在从节点终端登录 MySQL,执行以下 SQL,替换MASTER_LOG_FILE和MASTER_LOG_POS为你在主节点记录的值
sql
CHANGE MASTER TO
MASTER_HOST='主节点',
MASTER_USER='repl',
MASTER_PASSWORD='ReplPass@123',
MASTER_LOG_FILE='binlog.000004', -- 主节点SHOW MASTER STATUS的File值
MASTER_LOG_POS=157; -- 主节点SHOW MASTER STATUS的Position值
启动主从复制
sql
-- 启动主从复制
START SLAVE;
在从节点的 MySQL 中执行以下命令,查看复制状态:
sql
SHOW SLAVE STATUS\G;
重点检查以下两个参数,均为Yes则表示主从配置成功:

三、测试主从同步
在主节点创建数据库:
sql
CREATE DATABASE test_repl;

从节点执行:
sql
SHOW DATABASES;

然后我创建了一张user表,在主库插入一条数据

从库数据同步

如果向从库插入数据,则不会同步到主库,同步的过程是单向的。所以一般都是主库负责写,从库负责同步和读。

主库写入数据后,对应的binlog也会更新

四、部分同步
在上面提到过,主节点的binlog,其中的Binlog_Do_DB和Binlog_Ignore_DB代表了需要记录binlog的库以及不需要记录binlog的库,可以在my.cnf文件中进行设置,指定需要同步的库或排除不需要同步的,需要在从库配置部分同步,配置前首先STOP SLAVE;停止同步,然后systemctl stop mysqld停止服务。
编辑从库的/etc/my.cnf文件,可以进行以下的设置:
bash
# 仅同步test_repl库的所有表(推荐用wild参数)
replicate-wild-do-table=test_repl.%
# 忽略tmp_db库的所有表
#replicate-wild-ignore-table=tmp_db.%
# 忽略所有库下以tmp_开头的表
#replicate-wild-ignore-table=%.tmp_%
然后启动服务,开启从节点同步,验证效果,首先在主节点创建一个数据库test_repl_exclude,从节点没有同步:

在主节点创建一张表address,从节点同步到了:

但是进行如下的配置:
bash
# 忽略所有库下以address__开头的表
replicate-wild-ignore-table=%.address%
在主库的address中插入一条数据:

从节点没有同步到:

五、集群扩容同步
如果集群运行了一段时间,需要加入新的从节点,那么新的从节点在加入之后,是不会自动同步已有的数据的,新从节点需先获取主节点的全量数据备份,并记录备份时刻的 Binlog 位置(传统复制)如果数据量较小,可以通过MySQL自带的mysqldump 工具备份,在主节点执行:
sql
mysqldump -u root -p --all-databases > backup.sql
生成的文件:

然后将其复制到从节点上,并且执行:
sql
mysql u root p < backup.sql