2024-05-08 11:14:45
前言
本篇文章总结了MySQL集群架构的设计知识以及各种集群搭建实战,比如主从同步、半同步复制、并行复制、读写分离、双主模式、MHA架构、分库分表等等,希望对大家有所帮助。
集群架构设计的三个维度:可用性、扩展性、一致性
可用性设计
1) 站点高可用,冗余站点
2) 服务高可用,冗余服务
3) 数据高可用,冗余数据
高可用的方案:主从模式,双主模式(分双主双写和双主单写)
扩展性设计
1) 加从库,从库过多会引发主库性能损耗。
2) 分库分表,分为垂直拆分和水平拆分,垂直拆分可以缓解部分压力,水平拆分可以无限扩展。
一致性设计
1) 不使用从库
2) 增加访问路由层,得到主从同步最长时间t,在数据发生修改后的t时间内,先访问主库,保证数据一致。
数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点,默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,从节点可以复制主数据库中的所有数据库,或者特定的数据库,或者特定的表。
主从复制用途
1) 实时灾备,用于故障切换(高可用)
2) 读写分离,提供查询服务(读扩展)
3) 数据备份,避免影响业务(高可用)
主从部署必要条件
1) 从库服务器能连通主库
2) 主库开启binlog日志(设置log-bin参数)
3) 主从server-id不同
实现步骤:
1) 主库将数据库的变更操作记录到Binlog日志文件中
2) 从库读取主库中的Binlog日志文件信息写入到从库的Relay Log中继日志中
3) 从库读取中继日志信息在从库中进行Replay,更新从库数据信息
具体触发机制如下:
1) Master服务器对数据库更改操作记录在Binlog中,BinlogDump Thread接到写入请求后,读取 Binlog信息推送给Slave的I/O Thread。
2) Slave的I/O Thread将读取到的Binlog信息写入到本地Relay Log中。
3) Slave的SQL Thread检测到Relay Log的变更请求,解析relay log中内容在从库上执行。
存在的问题:
1) 主库宕机后,数据可能丢失
2) 从库只有一个SQL Thread,主库写压力大,复制很可能延时
解决的办法:
1) 半同步复制---解决数据丢失的问题
2) 并行复制----解决从库复制延迟的问题
从5.5开始,MySQL让Master在某一个时间点等待Slave节点的ACK消息,接收到ACK消息后才进行事务提交,这就是半同步复制。
主从复制时的完整过程:
1) InnoDB Redo File Write (Prepare Write)
2) Binlog File Flush & Sync to Binlog File
3) InnoDB Redo File Commit(Commit Write)
4) Send Binlog to Slave
当Master不需要关注Slave是否接受到Binlog Event时,即为传统的主从复制。
当Master需要在第三步等待Slave返回ACK时,即为 after-commit,半同步复制(MySQL 5.5引入)。
当Master需要在第二步等待 Slave 返回 ACK 时,即为 after-sync,增强半同步(MySQL 5.7引入)。
MySQL从5.6版本开始追加了并行复制功能,改善复制延迟。
5.6版本并行复制
基于库的并行复制,也就是多线程分别执行各自库的操作,互不干扰,单库多表并发效率就不高了。
5.7版本并行复制
基于组提交的并行复制,不再有库的并行复制限制。当事务提交时,通过在主库上的二进制日志中添加组提交信息,并将在单个操作中写入到二进制日志中。如果多个事务能同时提交成功,那么它们意味着没有冲突,因此可以在Slave上并行执行。MySQL 5.7的并行复制基于一个前提,即所有已经处于prepare阶段的事务,都是可以并行提交的。
InnoDB事务提交采用的是两阶段提交模式。一个阶段是prepare,另一个是commit。
在MySQL 5.7版本中,其设计方式是将组提交的信息存放在GTID中。为了避免用户没有开启GTID功能,MySQL 5.7又引入了称之为Anonymous_Gtid的二进制日志event类型,即日志中具有相同的last_committed,表示这些事务都在一组内。
8.0 并行复制
基于write-set的并行复制。有一个集合变量来存储事务修改的记录信息(主键哈希值),所有已经提交的事务所修改的主键值经过hash后都会与那个变量的集合进行对比,来判断改行是否与其冲突,并以此来确定依赖关系,没有冲突即可并行,row级别的粒度,类似于之前的表锁行锁差异,效率肯定更高。
1) 上传mysql安装包到Linux服务器并进行解压
tar -xvf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar
2) 检查是否已有Mysql安装,存在就移除‘
rpm -qa | grep mariadb
rpm -e mariadb-libs-5.5.41-2.el7_0.x86_64 –nodeps
3) 安装mysql-community-common-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm
4) 安装mysql-community-libs-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpm
5) 安装mysql-community-libs-compat-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-compat-5.7.28-1.el7.x86_64.rpm
6)安装客户端 mysql-community-client-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm
7)安装服务端mysql-community-server-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm
8)安装开发包 mysql-community-devel-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-devel-5.7.28-1.el7.x86_64.rpm
9)初始化Mysql
mysqld --initialize --user=mysql
10)查看root随机生成默认密码
cat /var/log/mysqld.log #root@localhost: Ajtag.WsR3,J
11)设置自动启动Mysql
systemctl start mysqld.service
12)查看状态
systemctl status mysqld.service
13)登录Mysql
mysql -uroot -p # 密码:Ajtag.WsR3,J
14)修改数据库密码
set password=password('root'); 修改密码
exit #退出
15)关闭服务器防火墙
systemctl stop iptables
systemctl stop firewalld
systemctl disable firewalld.service
注意1:如果安装执行出现Header V3 DSA/SHA1 Signature, key ID 5072e1f5:错误,这是由于yum安装了旧版本的GPG keys造成的,在尾部加上--force --nodeps即可。
注意2:如果初始化mysql失败,执行yum -y install numactl命令
注意3:如果安装完mysql之后,mysql命令登录不成功,使用yum install libncurses*命令
1) 修改主库my.cnf配置文件
执行命令vim /etc/my.cnf
log_bin=mysql-bin #开启binlog,文件名称为mysql-bin
server-id=1 #指定server-id
sync-binlog=1 #执行几次后进行磁盘同步1就代表次数
#忽略以下库的同步
binlog-ignore-db=performance_schema
binlog-ignore-db=information_schema
binlog-ignore-db=sys
#指定同步的库 不设置就是同步所有库
binlog-do-db=test
2) 完成配置修改重启mysql
systemctl restart mysqld
1) 主库授权
#登录MySQL
mysql -uroot -p
#主库授权设置
grant replication slave on *.* to 'root'@'%' identified by 'root';
grant all privileges on *.* to 'root'@'%' identified by 'root';
#刷新权限,立即生效
flush privileges;
#查看主库状态
show master status;
2) 从库配置修改
执行命令 vim /etc/my.cnf
server-id=2
relay_log=mysql-relay-bin #relay-log名称
read_only=1 #此库只读
5) 完成配置修改重启mysql
systemctl restart mysqld
6) 从库启动授权
<p style="margin-top: 1.4em; margin-bottom: 1.4em; color: rgb(25, 27, 31); font-family: -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif; font