MySQL-主从复制、读写分离-Docker部署
- 由于读写分离需要大于等于 2 2 2个可通信的MySQL服务器才可工作,而部署一台新的虚拟机很麻烦
- 一开始采用本地 + 云服务器,发现两端的
MySQL
是无法通信的 - 因此,想到采用在云服务器采用
Docker
部署(本地或虚拟机直接用Docker
应该也可以,云服务器非必要)
简要介绍
读写分离主要用于缓解服务器的压力
读写分离主要分为两个部分:主从复制和动态选择数据库进行操作
- 将主库内容与变更同步到从库
- 修改数据的操作皆在主库,查询操作在从库
主从复制主要流程(图片来源于:黑马程序员-瑞吉外卖)
动态选择数据库进行操作的主要内容
mater
服务器(主库)进行需要commit
的操作,如insert
,update
,delete
slave
服务器(从库)进行查询操作,如select
接下来为实践内容
主从复制
环境搭建
由于master
和slave
需要相互通信,因此首先在Docker
中创建network
docker network create reggie
接下来,运行容器创建master
和slave
docker run -d \
--name mysql-reggie-master \
-p 3307:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
--network reggie \
mysql
docker run -d \
--name mysql-reggie-slave \
-p 3308:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
--network reggie \
mysql
接着,我们需要将master
中的二进制记录打开,并配置独一的server-id
(server-id
只需要满足唯一即可,这里的
100
100
100是随便赋的)
因此,我们需要修改MySQL
的配置文件
其文件在容器内的路径为:/etc/mysql/my.cnf
master
配置文件
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
secure-file-priv= NULL
# 主库配置
log-bin = mysql-bin
server-id = 100
slave
配置文件
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
secure-file-priv= NULL
# 从库配置
server-id = 101
需要注意,容器下的是精简的MySQL
,因此是没有vim
操作的,我们需要在本地写好配置文件,用docker cp
命令复制到容器内
docker cp my.cnf mysql-reggie-master:/etc/mysql
docker cp my.cnf mysql-reggie-slave:/etc/mysql
修改完成后,重启master
和slave
容器
数据库操作
主库
通过IDEA
连接master
,输入命令
- 用
Navicat
也一样,只要能操作数据库就行
create user xiaoming identified by '123'; # 创建用户
grant replication slave on *.* to 'xiaoming'; # 赋给用户权限
flush privileges; # 刷新
结束后,输入命令查看信息
show master status;
信息形如:
从库
记录下红框中的内容,接下来操作slave
stop slave
:防止一开始有服务,先停一下master_user
,master_password
对应master
中新建的用户和密码master_log_file
,master_log_pos
对应红框中的内容
注意:时间久了master_log_pos
是会变的,如果读写分离一开始正常运行,后来突然又失败了,则大概率就是这个问题
master_host
需要我们在Docker
中查看,调用命令
docker inspect mysql-reggie-master
在底部的"Networks"
下会有一个"IPAddress"
,将其内容填入master_host
即可
stop slave;
change master to
master_host='IPAddress',
master_user='xiaoming',
master_password='123',
master_log_file='mysql-bin.000001',
master_log_pos=67412,
get_master_public_key=1;
start slave;
结束后,输入命令
show slave status;
红框中的内容皆为Yes
则可以算是配置成功
此时,主从复制已经实现,可以尝试给master
添加一些数据,可以发现,slave
会与master
自动同步
主从复制实现后,可配合SpringBoot
框架实现读写分离
读写分离
配合
SpringBoot
项目整合
给项目添加依赖
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
给application.yaml
添加配置
- 手动修改
url
中的ip
,port
,database
server:
port: 8080
mybatis-plus:
configuration:
# 在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: ASSIGN_ID
spring:
shardingsphere:
datasource:
names:
master,slave
# 主数据源
master:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://[ip:port]/[database]?characterEncoding=utf-8
username: root
password: 123
# 从数据源
slave:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://[ip:port]/[database]?characterEncoding=utf-8
username: root
password: 123
masterslave:
# 读写分离配置
load-balance-algorithm-type: round_robin # 轮询
# 最终的数据源名称
name: dataSource
# 主库数据源名称
master-data-source-name: master
# 从库数据源名称列表,多个逗号分隔
slave-data-source-names: slave
props:
sql:
show: true # 开启SQL显示,默认false
main:
allow-bean-definition-overriding: true # 允许Bean覆盖
只需简单配置后,此时,项目就实现了读写分离