介绍
我的上一篇文章实现了mysql的主从复制结构,今天这篇继续将如何实现读写分离。
读写分离是指:针对数据库的写操作(插入、更新、删除等)访问主数据库,读操作访问从数据库。
因为一般网站的读请求的数量是远远大于写请求的,所以读写分离模式往往可以有效的提升系统的性能的。
读写分离属于应用层面上的实现,思路也比较简单,就是手动解析数据库请求,如果是读请求就将其转发到从数据库,如果是写请求就将其转发到主数据库。不过要写好还是比较难的,涉及到对JDBC的二次封装、负载均衡等。目前市面上已有比较成熟的方案,比如MySQL Router(官方),Apache shardingsphere 等。
Apache shardingsphere
是目前比较流行的实现方式,本篇文章也使用该框架实现读写分离。
Apache shardingsphere 简介
Apache ShardingSphere 是一款分布式的数据库生态系统, 可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。
功能有:读写分离,数据分片、分布式事务、数据迁移、数据加密、联邦查询、影子库等功能。
主要有以下两部分构成:
ShardingSphere-JDBC
ShardingSphere-JDBC 定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。是在开发时需要引入的框架。
ShardingSphere-Proxy
ShardingSphere-Proxy 定位为透明化的数据库代理端,通过实现数据库二进制协议,对异构语言提供支持。
官网地址:Apache ShardingSphere
针对 Springboot 项目的实现
引入依赖
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>5.1.1</version>
</dependency>
注 这个依赖不止有一种,至少有三种,都可以实现读写分离,可能需要配置的东西不太一样,本文方的是Apache
官方的比较新的版本,老的版本坐标中间没有core
。
在application.yaml文件中配置
spring:
shardingsphere:
props:
sql-show: true 显示打印sql语句
datasource: # 配置主从数据库
names: master, slave # 主从数据库的名字,自定义
master: # 数据库的详细配置,名字跟上面的名字对应
username: root
password:
url: jdbc:mysql://localhost:3306/db_name?serverTimezone=UTC&useSSL=false
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
slave:
username: root
password:
url: jdbc:mysql://localhost:3307/db_name?serverTimezone=UTC&useSSL=false
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
rules: # 在这里配置读写分离、数据分片等功能的规则
readwrite-splitting: # 读写分离配置
data-sources: # 配置数据源
read-write-datasource:
type: Static # 静态配置,配置的选项来自同一个YAML文件的datasource参数
props:
write-data-source-name: master # 配置写库的名字
read-data-source-names: slave # 读库的配置,多个从库之间使用逗号进行隔开
load-balancer-name: round-robin # 多个读库之间采用的负载均衡策略,这里是轮询策略
load-balancers:
round-robin:
type: ROUND_ROBIN
mode:
type: Memory
repository:
type: JDBC
这样就配置完了,其他业务逻辑代码不需要更改,就跟使用单数据库时一样正常写mapper
、service
、controller
等代码。
负载均衡:
验证
本人首先写了一个查询管理员账号的读操作的Controller,验证读请求是否被转发到从库上去。
在浏览器上输入请求地址,查看控制台日志:
可以看到日志输出的是 slave,读请求顺利转发到从数据库上。
继续写一个插入管理员表的api,验证写请求:
日志显示请求的是主库,验证成功。