ShardingSphere新一代读写分离、分库分表神器

目录

一、什么是ShardingSphere

二、ShardingSphere-JDBC 相关功能

2.1 数据分片

2.1.1 垂直分片

2.1.2 水平分片

2.2 读写分离

2.3 广播表

三、环境准备

四、配置和使用

4.1 引入依赖

4.2 配置相关的yml

4.3 student表分片策略

4.4 实体类配置

五、总结


一、什么是ShardingSphere

        ShardingSphere是京东开源目前交给Apache的一个专门解决分库分表和读写分离等问题的框架,它是一款分布式的数据库生态系统, 可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。Apache ShardingSphere 设计哲学为 Database Plus,旨在构建异构数据库上层的标准和生态。 它关注如何充分合理地利用数据库的计算和存储能力,而并非实现一个全新的数据库。 它站在数据库的上层视角,关注它们之间的协作多于数据库自身。目前ShardingSphere包含ShardingSphere-JDBC和ShardingSphere-proxy两种解决方式。

ShardingSphere-JDBC:这是一款轻量型的框架,是对jdbc的封装,可以更轻量化的解决相关问题。只需要引入相关的依赖,配置一下yml文件或者通过java代码的方式配置就可以直接使用。

ShardingSphere-proxy:这个是需要单独部署,类似于mycat,它的定位为透明化的数据库代理,理论上支持任何使用 MySQL、PostgreSQL、openGauss 协议的客户端操作数据,对异构语言、运维场景更友好。

 我今天着重的讲解一下关于ShardingSphere-JDBC的相关使用。

二、ShardingSphere-JDBC 相关功能

目前只介绍一部分最主要的功能

2.1 数据分片

        传统的将数据集中存储至单一节点的解决方案,在性能、可用性和运维成本这三方面已经难于满足海量数据的场景。从性能方面来说,由于关系型数据库大多采用 B+ 树类型的索引,在数据量超过阈值的情况下,索引深度的增加也将使得磁盘访问的 IO 次数增加,进而导致查询性能的下降; 同时,高并发访问请求也使得集中式数据库成为系统的最大瓶颈。

2.1.1 垂直分片

        按照业务拆分的方式称为垂直分片,又称为纵向拆分,它的核心理念是专库专用。 在拆分之前,一个数据库由多个数据表构成,每个表对应着不同的业务。而拆分之后,则是按照业务将表进行归类,分布到不同的数据库中,从而将压力分散至不同的数据库。 下图展示了根据业务需要,将用户表和订单表垂直分片到不同的数据库的方案。这么做可以从一定程度上缓解单一数据库的压力,但是如果单张表的数据过大的时候,还是解决不了根本问题,会导致查询性能下降。所以在这种场景之下我们需要进行水平分片。

2.1.2 水平分片

        如上所述,当单张表的数据过大的时候,如果只进行垂直拆分的话,解决不了根本性的问题,所以我们需要对单张表进行水平拆分,比如现在有一张test表,里面有1亿条数据,如果我们对这张表进行水平分片的话,我们需要建test0,test1....等等几张表,然后将这1亿条数据平均分布到这几张表中,水平分片从理论上突破了单机数据量处理的瓶颈,并且扩展相对自由,是数据分片的标准解决方案。而shardingSphere会使用逻辑表关联到数据库实际的存在的表帮我们处理数据的集合,比如分页查询、排序、筛选等。

2.2 读写分离

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

2.3 广播表

        如上所述,当一张表的数据量过大的时候,我们会考虑,分不同的数据库,水平分片来减轻单台数据库的压力,来达到优化的效果,但是在我们的实际场景中,不可能所有的表都有这么多的数据,比如一些配置表,那么当有这些表的时候我们该怎么办呢。shardingShere给我们提供了广播表的特性,比如我们现在有两个数据库,database0,database1,按道理来说,两个数据库里面都有这张表,这时候我们往config表中插入一条数据,那么database0,database1两个库中的config表都会有这条数据。

三、环境准备

        在我们使用shardingSphere之前,我们需要先准备环境,因为shardingSphere是不会做主从同步的事情的,所以我们在使用之前需要先有一个mysql主从数据库(目前支持postgres和mysql)。在mac上安装的具体教程可以参考:【MySQL主从复制】2-Mac环境下实现MySQL主从复制_mac 搭建mysql 主从复制_风暴计划的博客-CSDN博客

四、配置和使用

4.1 引入依赖

implementation 'org.apache.shardingsphere:sharding-jdbc-spring-boot-starter:4.1.1'

4.2 配置相关的yml

server:
  port: 8080
spring:
  shardingsphere:
    datasource:
      names: write-master0,read-master0-slave1,read-master0-slave2,write-master1,read-master1-slave1,read-master1-slave2
      write-master0:
        jdbc-url: jdbc:mysql://localhost:3306/CopyMasterSlave?characterEncoding=utf8&useSSL=false&allowMultiQueries=true&serverTimezone=Hongkong&allowPublicKeyRetrieval=true
        driver-class-name: com.mysql.cj.jdbc.Driver
        type: com.zaxxer.hikari.HikariDataSource
        username: admin
        password: 123456
      read-master0-slave1:
        jdbc-url: jdbc:mysql://localhost:3316/CopyMasterSlave?characterEncoding=utf8&useSSL=false&allowMultiQueries=true&serverTimezone=Hongkong&allowPublicKeyRetrieval=true
        driver-class-name: com.mysql.cj.jdbc.Driver
        type: com.zaxxer.hikari.HikariDataSource
        username: admin
        password: 123456
      read-master0-slave2:
        jdbc-url: jdbc:mysql://localhost:3326/CopyMasterSlave?characterEncoding=utf8&useSSL=false&allowMultiQueries=true&serverTimezone=Hongkong&allowPublicKeyRetrieval=true
        driver-class-name: com.mysql.cj.jdbc.Driver
        type: com.zaxxer.hikari.HikariDataSource
        username: admin
        password: 123456
      write-master1:
        jdbc-url: jdbc:mysql://localhost:3306/CopyMasterSlave1?characterEncoding=utf8&useSSL=false&allowMultiQueries=true&serverTimezone=Hongkong&allowPublicKeyRetrieval=true
        driver-class-name: com.mysql.cj.jdbc.Driver
        type: com.zaxxer.hikari.HikariDataSource
        username: admin
        password: 123456
      read-master1-slave1:
        jdbc-url: jdbc:mysql://localhost:3316/CopyMasterSlave1?characterEncoding=utf8&useSSL=false&allowMultiQueries=true&serverTimezone=Hongkong&allowPublicKeyRetrieval=true
        driver-class-name: com.mysql.cj.jdbc.Driver
        type: com.zaxxer.hikari.HikariDataSource
        username: admin
        password: 123456
      read-master1-slave2:
        jdbc-url: jdbc:mysql://localhost:3326/CopyMasterSlave1?characterEncoding=utf8&useSSL=false&allowMultiQueries=true&serverTimezone=Hongkong&allowPublicKeyRetrieval=true
        driver-class-name: com.mysql.cj.jdbc.Driver
        type: com.zaxxer.hikari.HikariDataSource
        username: admin
        password: 123456
    sharding:
      #读写分离相关的配置
      master-slave-rules:
        ds_0:
          master-data-source-name: write-master0
          slave-data-source-names:
            - read-master0-slave1
            - read-master0-slave2
          load-balance-algorithm-type: ROUND_ROBIN
        ds_1:
          master-data-source-name: write-master1
          slave-data-source-names:
            - read-master1-slave1
            - read-master1-slave2
          load-balance-algorithm-type: ROUND_ROBIN
      #分库策略
      default-database-strategy:
        inline:
          sharding-column: id
          algorithm-expression: ds_$->{id % 2}
      #分表策略
      binding-tables: student
      tables:
        student:
          actual-data-nodes: ds_$->{0..1}.student$->{0..1}
          table-strategy:
            standard:
              sharding-column: id
              precise-algorithm-class-name: com.thoughtworks.shardingspheredemo.algorithm.StudentIdShardingAlgorithm
          key-generator:
            column: id
            type: SNOWFLAKE
            props:
              worker:
                id: 123
        province:
          key-generator:
            column: id
            type: SNOWFLAKE
            props:
              worker:
                id: 1
        class:
          actual-data-nodes: ds_$->{0..1}.class
          table-strategy:
            inline:
              sharding-column: id
              algorithm-expression: class
          key-generator:
            column: id
            type: SNOWFLAKE
            props:
              worker:
                id: 1
      #配置广播表
      broadcast-tables: province

    props:
      sql.show: true
      executor.size: 2
mybatis-plus:
  mapper-locations: classpath:/mapper/*Mapper.xml
  global-config:
    banner: false
    db-config:
      id-type: auto
      insert_strategy: NOT_NULL
      table-underline: true
      logic-delete-value: 1
      logic-not-delete-value: 0
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
    cache-enabled: false
    local-cache-scope: statement




4.3 student表分片策略

public class StudentIdShardingAlgorithm  implements PreciseShardingAlgorithm<Long> {

    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
        return shardingValue.getLogicTableName()+new Random().nextInt(2);
    }
}

4.4 实体类配置

@Data
/*
    student 是shardingSphere逻辑表名
 */
@TableName("student")
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Student {
    @TableId
    private Long id;
    private String name;
    private String gender;
    private Long age;
    private Long classId;
}

就这几步简单配置之后就可以正常使用了

五、总结

        ShardingSphere很好的帮我们解决了分库分表带来的问题,比如需要手动配置多数据源,需要处理不同数据库,表之间的分页、排序等相关问题,当然也有其他的框架也可以解决这个问题,比如mycat,但是ShardingSphere比mycat功能更加齐全,然后ShardingSphere-jdbc也不需要单独部署,使用起来更加方便,轻量!

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值