首页 > 其他分享 >使用ShardingShpere来实现读写分离跟分库分表

使用ShardingShpere来实现读写分离跟分库分表

时间:2023-05-20 20:00:25浏览次数:48  
标签:master1 分库 spring shardingsphere datasource mysql 分表 ShardingShpere user

环境准备

两个mysql集群,一主一从

我们简单的用docker-compose来快速搭建一个

version: '3'
services:
  master1:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    ports:
      - "3307:3306"
    volumes:
      - ./master1/data:/var/lib/mysql
      - ./master1/conf/my.cnf:/etc/mysql/conf.d/my.cnf

  slave1:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    ports:
      - "3308:3306"
    volumes:
      - ./slave1/data:/var/lib/mysql
      - ./slave1/conf/my.cnf:/etc/mysql/conf.d/my.cnf

  master2:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    ports:
      - "3309:3306"
    volumes:
      - ./master2/data:/var/lib/mysql
      - ./master2/conf/my.cnf:/etc/mysql/conf.d/my.cnf

  slave2:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    ports:
      - "3310:3306"
    volumes:
      - ./slave2/data:/var/lib/mysql
      - ./slave2/conf/my.cnf:/etc/mysql/conf.d/my.cnf

数据库集群搭建完成后我们在两个集群中创建两个库daily,然后分别创建4张表t_user_0 ~ t_user_3,表结构非常简单,就一个id,姓名跟性别

create table t_user_0
(
    id       bigint       not null
        primary key,
    username varchar(255) null,
    gender   tinyint      null
);


具体搭建步骤可以参考我之前的博客 mysql主从同步

项目搭建

我们使用SpringBoot来集成shardingsphere,mybatis-plus来作为orm框架。

相关pom如下:

<dependency>
     
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.5.3</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.32</version>
    </dependency>
   <!--省略SpringBoot相关依赖-->
    <dependency>
      <groupId>org.apache.shardingsphere</groupId>
      <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
      <version>4.1.0</version>
    </dependency>

项目目录结构如下:


模型类:

@TableName("t_user")
class User {
    var id:Long? = null
    var username:String? = null
    // 0:女性|1:男性
    var gender:Int = 0
    override fun toString(): String {
        return "User(id=$id, username=$username, gender=$gender)"
    }

}

Mapper

@Mapper
interface UserMapper:BaseMapper<User> {
}

Service&Impl

interface IUserService:IService<User> {
}

@Service
class UserServiceImpl(
    var userMapper: UserMapper
):ServiceImpl<UserMapper,User>(),IUserService {
}

配置文件

我们目标是将男性用户跟女性用户分表放在master1跟master2中,并且按照分别存储在4张表中t_user_0~t_user_3。我们先将用户按照性别划分存在哪个库中,再按照id来决定存在哪个表中。

我们这里id使用shardingsphere提供的雪花算法来自动生成,也可以用mybatis-plus的提供的,两者取一。

# 4个数据库的数据源信息 
spring.shardingsphere.datasource.names=master1,slave1,master2,slave2

spring.shardingsphere.datasource.master1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.master1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master1.jdbc-url=jdbc:mysql://localhost:3307/daily?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.shardingsphere.datasource.master1.username=root
spring.shardingsphere.datasource.master1.password=123456

spring.shardingsphere.datasource.slave1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave1.jdbc-url=jdbc:mysql://localhost:3308/daily?useSSL=false
spring.shardingsphere.datasource.slave1.username=root
spring.shardingsphere.datasource.slave1.password=123456


spring.shardingsphere.datasource.master2.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.master2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master2.jdbc-url=jdbc:mysql://localhost:3309/daily?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.shardingsphere.datasource.master2.username=root
spring.shardingsphere.datasource.master2.password=123456

spring.shardingsphere.datasource.slave2.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave2.jdbc-url=jdbc:mysql://localhost:3310/daily?useSSL=false
spring.shardingsphere.datasource.slave2.username=root
spring.shardingsphere.datasource.slave2.password=123456



#id 使用雪花算法
spring.shardingsphere.sharding.tables.t_user.key-generator.column=id
spring.shardingsphere.sharding.tables.t_user.key-generator.type=SNOWFLAKE

#database-strategy   基于gender进行分库 
spring.shardingsphere.sharding.tables.t_user.database-strategy.inline.sharding-column=gender
spring.shardingsphere.sharding.tables.t_user.database-strategy.inline.algorithm-expression=master$->{gender % 2+1}
# table-strategy  基于id进行分表

spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.algorithm-expression=t_user_$->{id%4}
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=master$->{1..2}.t_user_$->{0..3}


#master-slave   基于master1和master2主从集群实现读写分离
spring.shardingsphere.sharding.master-slave-rules.master1.master-data-source-name=master1
spring.shardingsphere.sharding.master-slave-rules.master1.slave-data-source-names=slave1
spring.shardingsphere.sharding.master-slave-rules.master2.master-data-source-name=master2
spring.shardingsphere.sharding.master-slave-rules.master2.slave-data-source-names=slave2

#多个从库的时候使用负载均衡
spring.shardingsphere.masterslave.load-balance-algorithm-type=ROUND_ROBIN

# 打印执行sql
spring.shardingsphere.props.sql.show=true


测试


 @Test
    fun test1(){
        val list = mutableListOf<User>()
        for (i in 0..200) {
            list.add(User().apply {
                this.username = "张三$i"
                gender = i%2
            })

        }
        userService.saveBatch(list)
    }



可以看到确实已经分别插入到不同的库跟表


测试一下读写分离功能:

我们在从库里面找一条数据,然后更改一下里面的值,我们再查询一下

1659885607800840196 我们把张三100改成张三100_slave



可以看到查询的时候确实是从 从库里面查询的


我们再在slave2中修改一条数据 1659885607817617412中将张三109修改为张三109_slave



标签:master1,分库,spring,shardingsphere,datasource,mysql,分表,ShardingShpere,user
From: https://www.cnblogs.com/loveletters/p/sharding-jdbc.html

相关文章

  • Mybatisplus3.5.1+shardingsphere-jdbc5.1.1分表
    注意使用雪花ID的话,查询ID时候必须使用long类型的ID,不要使用MP自带的默认的Serializable类型。否则会提示分片主键id数据类型和分片算法不匹配Inlineshardingalgorithmsexpressionxxxandshardingcolumnxxnotmatch错误。。。导入依赖<!--sharding-jdbc分库分表-->......
  • WM_分库分表的深入实战剖析v1.0 一般有用 看1
    分库分表的深入实战剖析内容大纲分库分表概念电商系统下订单性能瓶颈问题分库分表原则剖析&产生的问题剖析电商系统亿级订单数据分库分表实战指导一、分库分表概念概念:在数据爆炸的年代,单表数据达到千万级别,甚至过亿的量,都是很常见的情景。这时候再对数据库进行操作就是......
  • 多图详解:不停机分库分表五个步骤
    1理论知识1.1分库分表是否必要分库分表确实可以解决单表数据量大这个问题,但是并非首选。因为分库分表至少引入了三个必须解决的突出问题。第一是分库分表方案本身具有的复杂性。第二是本地事务失效问题,原本在同一个数据库中可以保证强一致性业务逻辑,分库之后事务失效。第三是......
  • 分库分表的 21 条法则,hold 住!
    大家好,我是小富~(一)好好的系统,为什么要分库分表?本文是《分库分表ShardingSphere5.x原理与实战》系列的第二篇文章,距离上一篇文章已经过去好久了,惭愧惭愧~还是不着急实战,咱们先介绍下在分库分表架构实施过程中,会接触到的一些通用概念,了解这些概念能够帮助理解市面上其他的分库分表......
  • 数据库什么时候分库分表
         分库分表实操-=====================容易造成读写都在最新的范围区间内的表,并未起到均分 ------哈希切分 双写,新旧数据库都要同步数据 重点,不会每个写操作都加代码,而是通过aop的方式还需要全量数据迁移 验证新库数据  分库分表工具,使用方无......
  • 数据库分库分表 (水平拆分,垂直拆分)分库分表的方式在生产中通常包括:垂直分库、垂直分表
    1.分库分表产生的背景采用单数据库存储存在以下的性能瓶颈:①IO瓶颈:热点数据太多,数据库缓存不足,产生大量磁盘IO,效率较低。请求数据太多,带宽不够,网络IO瓶颈。②CPU瓶颈:排序,分组,连接查询,聚合统计等SQL会消耗大量的CPU资源,请求数太多,CPU出现瓶颈。分库分表将数据分散存储,使得单一......
  • 读写分离与分库分表
    MySQL中间件Atlas一atlas简介Mysql的proxy中间件有比较多的工具,例如,mysql-proxy(官方提供),atlas,cobar,mycat,tddl,tinnydbrouter等等。而Atlas是由Qihoo360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它在MySQL官方推出的MySQL-Pro......
  • 分表分库解决思路
    阅读大约3分钟,建议收藏阅读随着公司业务快速发展,数据库中的数据量猛增,访问性能也变慢了,优化迫在眉睫。分析一下问题出现在哪儿呢?关系型数据库本身比较容易成为系统瓶颈,单机存储容量、连接数、处理能力都有限。当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库......
  • 动态分库分表策略
    关键字:动态分库分表策略参考网址:http://dragonsoar.iteye.com/blog/1769101其他相关软件:matrixOceanus(不支持spring)matrix没开源所以很多人还是用mycatdiamond里面可以配置读写比读写比权重那个是atom和group的作用吧国美好牛,以前后台ora......
  • 水平分库分表排雷帖
    一、背景提起分库分表,对于大部分服务器开发来说,其实并不是一个新鲜的名词。随着业务的发展,我们表中的数据量会变的越来越大,字段也可能随着业务复杂度的升高而逐渐增多,我们为了解决单表的查询性能问题,一般会进行分表操作。同时我们业务的用户活跃度也会越来越高,并发量......