MySQL集群搭建

本文为个人学习笔记整理,仅供交流参考,非专业教学资料,内容请自行甄别。

文章目录


概述

无论是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_DBBinlog_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_DBBinlog_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
相关推荐
马克学长7 小时前
SSM实验室预约管理系统5x7en(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·实验室预约管理系统·ssm 框架
小马爱打代码7 小时前
Spring AI:文生视频 - wanx2.1-i2v-plus
java·人工智能·spring
华仔啊7 小时前
RebbitMQ 入门教程看这一篇就够了
java·后端·rabbitmq
象象翔7 小时前
AI+若依(实战篇)
java·人工智能·spring boot·spring
CHANG_THE_WORLD7 小时前
C++ vs Python 参数传递方式对比
java·c++·python
talenteddriver7 小时前
java: 4种API 参数传递方式
java·开发语言
四谎真好看7 小时前
Java 黑马程序员学习笔记(进阶篇31)
java·笔记·学习·学习笔记
sdkingz7 小时前
cursor学习笔记
java
小王师傅667 小时前
【轻松入门SpringBoot】从 0 到 1 搭建 SpringBoot 工程-中
java·spring boot·spring