sharding proxy测试分库分表的扩容问题

分库分表设计阶段的一个重要考虑的因素是分库分表的数量以及后期扩容问题。
建议根据业务5-10年的发展,一次性确定表的数量,避免后期增加分表数量;如果后期要改变表的数量,数据迁移难度较大(会涉及到记录级别的迁移);
如果我们规划1024张表,初期可以1个实例,32个库,每个库32张表;
后期随着业务发展,可以将32个库切分到不同实例,甚至将每张表切到不同的实例,最多切1024个实例,对应1024个库,每个库一个表。


扩容的一个原则是只能表级迁移,避免记录级迁移。
一个普遍的规则是(假设分1024张表,初期16个库):库id = 分片键%16,表id = int(分片键/16) % 64

下面以sharding-proxy为例,说明这种情况下的扩容过程。
为了便于展示,假设一共16张表,初期4个库,每个库4张表,后期扩容为8个库,每个库2张表。

扩容前

datasource配置:

ds_0: !!org.apache.shardingsphere.orchestration.core.configuration.YamlDataSourceConfiguration
  dataSourceClassName: com.zaxxer.hikari.HikariDataSource
  properties:
    jdbcUrl: jdbc:mysql://10.40.12.21:9999/db0?serverTimezone=UTC&useSSL=false
    username: lbadmin
    password: lbadmin
    connectionTimeout: 30000
    idleTimeout: 60000
    maxLifetime: 0
    maxPoolSize: 50
    minPoolSize: 1
    maintenanceIntervalMilliseconds: 30000
    readOnly: false
ds_1: !!org.apache.shardingsphere.orchestration.core.configuration.YamlDataSourceConfiguration
  dataSourceClassName: com.zaxxer.hikari.HikariDataSource
  properties:
    jdbcUrl: jdbc:mysql://10.40.12.21:9999/db1?serverTimezone=UTC&useSSL=false
    ……
ds_2: !!org.apache.shardingsphere.orchestration.core.configuration.YamlDataSourceConfiguration
  dataSourceClassName: com.zaxxer.hikari.HikariDataSource
  properties:
    jdbcUrl: jdbc:mysql://10.40.12.21:9999/db2?serverTimezone=UTC&useSSL=false
    ……
ds_3: !!org.apache.shardingsphere.orchestration.core.configuration.YamlDataSourceConfiguration
  dataSourceClassName: com.zaxxer.hikari.HikariDataSource
  properties:
    jdbcUrl: jdbc:mysql://10.40.12.21:9999/db3?serverTimezone=UTC&useSSL=false
    ……

rule配置:

defaultDatabaseStrategy:
  inline:
    algorithmExpression: ds_${user_id % 4}
    shardingColumn: user_id
tables:
  t_order:
    actualDataNodes: ds_${0..3}.t_order_${0..3}
    keyGenerator:
      column: order_id
      type: SNOWFLAKE
    logicTable: t_order
    tableStrategy:
      inline:
        algorithmExpression: t_order_${user_id.intdiv(4) % 4}
        shardingColumn: user_id

通过sharding-proxy建表初始化数据

drop table t_order;

CREATE TABLE `t_order` (
  `order_id` bigint(20) DEFAULT NULL,
  `user_id` int(11) DEFAULT NULL,
   PRIMARY key(order_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

insert into t_order(user_id) values(1);
insert into t_order(user_id) values(2);
insert into t_order(user_id) values(3);
insert into t_order(user_id) values(4);
insert into t_order(user_id) values(5);
insert into t_order(user_id) values(6);
insert into t_order(user_id) values(7);
insert into t_order(user_id) values(8);
insert into t_order(user_id) values(9);
insert into t_order(user_id) values(10);
insert into t_order(user_id) values(11);
insert into t_order(user_id) values(12);
insert into t_order(user_id) values(13);
insert into t_order(user_id) values(14);
insert into t_order(user_id) values(15);
insert into t_order(user_id) values(16);

user_id数据的分布:

tab       db    user_id
t_order_0    db0    16
t_order_0    db1    1
t_order_0    db2    2
t_order_0    db3    3
t_order_1    db0    4
t_order_1    db1    5
t_order_1    db2    6
t_order_1    db3    7
t_order_2    db0    8
t_order_2    db1    9
t_order_2    db2    10
t_order_2    db3    11
t_order_3    db0    12
t_order_3    db1    13
t_order_3    db2    14
t_order_3    db3    15

扩容后

模拟扩容,8个库,每个库2张表:
datasource配置:

增加:
ds_4: !!org.apache.shardingsphere.orchestration.core.configuration.YamlDataSourceConfiguration
  dataSourceClassName: com.zaxxer.hikari.HikariDataSource
  properties:
    jdbcUrl: jdbc:mysql://10.40.12.21:9999/db4?serverTimezone=UTC&useSSL=false
    ……
ds_5: !!org.apache.shardingsphere.orchestration.core.configuration.YamlDataSourceConfiguration
  dataSourceClassName: com.zaxxer.hikari.HikariDataSource
  properties:
    jdbcUrl: jdbc:mysql://10.40.12.21:9999/db5?serverTimezone=UTC&useSSL=false
    ……
ds_6: !!org.apache.shardingsphere.orchestration.core.configuration.YamlDataSourceConfiguration
  dataSourceClassName: com.zaxxer.hikari.HikariDataSource
  properties:
    jdbcUrl: jdbc:mysql://10.40.12.21:9999/db6?serverTimezone=UTC&useSSL=false
    ……
ds_7: !!org.apache.shardingsphere.orchestration.core.configuration.YamlDataSourceConfiguration
  dataSourceClassName: com.zaxxer.hikari.HikariDataSource
  properties:
    jdbcUrl: jdbc:mysql://10.40.12.21:9999/db7?serverTimezone=UTC&useSSL=false
    ……

        
rule配置:

defaultDatabaseStrategy:
  inline:
    algorithmExpression: ds_${user_id % 8}
    shardingColumn: user_id
tables:
  t_order:
    actualDataNodes: ds_${0..7}.t_order_${0..7}
    keyGenerator:
      column: order_id
      type: SNOWFLAKE
    logicTable: t_order
    tableStrategy:
      inline:
        algorithmExpression: t_order_${user_id.intdiv(8) % 2}
        shardingColumn: user_id

        
重建表并初始化数据:
user_id数据的分布:

tab       db    user_id
t_order_0    db0    16
t_order_0    db1    1
t_order_0    db2    2
t_order_0    db3    3
t_order_0    db4    4
t_order_0    db5    5
t_order_0    db6    6
t_order_0    db7    7
t_order_1    db0    8
t_order_1    db1    9
t_order_1    db2    10
t_order_1    db3    11
t_order_1    db4    12
t_order_1    db5    13
t_order_1    db6    14
t_order_1    db7    15

数据迁移示意图

总之

扩容前:4个库,每个库4张表,库id = 分片键%4,表id = int(分片键/4) % 4

扩容后:8个库,每个库2张表,库id = 分片键%8,表id = int(分片键/8) % 2

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Sharding-Proxy 是一个开源的分库分表中间件,它可以帮助应用程序实现无感知的分库分表操作。下面是一个简单的步骤来利用 Sharding-Proxy 进行分库分表: 1. 安装和配置 Sharding-Proxy:首先,你需要下载 Sharding-Proxy 的安装包,并解压到你的服务器上。然后,根据你的需求修改配置文件,配置数据源和分片规则等信息。 2. 创建数据库和表:在进行分库分表之前,你需要创建相应的数据库和表结构。你可以选择手动创建,或者使用 Sharding-Proxy 提供的自动建表功能。 3. 配置分片规则:在 Sharding-Proxy 的配置文件中,你需要定义分片规则,指定如何将数据分散到不同的数据库和表中。可以使用基于范围、哈希、精确等多种分片算法。 4. 连接到 Sharding-Proxy:在应用程序中,需要修改数据库连接信息,将原来连接数据库的地址改为连接 Sharding-Proxy 的地址。这样应用程序就可以通过 Sharding-Proxy 访问分片后的数据。 5. 进行分库分表操作:现在你可以在应用程序中执行正常的数据库操作,而无需关心具体的分库分表细节。Sharding-Proxy 会根据配置的规则自动将数据路由到正确的库和表中。 需要注意的是,使用 Sharding-Proxy 进行分库分表操作需要仔细考虑数据一致性、事务处理、跨库查询等问题。在配置和使用过程中,建议参考官方文档和示例来确保正确性和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值