分布式序列

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

重要

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

普通序列

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

SELECT order_seq.nextval FROM dual

业务序列

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

  • 提升 Sequence 表的读写能力。

  • 提升 Sequence 表的可用性,无单点故障。

  • 通过将 Sequence 表和业务数据表部署在一起,保持数据拆分规则一致,方便生成业务主键。

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

SELECT
  order_seq.timestamp, order_seq.dbtimestamp, order_seq.groupid,
  order_seq.tableid, order_seq.nextval
FROM dual
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 建表语句

CREATE TABLE dbp_sequence (
`id` INT AUTO_INCREMENT,
`name` VARCHAR(255),
`value` INT,
`min_value` BIGINT,
`max_value` BIGINT,
`step` BIGINT,
`gmt_create` DATETIME,
`gmt_modified` DATETIME,
  PRIMARY KEY (`id`),
  UNIQUE KEY (`name`)
);

字段说明:

字段名称

类型

说明

name

VARCHAR

记录对应的业务表名,例如:trade_order。

min_value

BIGINT

Sequence 最小值,用于校验 Sequence 不能低于该数值,否则报错,默认为 1。

max_value

BIGINT

Sequence 最大值,当到达最大值以后,将从 min_value 开始重新增加,默认为 99999999。

step

BIGINT

一次获取的 Sequence 区间,默认 10000。

value

INT

当前 Sequence 值。

gmt_create

DATETIME

创建时间。

gmt_modified

DATETIME

修改时间。