我正在一个系统中工作,其中物联网设备连接并发送包含遥测数据的数据包。
设备以一秒分辨率对遥测报告添加时间戳,但它们还提供指示其顺序的“序列号”,以帮助检测重复项等。序列号是一个包装字节,即253,254,255,0,1.
我将数据存储在 DynamoDB 中,并希望使用 ULID 作为排序键来维护顺序但创建唯一性,因为您可能会在同一秒内收到多个报告。
我必须假设一个短暂的环境,其中我的 ULID 的创建只能依赖于第二个分辨率时间戳和序列号。
在大多数情况下,从时间戳创建 ULID 应该没问题。但是当同一秒内有多个报告时,如何确保 ULID 排序呢?
我推测可能只需将第二个分辨率时间戳增加以毫秒为单位的序列号即可稍微播种 ULID。
此解决方案有两个问题:
这不是一个大问题,因为它只有一秒的分辨率,最大增量 255 毫秒不会破坏数据,但它看起来仍然是一个 hacky 解决方法。
Time: 2024-09-28T22:36:19+00:00, Sequence: 254 Time: 2024-09-28T22:36:19+00:00, Sequence: 255 Time: 2024-09-28T22:36:19+00:00, Sequence: 0
第三个报告(实际上是最新报告)将被分配一个 ULID,该 ULID 按字典顺序小于其前一个报告。
根据规范,ULID具有毫秒分辨率。鉴于您预计同一秒内不会有超过 999 份报告,这可能没问题。
时间戳
48 位整数 UNIX 时间(以毫秒为单位) 直到公元 10889 年才会耗尽空间。
但是,如果您遇到需要将数据存储在亚毫秒记录中的问题;可以设计自己的按字典顺序排序的时间戳和随机值编码,类似于 ULID,但用特定序列替换随机性,因为在该分辨率下,从良好的随机性源读取数据本身可能会很昂贵。
该方案可以采用以下形式,使用从足够好的随机性源读取的随机值和原子整数序列:
将 R 和 N 的值更改为所需的大小。需要随机源来确保从每个虚拟机或进程存储的记录不会与同一序列中同时存储的任何其他记录发生冲突。