DRDS 全局唯一数字序列(64 位数字,对应 MySQL 中 Signed BIGINT 类型,以下简称为 Sequence)的主要目标是为了生成全局唯一和有序递增的数字序列,常用于主键列、唯一索引列等值的生成。
DRDS 中的 Sequence 主要有两类用法:
- 显式 Sequence,通过 Sequence DDL 语法创建和维护,可以独立使用;通过
select seq.nextval
获取序列值,seq
是具体 Sequence 的名字; - 隐式 Sequence,在为主键定义 AUTO_INCREMENT 后,用于自动填充主键,由 DRDS 自动维护。
注意:
- 通常情况下,仅拆分表或广播表指定了 AUTO_INCREMENT 后,DRDS 才会创建隐式的 Sequence;DRDS 并不会为非拆分表创建 Sequence,非拆分表的 AUTO_INCREMENT 字段的值由底层 RDS/MySQL 自己生成;
- 一个特例:对于 V5.3 版本,如果为非拆分表(即单表)的 AUTO_INCREMENT 字段显式指定了 BY GROUP,则 DRDS 也会为其自动创建对应的 Group Sequence,用于分布式事务的场景。
下文主要包含以下内容:
DRDS Sequence 类型与特性说明
目前共支持 4 种 Sequence 类型:
类型(缩写) | 全局唯一 | 连续 | 单调递增 | 同一连接内单调递增 | 非单点 | 数据类型 | 可读性 | 单元化能力 |
Group Sequence(GROUP) | 是 | 否 | 否 | 是 | 是 | 所有整型 | 好 | 否 |
单元化 Group Sequence(GROUP) | 是 | 否 | 否 | 是 | 是 | 所有整型 | 好 | 是 |
Time-based Sequence(TIME) | 是 | 否 | 宏观上单调递增,微观上非单调递增 | 是 | 是 | 仅支持 BIGINT | 差 | 否 |
Simple Sequence(SIMPLE) | 是 | 是 | 是 | 是 | 否 | 所有整型 | 好 | 否 |
概念解释:
- 连续:如果本次取值为 n,下一次取值一定是 n + 1,则是连续的;如果下一次取值不能保证为 n + 1,则是非连续的;
- 单调递增:如果本次取值为 n,下一次取值一定是一个比 n 大的数,则是单调递增的;
- 单点:存在单点故障风险;
-
宏观上单调递增,微观上非单调递增:类似于
1、3、2、4、5、7、6、8、......
这样的序列,这个序列从宏观是看是递增的,微观上非单调递增。 - 单元化能力:能够跨实例或跨库分配全局唯一数字序列。
Group Sequence(GROUP,默认使用)
特性
全局唯一的 Sequence,产生的值是自然数序列,但是不保证连续和单调递增。如果未指定 Sequence 类型,DRDS 默认使用 Group Sequence。
- 优点:全局唯一、不会产生单点问题、性能非常好。
- 缺点:产生的序列不连续、可能会有跳跃段;不会严格从起始值开始取值;不能循环。
实现机理
采用多个节点产生值来保证高可用,每次取出一段值,如果该段值没有取完(比如连接断掉等情形),就会产生跳跃段。
单元化 Group Sequence(GROUP)
以 Group Sequence 为基础,扩展了单元化能力,能够跨实例或跨库实现全局唯一,但同样不保证连续和单调自增。当单元化 Group Sequence 仅配置一个单元时,等价于普通的 Group Sequence。
- 优点:具备 Group Sequence 的所有优点,且扩展了单元化能力
- 缺点:同 Group Sequence
实现机理
基本原理与 Group Sequence 相同;通过扩展参数选项,支持自定义单元数量和单元索引:
- 单元数量决定了单元化 Group Sequence 的全局唯一数字序列分配空间;
- 每个单元(由单元索引指定)占用全局唯一数字序列分配空间中的一个子集;
- 不同单元(指定了不同的单元索引)占用的子集之间不重叠(即不会分配相同的 Sequence 值);
- 属于同一个全局唯一数字序列分配空间的每个单元化 Group Sequence,必须指定相同的单元数量和不同的单元索引。
注意:单元化 Group Sequence 从以下版本开始提供支持:
- DRDS V5.2:V5.2.7-1606682(2018.4.27)
- DRDS V5.3:V5.3.3-1670435(2018.8.15)
Time-based Sequence(TIME)
特性
基于时间戳 + 节点编号 + 序列号组合而成的一种 Sequence,保证全局唯一和宏观自增;这种 Sequence 值的更新不依赖于数据库,也不需要持久化到数据库,仅在数据库中保留名称和类型信息,性能很好;产生的是类似于776668092129345536、776668098018148352、776668111578333184、776668114812141568、......
这样的序列值。
- 优点:全局唯一、性能很好。
- 缺点:产生的序列不连续,起始值、步长、最大值、是否循环这些参数对于 Time-based Sequence 无意义。
注意:
- 用于表中自增列时,必须使用 BIGINT 类型;
- Time-based Sequence 从以下版本开始提供支持:
- DRDS V5.2:V5.2.8-15432885(2018.11.27)
- DRDS V5.3:V5.3.6-15439241(2018.11.29)
Simple Sequence(SIMPLE)
特性
仅 Simple Sequence 支持自定义步长、最大值和循环/非循环利用。
- 优点:全局唯一、连续、单调递增,并具备最大值和循环利用等特性。
- 缺点:单点,性能较差,存在瓶颈,需要谨慎使用。
实现机理
每产生一个值都要进行一次持久化操作。
使用场景
这几种 Sequence 都保证全局唯一,均可以应用在主键列和唯一索引列。
- 大部分场景下建议选用 Group Sequence;
- 如果有跨实例或跨库分配全局唯一数字序列的需求,可以选用单元化 Group Sequence;
- 如果业务上能接受整体趋势上的宏观自增,不介意微观上的不保证自增,且不想依赖数据库的分配机制,则 Time-based Sequence 可能是合适的选择;
- 如果业务强依赖连续的 Sequence 值,此时只能使用 Simple Sequence(注意 Simple Sequence 的性能问题)。
以创建一个起始值是 100000,步长为 1 的 Sequence 为例。
- 如果采用 Simple Sequence,则会严格产生
100000、100001、100002、100003、100004、.....、200000、200001、200002、200003、......
这样的序列(全局唯一、连续、单调递增)。Simple Sequence 会保证持久化,即使发生单点问题,服务重启后依然会在断点继续产生 Sequence 值,中间不会产生跳跃段。Simple Sequence 的机理是每产生一个值都要进行一次持久化操作,因此性能并不是很好。 - 如果采用 Group Sequence 或 单元化 Group Sequence,产生的序列有可能是
200001、200002、200003、200004、100001、100002、100003、......
这样的序列。
注意:
- Group Sequence 起始值并不会严格从设定的参数(本例中是100000)开始,但保证比该参数大。本例中是从 200001 开始取值的。
- Group Sequence 保证全局唯一,但是会有跳跃段。比如 Group Sequence 的某个节点失效,或者某个连接只取了一部分值,然后该连接被关闭了,都会产生跳跃段。该例中 200004 和 100001 之间产生了跳跃段。
- 单元化 Group Sequence 跨实例或跨库的全局唯一性,必须通过指定相同的单元数量和不同的单元索引来保证。