使用shardingsphere实现mysql数据库分片(分库分表的实现方式)、读写分离、弹性伸缩的设计

本文探讨了在快速增长的银行业务中,如何利用Shardingsphere实现数据库的弹性伸缩和流水表治理。通过实例展示机构与分区的配置,以及如何设计数据分片策略来应对每年数亿笔的流水增长,同时介绍了主从复制和数据迁移的最佳实践。

1.对shardingsphere学习的建议,也是对所有技术学习的建议

shardingsphere和mycat类似,均是高可用数据库的解决方案中间件。这里采用shardingsphere。

如果大家对shardingsphere不了解,先找些文章或者视频看一下,入门一下,然后需要看官方文档,你在看别人的文章或者东西的时候是一个快餐,而你看官方文档的时候才是大餐,所以请一定不要错过大餐。shardingsphere官方文档:https://shardingsphere.apache.org/document/legacy/4.x/document/cn/overview/

2.背景介绍

  1. 业务背景介绍:随着银行业务发展的迅速增长,每天锁产生的流水数据越来越多,对数据库的要求越来越高,特别是弹性伸缩这块儿的要求。
  2. 这里讨论主要矛盾,流水的数据库治理。
  3. 流水微服务主要处理流水表的增删改查操作,为其他微服务提供基础服务功能。
  4. 配置微服务为整个系统的参数配置服务,主要提供一些基础系统参数配置,如字典表数据的配置。
  5. 银行支行、柜员概念这里稍作说明:支行就是咱们业务的那个门面房,柜员就是办理业务的营业员。我们每办理一笔业务就会产生一笔(有可能是多条:借贷)流水。
  6. 目前一般中小银行的流水量一天在20-30万笔。峰值在60万笔。
  7. 每年增长之多10%,设计数据库满足业务3年的发展需要,同时兼顾业务突增时的数据库的弹性伸缩。
  8. 3年后可以对数据进行历史数据迁移。
    在这里插入图片描述
    我们的关注点近在上图匡红的地方应该怎设计?
    首先看下业务增长的情况

3.流水业务的增长情况

每天按峰值60万计算,每月1800万一年:2.16亿。
2020新增(亿):2.16
2020年累计总量亿):2.16
======================================
2021新增(亿):2.3760000000000003
2021年累计总量亿):4.5360000000000005
======================================
2022新增(亿):2.6136000000000004
2022年累计总量亿):7.149600000000001
======================================
2023新增(亿):2.8749600000000006
2023年累计总量亿):10.024560000000001
======================================
2024新增(亿):3.162456000000001
2024年累计总量亿):13.187016000000002
======================================
2025新增(亿):3.4787016000000013
2025年累计总量亿):16.665717600000004
======================================
2026新增(亿):3.8265717600000015
2026年累计总量亿):20.492289360000004
======================================
2027新增(亿):4.209228936000002
2027年累计总量亿):24.701518296000007
======================================
2028新增(亿):4.630151829600003
2028年累计总量亿):29.33167012560001
======================================
2029新增(亿):5.093167012560003
2029年累计总量亿):34.424837138160015
======================================
2030新增(亿):5.602483713816004
2030年累计总量亿):40.02732085197602
======================================

到达2022年累计数据达到7.14亿,如何提高数据库的想能。

4.设计

机构和分区的关系实例,用户纵向分区:

机构号库分区号
0706670010
0706670020
0706670031
0706670042
0706670053
0706670064
0706670075
0706670086
0706670096
07066700106
0706670116

柜员和分区的关系实例,用户横向分区:

机构号表分区号
40010
40020
40031
40042
40053
40064
40075
40086
40096
… …… …
401031
… …… …
  1. 共7个主节点,纵向切分:按机构所在的分区切分;横向切分按柜员所在的分区切分。
  2. 每个主节点有两个slave节点,做读写分离
  3. 达到的效果为,3面内每个节点的数据库量在329万左右。小于500万。足够完整业务发展的需要。且余量充足。
    在这里插入图片描述
    config配置如下
schemaName: sharding_db

dataSources:
  master_ds_0:
    url: jdbc:mysql://***.***.***.***:****/db_seq?serverTimezone=UTC&useSSL=false
    username: test
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 200
  slave_ds_0:
    url: jdbc:mysql://***.***.***.***:****/db_seq?serverTimezone=UTC&useSSL=false
    username: test
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 200
  master_ds_1:
    url: jdbc:mysql://***.***.***.***:****/db_seq?serverTimezone=UTC&useSSL=false
    username: test
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 200
  slave_ds_1:
    url: jdbc:mysql://***.***.***.***:****/db_seq?serverTimezone=UTC&useSSL=false
    username: test
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 200
  master_ds_2:
    url: jdbc:mysql://***.***.***.***:****/db_seq?serverTimezone=UTC&useSSL=false
    username: test
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 200
  slave_ds_2:
    url: jdbc:mysql://***.***.***.***:****/db_seq?serverTimezone=UTC&useSSL=false
    username: test
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 200
  master_ds_3:
    url: jdbc:mysql://***.***.***.***:****/db_seq?serverTimezone=UTC&useSSL=false
    username: test
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 200
  slave_ds_3:
    url: jdbc:mysql://***.***.***.***:****/db_seq?serverTimezone=UTC&useSSL=false
    username: test
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 200
	master_ds_4:
    url: jdbc:mysql://***.***.***.***:****/db_seq?serverTimezone=UTC&useSSL=false
    username: test
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 200
  slave_ds_4:
    url: jdbc:mysql://***.***.***.***:****/db_seq?serverTimezone=UTC&useSSL=false
    username: test
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 200
	master_ds_5:
    url: jdbc:mysql://***.***.***.***:****/db_seq?serverTimezone=UTC&useSSL=false
    username: test
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 200
  slave_ds_5:
    url: jdbc:mysql://***.***.***.***:****/db_seq?serverTimezone=UTC&useSSL=false
    username: test
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 200
  master_ds_6:
    url: jdbc:mysql://***.***.***.***:****/db_seq?serverTimezone=UTC&useSSL=false
    username: test
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 200
  slave_ds_6:
    url: jdbc:mysql://***.***.***.***:****/db_seq?serverTimezone=UTC&useSSL=false
    username: test
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 200
shardingRule:
  tables:
    tb_seq:
      actualDataNodes: ms_ds_${0..6}.tb_seq${0..30}
      databaseStrategy:
        inline:
          shardingColumn: ds_zone # 流水表中数据库的分区字段 0,1,2,3,4,5,6-和支行关联配置
          algorithmExpression: ms_ds_${ds_zone}
      tableStrategy:
        inline:
          shardingColumn: tb_zone #表分区key值
          algorithmExpression: tb_seq${ds_zone}
      keyGenerator:
        type: SNOWFLAKE #5.0之后使用LEAF
        column: seq_id #主键
  bindingTables:
    - tb_seq
  defaultDataSourceName: master_ds_1
  defaultTableStrategy:
    none:
  masterSlaveRules:
    ms_ds_0:
      masterDataSourceName: master_ds_0
      slaveDataSourceNames:
        - slave_ds_0
      loadBalanceAlgorithmType: ROUND_ROBIN
    ms_ds_1:
      masterDataSourceName: master_ds_1
      slaveDataSourceNames:
        - slave_ds_1
      loadBalanceAlgorithmType: ROUND_ROBIN
    ms_ds_2:
      masterDataSourceName: master_ds_2
      slaveDataSourceNames:
        - slave_ds_2
      loadBalanceAlgorithmType: ROUND_ROBIN
    ms_ds_3:
      masterDataSourceName: master_ds_3
      slaveDataSourceNames:
        - slave_ds_3
      loadBalanceAlgorithmType: ROUND_ROBIN
    ms_ds_4:
      masterDataSourceName: master_ds_4
      slaveDataSourceNames:
        - slave_ds_4
      loadBalanceAlgorithmType: ROUND_ROBIN
    ms_ds_5:
      masterDataSourceName: master_ds_5
      slaveDataSourceNames:
        - slave_ds_5
      loadBalanceAlgorithmType: ROUND_ROBIN
    ms_ds_6:
      masterDataSourceName: master_ds_6
      slaveDataSourceNames:
        - slave_ds_6
      loadBalanceAlgorithmType: ROUND_ROBIN

5.m主+n从升级

主节点如果宕机怎么办,可以使用m主+n从模式:
在这里插入图片描述

在这里插入图片描述

6.数据迁移

  • 可以使用mysql 的Archive存储引擎,迁移后数据压缩70-80,仅支持查询和插入。为业务数据库腾出更多的空间。
  • 针对历史数据的查询和现有数据的查询逻辑不变,这样即不影响现有业务的效率对,历史数据的查询也满足业务要求。

希望对大家理解mysql数据库分片和大批量数据导致数据库瓶颈问题解决有一定的参考意义。

6.动态水位调整

每晚定时任务:对库和表的水位进行自动调整。

<think> 我们正在讨论的是在单个MySQL服务器上使用ShardingSphere进行分库分表的问题。用户之前询问了在单机上使用FEDERATED引擎模拟水平拆分的方法,现在转向询问ShardingSphere在单机环境下的适用性。 关键点: 1. ShardingSphere的核心功能是分布式数据库中间件设计目标是在多台服务器上管理分片。 2. 但ShardingSphere也支持在单个物理数据库实例中进行逻辑分片(即分库分表都在同一个MySQL实例上)。 回答结构: a) 明确回答:可以实现在线分库分表 b) 解释单机分片的本质:逻辑分片(多个逻辑库/表映射到同一个物理实例) c) 具体配置方法(示例) d) 注意事项(性能、限制等) e) 与之前FEDERATED方案的对比 f) 生成相关问题 特别注意: - 引用之前提到的FEDERATED方案时自然添加引用标记[^1] - 使用LaTeX格式表达数学表达式(如分片算法) </think> ### 在单MySQL服务器中使用ShardingSphere实现在线分库分表 **是的,ShardingSphere完全支持单MySQL服务器的在线分库分表**,其实质是通过逻辑分片将单物理库拆分为多个逻辑库/表。以下是具体实现方案: --- #### 一、核心实现原理 1. **逻辑分片 vs 物理分片** - **物理分片**:数据实际分布在不同服务器(不适用单机环境) - **逻辑分片**:数据仍在同一MySQL实例,但通过ShardingSphere路由到不同逻辑库/表 $$ \text{SQL请求} \xrightarrow{\text{ShardingSphere路由}} \begin{cases} \text{逻辑库db0.user_0} & \rightarrow \text{物理表user_0} \\ \text{逻辑库db1.user_1} & \rightarrow \text{物理表user_1} \end{cases} $$ 2. **在线操作能力** 通过**弹性伸缩模块**实现不停机分片: ```mermaid graph LR A[原表user] --> B[ShardingSphere代理] B --> C[新建分片表user_0] B --> D[新建分片表user_1] B --> E[数据迁移+双写] E --> F[流量切换] ``` --- #### 二、具体配置步骤(YAML示例) ```yaml # 定义逻辑数据源(指向同一个MySQL实例) dataSources: ds_0: !!com.zaxxer.hikari.HikariDataSource jdbcUrl: jdbc:mysql://127.0.0.1:3306/db_real?useSSL=false username: root password: 123456 # 分片规则 rules: - !SHARDING tables: user: # 逻辑表名 actualDataNodes: ds_0.user_${0..1} # 映射物理表user_0, user_1 tableStrategy: standard: shardingColumn: user_id shardingAlgorithmName: mod2 # 分片算法 shardingAlgorithms: mod2: type: MOD props: sharding-count: 2 # 分2片 ``` --- #### 三、单机分片关键特性 | **特性** | **支持情况** | **说明** | |-------------------|-------------|----------| | **在线扩缩容** | ✅ | 通过`Scaling`模块动态增减分片[^1] | | **分布式事务** | ️ 受限 | 单机可用本地事务,跨逻辑库需XA事务 | | **分片算法** | ✅ | 支持$ \text{user\_id} \mod 2 $等10+种算法 | | **跨分片查询** | ✅ | 自动合并UNION结果 | | **读写分离** | ✅ | 可在单实例配置主从模拟 | --- #### 四、与FEDERATED方案对比 | **维度** | **ShardingSphere** | **FEDERATED引擎**[^2] | |------------------|----------------------------------|--------------------------------| | 分片透明性 | 应用无需改代码 | 需手动指定分片表 | | 跨分片查询 | 自动聚合结果 | 需手动UNION | | 事务支持 | 内置弱XA事务 | 无事务保障 | | 分片算法灵活性 | 支持范围、哈希、自定义等 | 仅应用层实现 | | 管理复杂度 | 需部署Proxy中间件 | 纯数据库方案 | --- #### 五、性能优化建议 1. **连接池配置** ```yaml # 避免单机多逻辑库连接爆炸 props: max-connections-size-per-query: 5 kernel-executor-size: 16 ``` 2. **分片设计** - 选择高基数字段:如用户ID而非性别 - 热键处理:`user_id % 128 + DATE(create_time) % 4` 3. **索引策略** ```sql /* 每个物理分片表需独立创建索引 */ CREATE INDEX idx_email ON user_0(email); CREATE INDEX idx_email ON user_1(email); ``` --- #### 六、适用场景建议 - **短期过渡方案**:预计未来扩展为多物理节点 - **低成本隔离**:将不同业务隔离到不同逻辑库(如订单/用户) - **性能瓶颈突破**:单表超千万后通过分片提升查询效率 > ⚠️ **注意**:单机分片无法突破单服务器硬件极限,CPU/IO瓶颈需物理分库[^3]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值