在 DynamoDB 中使用 ULID 按接收顺序存储遥测数据

问题描述 投票:0回答:1

我正在一个系统中工作,其中物联网设备连接并发送包含遥测数据的数据包。

设备以一秒分辨率对遥测报告添加时间戳,但它们还提供指示其顺序的“序列号”,以帮助检测重复项等。序列号是一个包装字节,即253,254,255,0,1.

我将数据存储在 DynamoDB 中,并希望使用 ULID 作为排序键来维护顺序但创建唯一性,因为您可能会在同一秒内收到多个报告。

我必须假设一个短暂的环境,其中我的 ULID 的创建只能依赖于第二个分辨率时间戳和序列号。

在大多数情况下,从时间戳创建 ULID 应该没问题。但是当同一秒内有多个报告时,如何确保 ULID 排序呢?

我推测可能只需将第二个分辨率时间戳增加以毫秒为单位的序列号即可稍微播种 ULID。

此解决方案有两个问题:

  1. ULID 的真实来源值有所丢失。

这不是一个大问题,因为它只有一秒的分辨率,最大增量 255 毫秒不会破坏数据,但它看起来仍然是一个 hacky 解决方法。

  1. 序列号翻转的边缘情况没有得到适当的解决。如果我有三份报告:

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 按字典顺序小于其前一个报告。

database sorting amazon-dynamodb lexicographic-ordering ulid
1个回答
0
投票

根据规范,ULID具有毫秒分辨率。鉴于您预计同一秒内不会有超过 999 份报告,这可能没问题。

时间戳

48 位整数 UNIX 时间(以毫秒为单位) 直到公元 10889 年才会耗尽空间。

但是,如果您遇到需要将数据存储在亚毫秒记录中的问题;可以设计自己的按字典顺序排序的时间戳和随机值编码,类似于 ULID,但用特定序列替换随机性,因为在该分辨率下,从良好的随机性源读取数据本身可能会很昂贵。

该方案可以采用以下形式,使用从足够好的随机性源读取的随机值和原子整数序列:

  1. 在应用程序启动时,从可靠的随机源读取 R 位
  2. 将原子整数序列初始化为0
  3. 每条新记录要存储:
    1. 创建一个空字节数组
    2. 将微秒分辨率时间戳推入字节数组(采用 MSB 排序)
    3. 将随机值推入字节数组
    4. 将当前整数序列的前 N 位压入数组的末尾
    5. 原子地递增整数序列
    6. 将字节数组编码为字符串;例如,包含所有字母和数字的环。

将 R 和 N 的值更改为所需的大小。需要随机源来确保从每个虚拟机或进程存储的记录不会与同一序列中同时存储的任何其他记录发生冲突。

© www.soinside.com 2019 - 2024. All rights reserved.