🍓 简介:java系列技术分享(👉持续更新中…🔥)
🍓 初衷:一起学习、一起进步、坚持不懈
🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏
🍓 希望这篇文章对你有所帮助,欢迎点赞 👍 收藏 ⭐留言 📝🍓 更多文章请点击
文章目录
- 一、为什么使用主从复制、读写分离?
- 二、主从复制的原理
- 三、 如何实现主从复制
- 3.1. Master配置
- 3.2. Slave配置
- 四、 使用ShardingJDBC配置读写分离
- 4.1. 添加sharding-jdbc的maven依赖:
- 4.2. 然后在application.yml添加配置
- 4.3. 如果Bean定义冲突报错
一、为什么使用主从复制、读写分离?
- 读和写的压力都由一台数据库承担,
压力大
- 数据库服务器磁盘损坏则数据丢失,单点故障
- 为了
提高数据库的并发性能,
- 随着业务量的扩展、如果是单机部署的MySQL,会导致I/O频率过高。采用主从复制、读写分离可以
提高数据库的可用性。
二、主从复制的原理
Mysql主从复制是一个异步的复制过程,底层是基于Myslq自带的二进制日志
功能,就是一台或多台(从库
)Mysql数据库从另一台数据库(主库
)进行二进制日志的复制然后再解析应用于自身,最终实现从库的数据和主库数据一致。
- 当Master节点进行insert、update、delete操作时,会按顺序写入到binlog中。
- salve从库连接master主库,Master有多少个slave就会创建多少个binlog dump线程。
- 当Master节点的binlog发生变化时,binlog dump 线程会通知所有的salve节点,并将相应的binlog内容推送给slave节点。
- I/O线程接收到 binlog 内容后,将内容写入到本地的 relay-log(中继日志)。
- SQL线程读取I/O线程写入的relay-log,并且根据 relay-log 的内容对从数据库做对应的操作。
三、 如何实现主从复制
从库可以有多台
,这里使用一主一从模式
数据库 | ip |
---|---|
Master | 192.168.100.101 |
Slave | 192.168.100.102 |
检查各自防火墙是否对数据库指定端口进行开放
3.1. Master配置
-
修改Mysql数据库的配置文件: /etc/my,cnf
# 开启binlog【必须】 log-bin=mysql-bin # 服务器唯一ID,唯一即可【必须】 server-id=101 # 需要同步的数据库,如果不配置则同步全部数据库 binlog-do-db=test_demo # binlog日志保留的天数,清除超过10天的日志 # 防止日志文件过大,导致磁盘空间不足 expire-logs-days=10
-
配置完成后,重启mysql:
systemctl restart mysqld
-
创建数据库同步用户并进行授权
- 使用命令行进入mysql:
mysql -u root -p
- 创建用户并授权
GRANT REPLICATION SLAVE ON *.* to 'zhangsan'@'%' identified by 'Java@123456';
注意:
- 上面语句的意思是创建了一个用户zhangsan,密码Java@123456,并授予了REPLICATION SLAVE权限,用于复制是所需要用到的用户权限,也就是slave必须被master授权的用户,才能复制,
- 目前mysql5.7默认密码等级为MEDIUM,该等级
要求密码组成为:数字,大,小写字母,特殊字符,至少8位
- 使用命令行进入mysql:
-
登录数据库查看master状态
show master status;
File Position mysql-bin.000001 367 执行完后master不要执行任何操作(此时的Position 数值已经获取,从库要使用一旦操作Position 会改变)
3.2. Slave配置
-
修改Mysql数据库的配置文件: /etc/my,cnf
# 不要和其他mysql服务id重复即可 server-id=102
-
配置完成后,重启mysql:
systemctl restart mysqld
-
设置主库地址及同步位置
-
使用命令行进入mysql:
mysql -u root -p
-
执行以下语句
CHANGE MASTER TO MASTER_HOST='192.168.100.101',//主机IP MASTER_USER='zhangsan',//之前创建的用户账号 MASTER_PASSWORD='Java@123456',//之前创建的用户密码 MASTER_LOG_FILE='mysql-bin.000001',//master主机的binlog日志名称 MASTER_LOG_POS=367,//binlog日志偏移量 master_port=3306;//端口
-
设置完之后需要启动:
start slave;
-
-
查看slave状态
show slave status\G;
\G:sql语句后加\G,表示将查询结果进行按列打印,也就是结构旋转90度变成纵向
*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.100.101 Master_User: zhangsan Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 247 Relay_Log_File: mysqld-relay-bin.000001 Relay_Log_Pos: 374 Relay_Master_Log_File: mysql-bin.000001 //binlog日志文件名称 Slave_IO_Running: Yes //Slave_IO线程、SQL线程都在运行 Slave_SQL_Running: Yes
Slave_IO_Running和Slave_SQL_Running都是Yes,则表示同步完成。
四、 使用ShardingJDBC配置读写分离
主从复制完成后,我们还需要实现读写分离,master负责写入数据,slave负责读取数据。
4.1. 添加sharding-jdbc的maven依赖:
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.1.1-RC1</version>
</dependency>
4.2. 然后在application.yml添加配置
这是使用druid连接池的配置
spring:
shardingsphere:
datasource:
names:
master,slave1 # 配置了几个则写几个,和下面名字一致即可
# 主数据源
master:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.100.101:3306/test_demo?characterEncoding=utf-8
username: root
password: 123456
# 从数据源
slave1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.100.102:3306/test_demo?characterEncoding=utf-8
username: root
password: 123456
# slave2:
# type: com.alibaba.druid.pool.DruidDataSource
# driver-class-name: com.mysql.jdbc.Driver
# url: jdbc:mysql://192.168.0.110:3306/test_demo?characterEncoding=utf-8
# username: root
# password: 123456
masterslave:
# 读写分离配置
load-balance-algorithm-type: round_robin #轮询
# 最终的数据源名称
name: dataSource
# 主库数据源名称
master-data-source-name: master
# 从库数据源名称列表,多个逗号分隔
slave-data-source-names: slave1
props:
sql:
show: true #开启SQL显示,默认false
main:
allow-bean-definition-overriding: true
load-balance-algorithm-type是路由策略,round_robin表示轮询策略。
4.3. 如果Bean定义冲突报错
可以添加如下添加配置
spring
main:
allow-bean-definition-overriding: true