分片库内部实现

438 阅读3分钟

这是我参与2022首次更文挑战的第15天,活动详情查看:2022首次更文挑战

主要的背景都是原有的单库数据库实例的容量不足,需要进行数据库的扩展

  • 在路由机制中,会涉及到不同路由方式的迁移操作

流量图

单分片键流量;

\

批量分片键流量:

\

路由机制

hash路由:

在一开始接入的时候需要从单库迁移到分片库

  • 需要建立数据库同步链路,包括全量与增量同步
    • 同步的过程实际上就是消费binlog的过程
    • 同步都会带上分库键,在同步的过程中就会根据分库键进行hash

优势:

  • 提升读写性能

缺陷:

  • 跨分库键的range操作会进行跨库的全表扫描

改进

  • 针对range操作
    • 根据分库键进行拆分,使用不同的分库键进行range查询操作

range路由:

支持按照 日期格式 uint64 两种方式进行range分库

优势:

  • 可以更好地对range操作进行支持

缺陷:

  • 实际上针对大范围或者特大范围的range操作还是无法保证事务特性
    • 针对带有分库件的range查询
  • 在一开始进行旧数据迁移的时候,旧数据依旧会在同个range下的库,依旧存在数据库溢出的可能性

冷热数据处理

基本思想

选择 分库键 以外的另外一个键作为 冷热分离键

  • 会先根据分库键路由到对应的分片库
  • 再根据冷热分离键路由到同分片库的不同集群实例
    • 如果没有带上分库键,带上了冷热分离键
      • 会扫所有的分片对应冷热实例
    • 如果带上分库键,没有带上冷热分离键
      • 会扫对应分片的所有冷热实例

冷热数据调整过程:

  • 当没有满的时候:

  • 当冷数据实例满时

存在的问题

由于数据冷热变化每时每刻都在进行,因此每时每刻都有数据在进行迁移

  • 不支持跨冷热库的事务

读请求

  • 对于范围操作时,查询正在迁移的数据,可能会出现在热数据、冷数据都查找出数据的情况

写请求

  • 对于正在迁移的数据进行修改,数据已经迁移到了冷数据实例,并且冷热数据路由策略还未发生改变,这个时候在热数据集群上的数据修改就会丢失

解决方案

对于读问题:

  • 对应用发过来的sql请求优化时,根据当前迁移的数据进行时间范围的分割,对于边界数据只支持打到一个集群上

对于写请求:

  • 对于迁移中的数据不允许修改

扩容策略

主要有两种方式

数据归档

类似上面的冷数据的处理方式,DBA将冷数据备份出来,放到离线的存储,然后将集群中的数据删除

需要查询冷数据的时候,可以提工单让DBA帮忙查询

横向扩容

对于应用侧的分片不一定就是底层的存储实例数量

比如我有101个分片,但是可能都在同一个mysql实例上面

  • 每个实例的空间是固定的
    • 因此每个实例上的分片空间也是固定的
  • 当实例快满的时候,会将部分分片挂到另外一个实例上
    • 每一个分片可用的空间就增加了(实例空间不变,分配到的分片数少了)