本文重点在与ShardingJdbc的读写分离配置,所以不介绍Mysql主从的搭建。
所以请提前准备好Mysql主从环境。
简介
面对日益增加的系统访问量,数据库的吞吐量面临着巨大瓶颈。对于同一时刻有大量并发读操作和较少写操作类型的应用系统来说,将数据库拆分为主库和从库,主库负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁,使得整个系统的查询性能得到极大的改善。 通过一主多从的配置方式,可以将查询请求均匀的分散到多个数据副本,能够进一步的提升系统的处理 能力。使用多主多从的方式,不但能够提升系统的吞吐量,还能够提升系统的可用性,可以达到在任何 一个数据库宕机,甚至磁盘物理损坏的情况下仍然不影响系统的正常运行。
与将数据根据分片键打散至各个数据节点的水平分片不同,读写分离则是根据 SQL 语义的分析,将读操 作和写操作分别路由至主库与从库。
读写分离的数据节点中的数据内容是一致的,而水平分片的每个数据节点的数据内容却并不相同。将水 平分片和读写分离联合使用,能够更加有效的提升系统性能。
使用规范
支持项
-
提供一主多从的读写分离配置,可独立使用,也可配合分库分表使用;
-
独立使用读写分离支持 SQL 透传;
-
同一线程且同一数据库连接内,如有写入操作,以后的读操作均从主库读取,用于保证数据一致性;
-
基于 Hint 的强制主库路由。
读写分离实现
环境搭建
ip | 角色 | 数据库 |
---|---|---|
192.168.1.36:3307 | 主 | user_db |
192.168.1.36:3317 | 从 | user_db |
create database user_db;
use user_db;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_udict
-- ----------------------------
DROP TABLE IF EXISTS `t_udict`;
CREATE TABLE `t_udict` (
`dictid` bigint(20) NOT NULL,
`ustatus` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`uvalue` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`dictid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`user_id` bigint(20) NOT NULL,
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`ustatus` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`user_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
ShardingJdbc读写分离
配置application.properties
# ShardingJdbc分片策略
#数据源名称
spring.shardingsphere.datasource.names=master0,slave0
#一个实体类对应两张表( 后定义的bean会覆盖之前定义的相同名称的bean。)
spring.main.allow-bean-definition-overriding=true
spring.shardingsphere.datasource.master0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.master0.url=jdbc:mysql://192.168.1.36:3307/user_db?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.master0.username=root
spring.shardingsphere.datasource.master0.password=1234
spring.shardingsphere.datasource.slave0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.slave0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.slave0.url=jdbc:mysql://192.168.1.36:3317/user_db?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.slave0.username=root
spring.shardingsphere.datasource.slave0.password=1234
spring.shardingsphere.sharding.master-slave-rules.ds0.master-data-source-name=master0
spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names=slave0
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=ds0.t_user
spring.shardingsphere.sharding.tables.t_user.key-generator.column=user_id
spring.shardingsphere.sharding.tables.t_user.key-generator.type=SNOWFLAKE
#输出sql
spring.shardingsphere.props.sql.show=true
实体类和mapper
@Data
@TableName("t_user")
public class User {
@TableId
private Long userId;
private String username;
private String ustatus;
}
public interface UserMapper extends BaseMapper<User> {
}
测试
新增:
@Resource
UserMapper userMapper;
@Test
void userAdd(){
User user = new User();
user.setUsername("张三");
user.setUstatus("1");
userMapper.insert(user);
}
查询:
@Test
void userSelect(){
userMapper.selectList(null);
}