MySQL 主从复制与读写分离架构部署
项目概述
本项目旨在通过搭建 MySQL 主从复制架构,并结合中间件实现读写分离,提升数据库的读写性能和可用性。主从复制允许数据从主服务器同步到一个或多个从服务器,读写分离则将读操作和写操作分别分配到不同的服务器上,从而减轻主服务器的负载。
架构设计图
主从复制
原理解释:
- Master节点将数据的改变记录成二进制日志(bin log),当Master上的数据发生改变时,则将其改变写入二进制日志中
- Slave节点会在一定时间间隔内对Master的二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/O线程请求 Master的二进制事件
- 同时Master节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至Slave节点本地的中继日志(Relay log)中
- Slave节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,即解析成SQL语句逐一执行,使得其数据和 Master节点的保持一致,最后I/O线程和SQL线程将进入睡眠状态,等待下一次被唤醒。
flowchart TB
Master[Master<br>192.168.100.110] -->|Binary Log| Slave1[Slave1<br>192.168.100.112]
Master -->|Binary Log| Slave2[Slave2<br>192.168.100.114]
%% 样式定义
classDef master fill:#f96,stroke:#333,stroke-width:2px;
classDef slave fill:#9cf,stroke:#333,stroke-width:2px;
%% 应用样式
class Master master;
class Slave1,Slave2 slave;
读写分离
原理解释:
让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库
flowchart TB
Client[Clinet<br>192.168.100.118] -->|Request| Amoeba[Amoeba Proxy<br>192.168.100.116]
Amoeba -->|Write| Master[Master<br>192.168.100.110]
Master -->|Sync| Slave1
Amoeba -->|Read| Slave1[Slave1<br>192.168.100.112]
Amoeba -->|Read| Slave2[Slave2<br>192.168.100.114]
Master -->|Sync| Slave2
%% 样式定义
classDef client fill:#fcf,stroke:#333,stroke-width:2px;
classDef proxy fill:#ff9,stroke:#333,stroke-width:2px;
classDef master fill:#f96,stroke:#333,stroke-width:2px;
classDef slave fill:#9cf,stroke:#333,stroke-width:2px;
%% 应用样式
class Client client;
class Amoeba proxy;
class Master master;
class Slave1,Slave2 slave;
环境准备
主机规划
主机名 | IP | 环境 | 角色 |
---|---|---|---|
master | 192.168.100.110 | CentOS 7.9 | MySQL 主服务器 |
slave1 | 192.168.100.112 | CentOS 7.9 | MySQL 从服务器1 |
slave2 | 192.168.100.114 | CentOS 7.9 | MySQL 从服务器2 |
amoeba | 192.168.100.116 | CentOS 7.9 | Amoeba 服务器 |
client | 192.168.100.118 | Ubuntu22.04 | 客户端 |
目录规划
服务 | 目录 | 说明 |
---|---|---|
MySQL | /usr/lib/mysql |
MySQL安装目录 |
Java | /usr/local/java/jdk1.0.8 |
Java环境目录 |
Amoeba | /usr/local/amoeba |
Amoeba安装目录 |
部署步骤
配置必要服务
配置NTP服务
安装NTP服务
1 | yum install -y ntp ntpdate |
配置定时任务(每10min同步一次时间): crontab -e
1 | ntpdate time for ntp1.aliyun.com |
安装MySQL
下载MySQL5.7 安装包
1 | wget https://repo.mysql.com/mysql57-community-release-el7.rpm |
安装MySQL服务
1 | rpm -ivh mysql57-community-release-el7.rpm |
配置编码和端口,编辑 /etc/my.cnf
,添加以下内容
1 | port=3306 |
重启MySQL服务
1 | systemctl start mysqld |
查看服务运行状态并从日志中获取密码
1 | systemctl status mysqld.service |
修改密码
1 | mysql -u root -p |
主从复制
对Master进行配置
编辑 /etc/my.cnf
1 | server-id = 1 |
并重启MySQL服务
1 | systemctl restart mysqld |
进入MySQL,给从服务器授权等操作
1 | # 给从服务器授权,创建一个专门用于复制的MySQL用户账户,并授予其复制权限 |
对Slave1进行配置
编辑 /etc/my.cnf
,并重启MySQL服务
1 | server-id = 2 #修改,注意id与Master的不同,两个Slave的id也要不同 |
进入MySQL,配置主从复制master
1 | change master to master_host='192.168.100.110' , master_user='myslave',master_password='Admin@123',master_log_file='master-bin.000001',master_log_pos=604; |
查看Slave状态,必须确保IO 和 SQL 线程都是 Yes,代表同步正常
1 | START SLAVE; |
对Slave2进行配置
编辑 /etc/my.cnf
,并重启MySQL服务
1 | server-id = 3 #修改,注意id与Master的不同,两个Slave的id也要不同 |
进入MySQL,配置主从复制master
1 | change master to master_host='192.168.100.110' , master_user='myslave',master_password='Admin@123',master_log_file='master-bin.000001',master_log_pos=604; |
查看Slave状态,必须确保IO 和 SQL 线程都是 Yes,代表同步正常
对主从复制进行验证
在master节点创建数据库
1 | create database sky; |
查看从节点的同步情况,验证成功!
读写分离
配置Java环境
在Amoeba主机上,下载安装包
1 | wget https://repo.huaweicloud.com/java/jdk/8u181-b13/jdk-8u181-linux-x64.tar.gz |
配置安装目录
1 | mkdir -p /usr/local/java |
配置环境变量,编辑/etc/profile
,在文件末尾加上
1 | #java 1.0.8 |
手动使环境变量生效,配置成功
1 | source /etc/profile |
配置Amoeba
下载地址:https://sourceforge.net/projects/amoeba/files/Amoeba%20for%20mysql/2.2.x/
解压到对应目录
1 | mkdir -p /usr/local/amoeba |
配置环境变量,编辑/etc/profile
,在文件末加上如下内容:
1 | # amoeba |
手动使环境变量生效,此时正美美得想着启动,但是它出现了一个报错
解决办法:将/usr/local/amoeba/bin/amoeba文件的第58行
1 | 58 DEFAULT_OPTS="-server -Xms256m -Xmx256m -Xss128k" |
替换成如下:
1 | 58 DEFAULT_OPTS="-server -Xms256m -Xmx256m -Xss256k" |
成功启动!
先在master,slave1,slave2分别执行以下语句,授权给Amoeba访问
1 | grant all on *.* to root@'192.168.100.%' identified by 'Admin@123'; |
配置/usr/local/amoeba/conf/{amoeba,dbServers}.xml
,先备份
1 | cp amoeba.xml{,.bak}; cp dbServers.xml{,.bak} |
修改文件amoeba.xml
的第30,32行内容
115gg快速跳转,修改第115,118,119行内容
修改文件dbServers.xml
的第23,26,29行内容
注释一定要对,格式是
修改第45,48,52,55行内容,新增slave2,并配置分离主从
运行Amoeba
对读写分离进行验证
登录amoeba
1 | mysql -u amoeba -p Admin@123 -h 192.168.100.116 -P 8066 --default-character-set=utf8 |
创建一个表,并插入数据
1 | CREATE TABLE students ( |
进行查询,正常
关闭slave1或slave2的MySQL服务,发现查询正常,都关闭则无法查询
关闭master节点,发现无法写入,但是可以进行查询
至此,读写分离验证成功!
总结
在实际的生产环境中,对数据库的读和写都在同一个数据库服务器中,是不能满足实际需求的。无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。因此,通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。