1
0
mirror of https://github.com/charlienet/go-mixed.git synced 2025-07-18 00:22:41 +08:00

更新ID生成器

This commit is contained in:
2023-10-26 14:42:23 +08:00
parent 6647f96978
commit 0d124c0b79
17 changed files with 1079 additions and 150 deletions

114
idGenerator/readme.md Normal file
View File

@ -0,0 +1,114 @@
id生成服务
标识生成服务,可用于分布式环境的标识生成服务,本服务可以多实例部署。
要求
1. 全局唯一: 必须保证生成的 ID 是全局性唯一的;
2. 趋势递增: 生成的 ID 需要按照某种规则有序,便于数据库的写入和排序操作;
3. 单调递增: 后生成的标识大于前面生成的标识
3. 可用性: 需要保证高并发下的可用性。
4. 自主性: 分布式环境下不依赖中心认证即可自行生成 ID
5. 安全性: 不暴露系统和业务的信息。在一些业务场景下,需要 ID 无规则或者不规则;
标识组成
1. 时间信息,从当前时间中根据模板获取数据段。
号段模式
![号段模式](assets/双缓存号段分配.webp)
批量获取标识,业务应用使用后临近剩余数量时生成新的号段,使用双标识缓冲区方式保存。在活动缓冲区使用量达到限定值时在备缓冲区放置新的号段。
号段分配器
数据结构
1. 最大序列
2. 步长
3. 版本号
分配步骤
1. 服务端按照KEY存储当前分配的最大值
2. 获取是
序列回绕当序列递增到最大值时恢复为起始值重新开始。在使用中按照业务场景同一时间段中不能耗尽序列值。当序列发生回绕时分配器返回已回绕backward
操作接口
1. 客户端注册标识,客户端使用应用名、规则(前缀、步长、阈值、初始值)进行注册。注册成功后返回标识
标识生成规则,时间段、数字序列
1. 前缀: 使用模板方式生成,生成参数包括当前时间,时间戳。
2. 位数: 表示数据序列包含的位数如4位表示序列
3. 初始值:序列初始值,序列到达最大值时返回到初始值。
标识生成统一包含时间信息,由于在分布式环境中各应用节点时间可能并不同步,可能造成应用节点生成重复。
1. 应用端获取片段时记录当前时间(T1)
2. 请求服务端分配片段
3. 服务端记录报文到达时间(T2)
4. 服务端处理完成后记录离开时间(T3)
5. 应用端接收到响应时,记录时间(T4)
时间周期延时
1. Delay = ( T4 - T1 ) - ( T3 - T2 )
2. Offset = (( T2- T1 ) + ( T3 T4 )) / 2
应用端使用延时和偏移计算当前时间
标识服务服务器多活
微信序列号生成方案
微信序列号跟用户 uin 绑定,具有以下性质:递增的 64 位整形;使用每个用户独立的 64 位 sequence 的体系,而不是用一个全局的 64 位(或更高位) sequence ,很大原因是全局唯一的 sequence 会有非常严重的申请互斥问题,不容易去实现一个高性能高可靠的架构。其实现方式包含如下两个关键点:
1步进式持久化增加一个缓存中间层内存中缓存最近一个分配出现的 sequencecur_seq以及分配上限max_seq分配 sequence 时,将 cur_seq++,与分配上限 max_seq 比较,如果 cur_seq > max_seq将分配上限提升一个步长 max_seq += step并持久化 max_seq重启时读出持久化的 max_seq赋值给 cur_seq。此种处理方式可以降低持久化的硬盘 IO 次数,可以系统的整体吞吐量。
2分号段共享存储引入号段 section 的概念uin 相邻的一段用户属于一个号段,共享一个 max_seq。该处理方式可以大幅减少 max_seq 数据的大小,同时可以进一步地降低 IO 次数。
二进制模式
按照二进制模式处理序列号生成,各数据段按照各自的位长度组装
十进制模式
缺陷
当发生序列回绕时,不同的时间序列有不同的处理。如时间序列精度为日,那么在发生回绕时认为此时的回绕不能发生。如果应用在当日内被重启,并且发生了回绕,当前机制无法检测此问题。
序列记录可以依赖于外部存储如RedisDB等。当外部存储失效时序列可能会发生冲突。此时当时间段没有前进时可能发生重复。一般认为DB为不失效存储。
需要烦精确的选择时间段和序列的相对关系,一般情况下
ID分配器工作流程
初始化
1. 创建生成器
2. 创建外部存储
3. 指定生成器生成规则,机器码长度,序列长度,序列化格式。
4. 创建双缓存,使用外部存储分配数据段。
标识分配
1. 向序列缓冲器获取下一序列
2. 向时间段分配器获取下一时间戳(传入是否回旋)
4. 由标识组装器获取
格式化器
十进制格式化,时间段格式串
二进制格式化,起始时间,时间精度