数据访问代理提供了生成分布式环境下的分布式唯一序列(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 规则为示例:
全局序列
通过配置分布式序列,获取全局序列的核心步骤如下:
在 DB 中创建
dbp_sequence
表。建议您在数据访问代理中创建逻辑表
dbp_sequence
时,让数据访问代理去创建 DB 中的dbp_sequence
表(数据访问代理会按照分表规则,自动创建相应的表)。假如是分表模式,则添加的分表必须以
sharding_col
为分表字段,例如#sharding_col#%4
,注意这个字段不能变。
在客户端使用
SELECT user.nextval FROM dual WHERE sharding_col = xxxx
去获取 sequence。其中,
dual
和sharding_col
不能变。user
代表客户的逻辑表,会被数据访问代理填充到dbp_sequence
表的name
字段里面去,表示该 sequence 是为user
这个表产生的。但是,这里没有强相关性,只是为了程序中好控制唯一性。
数据访问代理上的逻辑表,示例如下:
dbp_sequence
的分表规则,示例如下:
物理数据库中的表和内容示例如下:
表中内容是客户端运行 SQL 后自动创建的,其中 SQL 是用来获取 sequence 的。
获取 sequence 的 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 | 修改时间。 |