ShardingSphere数据分片

简介: 坚持是一件比较难的事,坚持并不是自欺欺人的一种自我麻痹和安慰,也不是做给被人的,我觉得,坚持的本质并没有带着过多的功利主义,如果满是功利主义,那么这个坚持并不会长久,也不会有好的收获,坚持应该带着热爱,带着思想,把它当成习惯,但是并不是内卷,而是一种发自内心的喜欢和平实!希望我们都有自己的坚持,坚持写一篇文章,坚持爱一个人,坚持读一本书,坚持走向远方!

码农在囧途


坚持是一件比较难的事,坚持并不是自欺欺人的一种自我麻痹和安慰,也不是做给被人的,我觉得,坚持的本质并没有带着过多的功利主义,如果满是功利主义,那么这个坚持并不会长久,也不会有好的收获,坚持应该带着热爱,带着思想,把它当成习惯,但是并不是内卷,而是一种发自内心的喜欢和平实!希望我们都有自己的坚持,坚持写一篇文章,坚持爱一个人,坚持读一本书,坚持走向远方!


前言


上一篇我们说了ShardingSphere的读写分离,使用读写分离能够减轻单库的读写操作,从而提升数据库的吞吐量,但是当数据库中表的数据量到达一定数量时,我们可能就会需要进行分片了,


分片又分为垂直分片和水平分片,下面我们对二者进行简单的分析。


垂直分片


我们的一个数据库中通常是有很多数据表的,不过可能由于我们的分类不到位,就会出现涝的涝死旱的旱死的局面,比如某些数据表的读写操作十分频繁,而我的这个库中大量的集中了这种读写操作频繁的表,那么整体的吞吐量就会降低,而某个库中又集中了读写不频繁的表,吞吐量十分的高(但是好像没什么卵用),所以我们应该合理的分配,以保证整理的吞吐量达到最大值,

下图将数据表各分到了一个数据库中。



不过垂直分片不能从根本上解决读写瓶颈,因为不管你再怎么分,所有的数据始终都集中在一张表里面,就算数据库的性能再好,也解决不了这个问题。所以我们需要进行更加细粒度的划分,下面我们来讲解水平分片。


水平分片


水平分片又可以叫做横向拆分,就是将一张大表拆分为若干张小表,比如我一张表中有1亿条数据,那么我拆分为10张表,每张表中存1000万条数据,那么效率就会变高,还有些数据需要进行分类和归档,那么我们也需要进行分表,之前我们系统中一个表用来存储文档信息,有十多年因为数据量十分庞大,在业务中需要对文档进行排序等操作,本来查询就比较耗时了,再加上需要进行逻辑上的处理,所以就更加耗时,于是就进行了分表,将每一年的数据存进一个表,这样就提高了查询效率,并且更加容易对数据进行追踪和管理,如下就是水平分片的图例。



ShardingSphere数据分片实战


使用ShardingSphere数据分片,我们只需通过简单的配置就能实现,ShardingSphere帮我们屏蔽了底层逻辑,我们也可通过ShardingSphere预留的接口和SPI进行扩展我们的需求,比如可以实现我们自己的分片算法,主键生成策略等等。


下面演示将文档按照年份进行分表,将文档数据分表至2013年至2022年来存,一般我们的配置文件都是配置在nacos上面,所以能够灵活的进行配置,


当到了2023年,我们可以添加一个2023年的表,改下nacos的配置,当然,一般会先预留出数据表,nacos上面也留出空间,我们的是预留到2032年,留出了10年。


yml文件


我们重点关注下面的一些配置,actual-data-nodes代表进行分片的表,使用表达式,document.document_$->{2013..2022}代表document数据库


下面的document_前缀的表进行分片,如document_2022document_2021{2013..2022}代表2013到2022这个区间,sharding-column是分片列,


是我们数据表中的某个字段,就是根据它来进行分片,sharding-algorithms是分片算法,我们可以通过SPI来实现自己的分片算法,接口是StandardShardingAlgorithm


如下我们使用的是INLINE基于行表达式的分片算法,algorithm-expression是分片表达式,ShardingSphere底层会进行解析表达式,然后分片到对应的数据表上面,


我们的表达式是document_$->{year},也就是根据年进行分片,当然,我们可以根据自己的需求去写表达式,比如根据主键取模进行分片等,需要根据我们的实际场景去做,


key-generate-strategy是主键生成策略,ShardingSphere支持自定义主键生成策略,我们只需要通过SPI就可以实现,接口是KeyGenerateAlgorithm,已经实现了UUIDsnowflake雪花算法等主键生成策略。


spring:
  shardingsphere:
    mode:
      type: Standalone
      repository:
        type: File
      overwrite: true
    datasource:
      names: document
      document:
        jdbc-url: jdbc:mysql://localhost:3306/document?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.jdbc.Driver
        username: root
        password: qwer123@
    rules:
      sharding:
        tables:
          document:
            actual-data-nodes: document.document_$->{2013..2022}
            table-strategy:
              standard:
                sharding-column: year #分片列
                sharding-algorithm-name: document-inline # 分片算法名称
            key-generate-strategy:
              column: id # 主键列
              key-generator-name: timestamp #主键生成算法
        sharding-algorithms: #分片算法
          document-inline:
            type: INLINE
            props:
              algorithm-expression: document_$->{year}
        key-generators:
          timestamp:
            type: SNOWFLAKE


测试数据数据分片


虚幻插入十次,每次都插入2013年到2022年的数据。


void addDocSliceYear(){
    for (int i = 0; i < 10; i++) {
        for (int year = 2013; year <= 2022; year++) {
            Document document = new Document()
                .setDocumentName("document year【" + year + "】")
                .setDocumentDetail("year【" + year + "】")
                .setYear(year);
            documentService.save(document);
        }
    }
}




我们可以看出,数据分片成功,我们看一下分片的数据怎么查询的(此处只是单表查询),我们看一下ShardingSphere-SQL输出的sql语句


SELECT  id,document_name,document_detail,year  FROM document_2013 
UNION ALL SELECT  id,document_name,document_detail,year  FROM document_2014 
UNION ALL SELECT  id,document_name,document_detail,year  FROM document_2015 
UNION ALL SELECT  id,document_name,document_detail,year  FROM document_2016 
UNION ALL SELECT  id,document_name,document_detail,year  FROM document_2017 
UNION ALL SELECT  id,document_name,document_detail,year  FROM document_2018 
UNION ALL SELECT  id,document_name,document_detail,year  FROM document_2019 
UNION ALL SELECT  id,document_name,document_detail,year  FROM document_2020 
UNION ALL SELECT  id,document_name,document_detail,year  FROM document_2021 
UNION ALL SELECT  id,document_name,document_detail,year  FROM document_2022


从控制台打印的SQL语句中看出,ShardingSphere分片查询使用的是UNION ALL,UNION ALL实现把前后两个SELECT集合的数据联合起来,组成一个结果集查询输出,


联合查询需要每个表中的的字段相同,字段类型相同,数量相同,这也是分片的基本要求。


上面我们只演示了单表的数据分片查询,如果是多表查询,我们需要配置binding-tables绑定表,这样能够减少查询的笛卡尔积,从而提升查询效率,我们就不做详细的介绍,可去官网自己查看。


分片算法


ShardingSphere的分片算法有多种,我们也可以自己实现一套分片算法,通过SPI,分片算法的顶层接口是ShardingAlgorithm,目前实现了多种算法。


BoundaryBasedRangeShardingAlgorithm: 基于分片边界的范围分片算法


VolumeBasedRangeShardingAlgorithm: 基于分片容量的范围分片算法


ComplexInlineShardingAlgorithm: 基于行表达式的复合分片算法


AutoIntervalShardingAlgorithm: 基于可变时间范围的分片算法


ClassBasedShardingAlgorithm: 基于自定义类的分片算法


HintInlineShardingAlgorithm: 基于行表达式的 Hint 分片算法


IntervalShardingAlgorithm: 基于固定时间范围的分片算法


HashModShardingAlgorithm: 基于哈希取模的分片算法


InlineShardingAlgorithm: 基于行表达式的分片算法


ModShardingAlgorithm: 基于取模的分片算法


CosIdModShardingAlgorithm: 基于 CosId 的取模分片算法


CosIdIntervalShardingAlgorithm: 基于 CosId 的固定时间范围的分片算法


CosIdSnowflakeIntervalShardingAlgorithm: 基于 CosId 的雪花ID固定时间范围的分片算法


分布式主键生成算法


ShardingSphere也可以自定义实现主键生成策略,通过SPI,顶层接口为KeyGenerateAlgorithm,目前实现的算法有。


SnowflakeKeyGenerateAlgorithm 基于雪花算法的分布式主键生成算法


UUIDKeyGenerateAlgorithm: 基于 UUID 的分布式主键生成算法


CosIdKeyGenerateAlgorithm: 基于 CosId 的分布式主键生成算法


CosIdSnowflakeKeyGenerateAlgorithm: 基于 CosId 的雪花算法分布式主键生成算法


NanoIdKeyGenerateAlgorithm: 基于 NanoId 的分布式主键生成算法


总结


ShardingSphere能够方便的实现数据分片,但是数据分片本身就是一件迫不得已的事情,它会是我们的业务变得更加的复杂,在设计的时候需要经过严格的考量后再进行数据分片,防止出现一些不必要的麻烦。


关于ShardingSphere的数据分片,我们就说到这里,感谢你的观看,我们下期再见。

目录
相关文章
|
5月前
|
Java Apache Maven
Apache ShardingSphere 实现分库分表及读写分离
Apache ShardingSphere 实现分库分表及读写分离
100 0
|
7月前
|
SQL 存储 Java
Sharding-JDBC 如何实现分片
以上是V 哥在教学过程中实现分片的示例步骤,Sharding-JDBC能够实现SQL的分片操作,将请求路由到正确的数据库和表中,从而实现数据的水平扩展,这是在使用例如 MySQL作为数据库的场景中经常会使用到的,但如果你的企业正在考虑分布式数据库迁移,V 哥建议可以考虑 TiDB 或 OceanBase 这样的分布式数据库,因为它们天然就支持分布式,而不需要考虑这些。
|
7月前
|
负载均衡 算法 Java
Sharding-JDBC如何实现读写分离
通过以上步骤,Sharding-JDBC能够实现数据库的读写分离,从而提高应用程序的读取性能。欢迎关注威哥爱编程,一起学习成长。
110 0
|
7月前
|
Java Maven 数据库
【快速使用ShardingJDBC的哈希分片策略进行分库分表】
【快速使用ShardingJDBC的哈希分片策略进行分库分表】
385 0
|
SQL 存储 算法
sharding-jdbc 分库分表的 4种分片策略,还蛮简单的
sharding-jdbc 分库分表的 4种分片策略,还蛮简单的
1788 0
sharding-jdbc 分库分表的 4种分片策略,还蛮简单的
|
SQL 存储 算法
海量数据存储Sharding-JDBC分库分表2
海量数据存储Sharding-JDBC分库分表
|
SQL 存储 算法
海量数据存储Sharding-JDBC分库分表1
海量数据存储Sharding-JDBC分库分表
|
SQL 存储 消息中间件
海量数据存储Sharding-JDBC分库分表3
海量数据存储Sharding-JDBC分库分表
|
SQL druid 算法
ShardingSphere-Sharding-JDBC水平分表(分片策略) | 学习笔记
快速学习ShardingSphere-Sharding-JDBC水平分表(分片策略)。
ShardingSphere-Sharding-JDBC水平分表(分片策略) | 学习笔记
|
Cloud Native NoSQL Java
ShardingSphere 之 Sharding-JDBC 数据分片实践
ShardingSphere 是一套开源的分布式数据库中间件解决方案组成的生态圈,它由 Sharding-JDBC、Sharding-Proxy 和 Sharding-Sidecar(计划中)这3款相互独立的产品组成。 他们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如Java同构、异构语言、云原生等各种多样化的应用场景。
744 0
ShardingSphere 之 Sharding-JDBC 数据分片实践