任务 ID

Disque 中的任务由类似这样的 ID 进行唯一标识: DI0f0c644fd3ccb51c2cedbd47fcb6f312646c993c05a0SQ

每个任务 ID 总是以 "DI" 开头,并以 "SQ" 结束, 而且总是由正好 48 个字符组成。

任务 ID 可以被分为几个不同的部分:

DI | 0f0c644f | d3ccb51c2cedbd47fcb6f312646c993c | 05a0 | SQ

以下是各个部分的含义:

  1. DI 是 ID 的前缀。
  2. 0f0c644f 是一个节点 ID 的前 8 个字节,正是这个 ID 所记录的节点创建了这个任务。
  3. d3ccb51c2cedbd47fcb6f312646c993c 是以十六进制格式表示的、通过伪随机方式生成的 128 位 ID 。
  4. 05a0 是以分钟计算的任务生存时间。这个值使得任务 ID 可以安全地过期,即使节点并不知道任务的具体表示。
  5. SQ 是 ID 的后缀。

任务 ID 是 ADDJOB 命令在成功创建任务时的返回值, 也是 GETJOB 输出的一部分, 并且在任务已经交由工作进程(worker)处理完毕时, 可以使用任务 ID 向 Disque 报告该任务已经完成。

任务 ID 包含了一部分节点 ID , 这使得为给定队列处理任务的工作进程可以很容易地知道自己正在处理的任务是由哪个节点创建的, 然后直接向该节点发送请求, 这样可以避免将请求发送至其他无关的节点, 从而提高效率。

因为任务 ID 只是用了 32 个二进制位来储存节点 ID , 所以在包含 100 个节点的 Disque 集群里面, 这个 32 位 ID 出现碰撞的几率可以通过生日悖论(birthday paradox)计算得出:

P(100,2^32) = .000001164

在发生碰撞的情况下, 工作进程可能会做出不高效的选择。

任务 ID 中的 128 位随机生成 ID 几乎不可能出现碰撞, 因为它是由以下方法计算得出的:

128 bit ID = SHA1(seed || counter)

其中 seed 是服务器在启动时通过 /dev/urandom 生成的, 而 counter 则是一个在每次生成 ID 时都会进行自增的计数器。