ShardingJdbc:读写分离

本文重点在与ShardingJdbc的读写分离配置,所以不介绍Mysql主从的搭建。

所以请提前准备好Mysql主从环境。

简介

面对日益增加的系统访问量,数据库的吞吐量面临着巨大瓶颈。对于同一时刻有大量并发读操作和较少写操作类型的应用系统来说,将数据库拆分为主库和从库,主库负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁,使得整个系统的查询性能得到极大的改善。 通过一主多从的配置方式,可以将查询请求均匀的分散到多个数据副本,能够进一步的提升系统的处理 能力。使用多主多从的方式,不但能够提升系统的吞吐量,还能够提升系统的可用性,可以达到在任何 一个数据库宕机,甚至磁盘物理损坏的情况下仍然不影响系统的正常运行。

与将数据根据分片键打散至各个数据节点的水平分片不同,读写分离则是根据 SQL 语义的分析,将读操 作和写操作分别路由至主库与从库。

image-20210331095311356

读写分离的数据节点中的数据内容是一致的,而水平分片的每个数据节点的数据内容却并不相同。将水 平分片和读写分离联合使用,能够更加有效的提升系统性能。

image-20210331095808248

使用规范

支持项

  • 提供一主多从的读写分离配置,可独立使用,也可配合分库分表使用;

  • 独立使用读写分离支持 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);
    }

image-20210331111749101

查询:

    @Test
    void userSelect(){
        userMapper.selectList(null);
    }

image-20210331111529927

原文地址:https://www.cnblogs.com/wwjj4811/p/14600605.html