全部产品

分布式序列

更新时间:2020-03-18 16:50:23

数据访问代理提供了生成分布式环境下的分布式唯一序列(Sequence)的能力,该序列有全局唯一、全局递增的特性,常用于分库分表下的主键、业务主键生成的场景。

注意:数据访问代理分布式序列功能是基于数据库实现,如果需要使用该功能,需要在业务数据库中创建 dbp_sequence 表。

普通序列

数据访问代理的分布式序列功能提供了类 Oracle 语法的 SQL 语句,seq_name.nextval,其中 seq_name 是任意字符串,一般是一张逻辑表使用同一个 seq_name。使用如下:

  1. SELECT order_seq.nextval FROM dual

基于单库单表的 dbp_sequence 表实现。

业务序列

如前面提到的,分布式序列功能基于数据库表实现,dbp_sequence 可以部署成单库单表模式,同样也可以部署成分库分表模式,分库分表模式下有如下优点:

  • 提升 Sequence 表的读写能力。
  • 提升 Sequence 表的可用性,无单点故障。
  • 通过将 Sequence 表和业务数据表部署在一起,保持数据拆分规则一致,方便生成业务主键。

数据访问代理的分布式序列在 nextVal 语法基础下,扩展了更多业务型的字段,在获得 Sequence 值之外,还可以获得更多分库分表相关的信息,开发者可以根据实际场景灵活组装业务的序列号。使用如下:

  1. SELECT
  2. order_seq.timestamp, order_seq.dbtimestamp, order_seq.groupid,
  3. order_seq.tableid, order_seq.nextval
  4. FROM dual
  5. WHERE sharding_col = ?

其中各项字段的含义:

  • timestamp:获取 Sequence 的时间戳,该时间是机器时间。
  • dbtimestamp:获取 Sequence 数据库的时间,使用该命令的话,数据访问代理会实时向物理数据库请求当前时间。
  • groupid:获取 Sequence 所在分片的 ID。
  • tableid:获取 Sequence 所在分表的 ID。
  • sharding_col:获取 Sequence 的分库分表字段,该字段是虚拟并不真实存在,用以方便数据访问代理计算分库分表规则。

配置分表规则

在数据库中添加 dbp_sequence 表的分表规则,以下是以 100 个分片 100 个分表,以 sharding_col 字段 hash 规则为示例:

rule

全局序列

通过配置分布式序列,获取全局序列的核心步骤如下:

  1. 在 DB 中创建 dbp_sequence 表。

    • 最好是在数据访问代理中创建逻辑表 dbp_sequence 的时候,让数据访问代理去创建 DB 中的 dbp_sequence 表(数据访问代理会按照分表规则,自动创建相应的表)。
    • 假如是分表模式,则添加的分表必须以 sharding_col 为分表字段,例如 #sharding_col#%4 ,注意这个字段不能变。
  2. 在客户端使用 SELECT user.nextval FROM dual WHERE sharding_col = xxxx 去获取 sequence。

    • 其中,dualsharding_col 不能变。
    • user 代表客户的逻辑表,会被数据访问代理填充到 dbp_sequence 表的 name 字段里面去,表示该 sequence 是为 user 这个表产生的。但是,这里没有强相关性,只是为了程序中好控制唯一性。

数据访问代理上的逻辑表,示例如下:

dbp 逻辑表

dbp_sequence 的分表规则,示例如下:

dbp_sequence 分表规则

物理数据库中的表和内容示例如下:

物理数据库表

说明:表中内容是客户端运行 SQL 后自动创建的,其中 SQL 是用来获取 sequence 的。

获取 sequence 的 SQL 代码,示例如下:

获取 sql 代码

注意事项

  • 分库分表场景下,nextval 是每个分片/分表独立递增,不同分片/分表的 nextval 会有重复的情况。所以请拼接其他信息用以区分,如:groupid
  • nextval 不保证严格递增,且也有上限,默认 nextval 在 1 ~ 99999999 中重复循环。
  • 单条 SQL 中不支持多个 Sequence 名字。

附录

dbp_sequence 建表语句

  1. CREATE TABLE dbp_sequence (
  2. `id` INT AUTO_INCREMENT,
  3. `name` VARCHAR(255),
  4. `value` INT,
  5. `min_value` BIGINT,
  6. `max_value` BIGINT,
  7. `step` BIGINT,
  8. `gmt_create` DATETIME,
  9. `gmt_modified` DATETIME,
  10. PRIMARY KEY (`id`),
  11. UNIQUE KEY (`name`)
  12. );

字段说明:

字段名称 类型 说明
name varchar 记录对应的业务表名,例如:trade_order
min_value int Sequence 最小值, 用于校验 Seqeunce 不能低于该数值,否则报错,默认为 1
max_value int Sequence 最大值,当到达最大值以后,将从 min_value 开始重新增加,默认为 99999999
step int 一次获取的 Sequence 区间,默认 10000
value bigint 当前 Sequence 值
gmt_create DATETIME 创建时间
gmt_modified DATETIME 修改时间