3

ShardingSphere数据分片 - 渣男小四

 2 years ago
source link: https://www.cnblogs.com/steakliu/p/16519304.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

码农在囧途

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

image

上一篇我们说了ShardingSphere的读写分离,使用读写分离能够减轻单库的读写操作,从而提升数据库的吞吐量,但是当数据库中表的数据量到达一定数量时,我们可能就会需要进行分片了,
分片又分为垂直分片和水平分片,下面我们对二者进行简单的分析。

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

a0acf5679c0d4073871067070a9ccc73~tplv-k3u1fbpfcp-zoom-1.image

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

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

e427ccd632df4308b2565ff4c1b1691d~tplv-k3u1fbpfcp-zoom-1.image

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);
        }
    }
}
fb162b57b7d54cb2b132a9b5f721a898~tplv-k3u1fbpfcp-zoom-1.image
c2addc39df82495682115b8fa2bc7156~tplv-k3u1fbpfcp-zoom-1.image

我们可以看出,数据分片成功,我们看一下分片的数据怎么查询的(此处只是单表查询),我们看一下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的数据分片,我们就说到这里,感谢你的观看,我们下期再见。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK