# sequence **Repository Path**: sections/sequence ## Basic Information - **Project Name**: sequence - **Description**: sequence是一个基于数据库实现的分布式全局序列号生成器,适用于分布式场景下需要连续递增或递减序号的场景 - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 3 - **Created**: 2022-12-27 - **Last Updated**: 2024-10-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 1 简介 sequence是一款轻量的分布式序列号生成器 基于数据库实现的分布式全局序列生成,适用于分布式场景下需要连续递增或递减序号的场景,具备以下特点: - 简单轻量 - 开箱即用 - 可扩展性强 # 2 主要概念 - 序列号:从小到大或从大到小逐渐递增或递减的数字序列,可以用于数据库表ID,业务编号等场景 - 序列号Key:序列号的唯一标识 - 序列号初始值:序列号默认从0开始,也可以指定初始值为任何其他值 - 序列号步长:序列号默认自动增步长为1,也可以指定为负数,负数步长可以实现从大到小的序列 - 序列号缓存:为了提升序列号获取性能,可以使用序列号缓存机制,缓存值必须大于0: * 当缓存值为1时,每次从数据库获取1个ID,相当于没有缓存 * 当缓存值大于1时,每次从数据库获取多个ID并缓存到本地内存中,后续优先从缓存中获取ID - 默认序列号:系统内置了一个默认序列号,key为default,初始值为0,步长为1,缓存大小为50,可以开箱即用 - 自定义序列号:用于可以定义自己的序列号,为不同key的序列号设置不同的初始值、步长和缓存大小 - 跳号:序列号一旦生成后,如果业务异常没有使用,或者服务器重启缓存丢失,都会导致跳号现象产生 * 如果业务没有严格要求序号必须连续可以忽略 * 如果业务要序号求必须连续可以配置缓存为1或者使用Redis缓存 # 3 快速开始 ## 3.1 引入 基于springboot的应用可以使用下面的starter引入sequence组件 ```xml io.gitee.sections sequence-spring-boot-starter 版本 ``` ## 3.2 建表 建表SQL参考sequence-core包中的script目录下的create_table.sql ```sql CREATE TABLE `SEQ_SEQUENCE` ( `KEY` CHAR(255) NOT NULL PRIMARY KEY COMMENT '序列号标识', `INITIAL` INT NOT NULL COMMENT '序列初始值', `STEP_SIZE` INT NOT NULL COMMENT '序列步长大小', `CACHE_SIZE` INT NOT NULL COMMENT '序列缓存大小', `CACHE_MODE` CHAR(255) NOT NULL COMMENT '序列缓存模式', `NUMBER` BIGINT NOT NULL DEFAULT 0 COMMENT '序列号当前最新值' ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='序列号生成器记录表' ``` ## 3.3 注入 sequence组件中已经声明了SequenceGenerator的Bean,可以直接注入使用 ```java @Autowired private SequenceGenerator sequenceGenerator; ``` ## 3.4 使用 调用next方法获取默认序列的下一个序列号 ```java Long id = sequenceGenerator.next(); ``` # 4 自定义序列 sequence组件支持创建多个独立的序列,每个序列可以单独配置初始值、步长和缓存池大小,你需要为每个序列指定一个key作为唯一标识; 组件自动初始化了一个默认序列,默认序列的key为default,初始值为0,步长为1,缓冲池大小为50; SequenceGenerator接口有两个next方法,分别用于获取默认序列的值或指定序列的值: ```java public interface SequenceGenerator { //获取默认序列的下一个值 Long next(); //获取指定序列的下一个值 Long next(String key); } ``` ## 4.1 使用默认参数 调用带参数key的next方法获取下一个序列号,指定序列的key,若该key不存在,则会自定创建一个对应的序列。自动创建的序列的初始值、步长和缓存大小与默认序列参数相同 ```java Long id = sequenceGenerator.next("mySequence"); ``` 可以通过如下的yml配置修改默认序列的参数 ```yaml sequence: config: sequences: - key: defalt initial: 0 #初始值 step-size: 1 #步长 cache-size: 50 #缓存池大小 ``` ## 4.2 使用自定义参数 ### 基于YML配置 如果不想使用默认参数创建序列,可以通过如下的yml配置,为指定key的序列的配置单独的初始值、步长和缓存大小 ```yaml sequence: config: sequences: - key: mySequence1 initial: 100 step-size: 1 cache-size: 100 - key: mySequence2 initial: 0 step-size: -1 cache-size: 10 ``` 然后再使用下面的代码可以获取对应配置的序列号值,对应的序列号将基于yml配置中的参数来初始化 ```java Long id1 = sequenceGenerator.next("mySequence1"); Long id2 = sequenceGenerator.next("mySequence2"); ``` ### 基于数据库配置 yml中的配置在程序启动后会记录到数据库中,因此也可以在数据库中直接配置或修改对应的key和序列参数,yml配置的优先级高于数据库配置 |KYE|INITAIL|STEP_SIZE|CACHE_SIZE|CAHCE_MODE|NUMBER| |---|---|---|---|---|---| |default|0|1|50|inMemory|0| |mySequence1|100|1|100|inMemory|100| |mySequence2|0|-1|10|inMemory|-20| # 5 使用Redis缓存 squence组件默认使用本地内存缓存模式,在分布式环境下,不同节点各自缓存并生成id,会打破序列的严格递增性,最终呈现趋势递增,且服务重启时会存在跳号的问题 如果业务不能接受跳号的情况或必须要求严格递增,可以采用Redis缓存来实现,步骤如下: 第一步:需要引入SpringDataRedis并配置好redis链接信息即可,sequence组件会自动检测RedisTemplate类型的bean,用于访问redis缓存 ```xml org.springframework.boot spring-boot-starter-data-redis 版本 ``` sequence组件使用的缓存key前缀为**sequence:key:** > 可以参考Demo:https://gitee.com/sections/sequence/tree/master/sequence-demos/sequence-demo-spring-boot-redis 第二步:配置对应序列的cache-mode为redis ```yaml sequence: config: sequences: - key: mySequence1 initial: 100 step-size: 1 cache-size: 100 cache-mode: redis - key: mySequence2 initial: 0 step-size: -1 cache-size: 10 ``` > 没有配置cache-mode的序列其cache-mode的默认值为inMemory,表示使用默认的内存缓存模式 # 6 使用Standalone模式 sequence组件默认使用当前系统spring容器中的DataSource来实现对数据库的访问, 也支持独立的数据库访问模式,只需要单独配置数据库访问参数即可触发standalone模式; ```yaml sequence: config: datasource: url: jdbc:mysql://localhost:3306/schema username: abc password: 123 driver: com.mysql.cj.jdbc.Driver ``` > 可以参考Demo:https://gitee.com/sections/sequence/tree/master/sequence-demos/sequence-demo-spring-boot-standalone