sharding-proxy分库分表的操作

一、分库分表概念

1.分表

(1)垂直分表

表中的字段较多,一般将不常用的、 数据较大、长度较长的拆分到“扩展表“。一般情况加表的字段可能有几百列,此时是按照字段进行数竖直切。注意垂直分是列多的情况。

(2)水平分表

单表的数据量太大。按照某种规则(RANGE,HASH取模等),切分到多张表里面去。 但是这些表还是在同一个库中,所以库级别的数据库操作还是有IO瓶颈。这种情况是不建议使用的,因为数据量是逐渐增加的,当数据量增加到一定的程度还需要再进行切分。比较麻烦

2.分库

(1)垂直分库

一个数据库的表太多。此时就会按照一定业务逻辑进行垂直切,比如用户相关的表放在一个数据库里,订单相关的表放在一个数据库里。注意此时不同的数据库应该存放在不同的服务器上,此时磁盘空间、内存、TPS等等都会得到解决。

(2)水平分库

水平分库理论上切分起来是比较麻烦的,它是指将单张表的数据切分到多个服务器上去,每个服务器具有相应的库与表,只是表中数据集合不同。 水平分库分表能够有效的缓解单机和单库的性能瓶颈和压力,突破IO、连接数、硬件资源等的瓶颈。

二、为什么要分库分表

1.为什么要分库

按一般的经验来说,一个单库最多支持并发量到2000,且最好保持在1000。如果有20000并发量的需求,这时就需要扩容了,可以将一个库的数据拆分到多个库中,访问的时候根据一定条件访问单库,缓解单库的性能压力。

2.为什么要分表

分表也是一样的,如果单表的数据量太大,就会影响SQL语句的执行性能。分表就是按照一定的策略将单表的数据拆分到多个表中,查询的时候也按照一定的策略去查询对应的表,这样就将一次查询的数据范围缩小了。比如按照用户id来分表,将一个用户的数据就放在一个表中,crud先通过用户id找到那个表在进行操作就可以了。这样就把每个表的数据量控制在一定范围内,提升SQL语句的执行性能。

三、使用哪些分库分表中间件好

这里主要讲解 sharding中的 sharding -proxy并且是单独启动的服务,无需在项目中结合。

1.Sharding-Proxy的安装

我们可以在Sharding-Proxy官网上找的下载目录,再找到Sharding-Proxy的下载链接,下载最新版本的二进制包。然后把二进制包(tar.gz)上传到服务器的目录中,然后解压

2.配置sharding-Proxy的分片规则

进入到sharding-proxy的conf目录,这个目录sharding-proxy的配置目录,我们所有的数据源、分片规则、读写分离等都在此目录下配置。

  • logback.xml是日志的配置。

  • server.yaml是Sharding-Proxy的一些基础配置,比如:账号、密码、注册中心等。

  • 剩下的所有以config开头的yaml文件,都是一个逻辑数据源,我们可以看到最常见的两个config-sharding.yaml(分片的配置),config-master_slave.yaml(读写分离的配置)。注意,如果我们要配置分片+读写分离,要不要在两个配置文件中配置呢?不需要的,我们只需要在config-sharding.yaml中配置就可以了,如果要配置单独的读写分离,则需要按照config-master_slave.yaml配置。单独的读写分离和分片+读写分离在配置上,还是有一些区别的。

    这里主要讲解配置分片

    在这里我们的数据库使用的是MySQL,我们要将mysql-connector-java.jar这个jar包放入lib目录

3.配置config-sharding.yaml

    # 配置虚拟出来的数据库名,在server.yaml中会用到
      
      schemaName: sharding_db

  #配置数据源
    dataSources:
      test0:
        url: jdbc:mysql://localhost:3306/test0?characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=Asia/Shanghai
        username: root
        password: 1754
        connectionTimeoutMilliseconds: 30000
        idleTimeoutMilliseconds: 60000
        maxLifetimeMilliseconds: 1800000
        maxPoolSize: 50
       test1:
        url: jdbc:mysql://localhost:3306/test1?characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=Asia/Shanghai
        username: root
        password: 1754
        connectionTimeoutMilliseconds: 30000
        idleTimeoutMilliseconds: 60000
        maxLifetimeMilliseconds: 1800000
        maxPoolSize: 50 
    #配置分片规则    
    shardingRule:
      tables:
      #配置表分片策略为复合策略  
        table_one:
          actualDataNodes:  test.table_one20${1..4}
          tableStrategy:
            complex:
              shardingColumns: ctstamp
              #com.sinosoft.dea.sharding.algorithm.WjwTableByDateAlg 是java包,需要另行开发打包成jar包放到lib目录下
              algorithmClassName: com.sinosoft.dea.sharding.algorithm.WjwTableByDateAlg
      bindingTables:
    

       - table_one
         #配置默认分库策略为行表达式分片策略  用户id模2 得出 0或1作为数据库test的后缀
           defaultDatabaseStrategy:
             inline:
         shardingColumn: user_id
         algorithmExpression: test${user_id % 2}
           defaultTableStrategy: 
             none:

4.配置server.yaml

authentication:
#配置用户名密码  root  1234
  users:
    root:
      password: 1234
    tcmuser:
      password: tcmuser 
      #在config-sharding中配置的虚拟出来的库名
      authorizedSchemas: sharding_db
#
props:
  max.connections.size.per.query: 1
  acceptor.size: 16  # The default value is available processors count * 2.
  executor.size: 16  # Infinite by default.
  proxy.frontend.flush.threshold: 128  # The default value is 128.

#    # LOCAL: Proxy will run with LOCAL transaction.

#    # XA: Proxy will run with XA transaction.

#    # BASE: Proxy will run with B.A.S.E transaction.

  proxy.transaction.type: LOCAL
  proxy.opentracing.enabled: false
  query.with.cipher.column: true
  sql.show: true
  allow.range.query.with.inline.sharding: false

5.启动

windows下运行bin目录下的start.bat linux运行start.sh

四、分片策略介绍

1.标准分片策略

对应StandardShardingStrategy。提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持。StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法。PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。RangeShardingAlgorithm是可选的,用于处理BETWEEN AND分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理。

2.复合分片策略

对应ComplexShardingStrategy。复合分片策略。提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。

3.行表达式分片策略

对应InlineShardingStrategy。使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发,如: t_user_$->{u_id % 8} 表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0t_user_7

4.Hint分片策略

对应HintShardingStrategy。通过Hint而非SQL解析的方式分片的策略。

5.不分片策略

对应NoneShardingStrategy。不分片的策略。

五、实战定义分片策略

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-core</artifactId>
    <version>4.0.0-RC3</version>
</dependency>
public class AdminIdShardingAlgorithm implements ComplexKeysShardingAlgorithm<String> {
 
    @Override
    public Collection<String> doSharding(Collection<String> tables, ComplexKeysShardingValue<String> shardingValue) {
        // 获取用到的参数名比如插入时  id  name password 等
       Map<String, Collection<String>> valueMap = shardingValue.getColumnNameAndShardingValuesMap();
        //获取范围,这儿以获取时间范围为例
        Map<String, Range<String>> rangeMap = shardingValue.getColumnNameAndRangeValuesMap();
        Range<String> datatime=rangeMap.get("ctstamp");
        System.out.println("获取条件中的时间"+datatime);
        String startDate = datatime.lowerEndpoint();
        System.out.println("获取条件中的最小时间"+startDate);
        String endDate = datatime.upperEndpoint();
        System.out.println("获取条件中的最大时间"+endDate);
        //拿到数据库操作的参数名,比如查询时 where中的id,插入时id的值等。根据自己的需求计算出
        //相应的数据库后缀名
        //比如: 现在表名有两张 test0和test1 
        //那么我这边插入时 id%2 得出的是1的话,那么我这边就将相应的库名返回,即test1。
        //这样就不会对test0做操作
        //查询时也相同道理,根据要查的id =4 的话,我这边拿到这个值,4%2=0,那么我就知道去test0查询
        //不用在去test1查询
        //这边最后返回的就是你业务逻辑满足的表名,不单单只会是一张表
        //tables就是数据库中实际存在的所有分表,如果配置了10张那么这个值就包含了所有的名称
        //这儿是分片对表操作,也有相应的策略对库进行操作。但逻辑都是大同小异
        return tables;
    }
}

有不足指出还望大佬指出!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值