好的,这是一个很老的问题,我现在第一次看到。

您需要区分序列号和唯一ID(可选)通过特定条件(通常为生成时间)进行松散排序。真序列号意味着知道所有其他工作者都做了什么,因此需要共享的状态。没有容易的方式以分布式,高规模的方式这样做。你可以看看网络广播,每个工人的窗口范围和distributed hash tables for unique worker IDs,但它是很多工作。

唯一ID是另一回事,有几种以分散方式生成唯一ID的好方法:

>网络服务,即您进行网络呼叫以获取唯一ID;

>其产生按生成时间排序的64位唯一ID;

>并且服务具有高度可扩展性和(可能)高可用性;每个实例每秒可以生成许多个ID,并且您可以在LAN / WAN上运行多个实例;

>用Scala编写,在JVM上运行。

b)您可以使用从how UUIDs派生的方法和Snowflake的ID生成客户端自身的唯一ID。有多个选项,但是类似的东西:

>最显着的40个左右位:时间戳; ID的生成时间。 (我们使用时间戳的最高有效位,使ID可以按生成时间排序。)

>接下来的14个位:每个生成器计数器,每个生成器对于生成的每个新ID递增1。这确保在同一时刻生成的ID(相同的时间戳)不重叠。

>最后10位左右:每个发生器的唯一值。使用这个,我们不需要在生成器之间做任何同步(这是非常困难的),因为所有的生成器产生不重叠的ID,因为这个值。

c)您可以使用时间戳和随机值在客户端上生成ID。这避免了需要知道所有生成器,并且为每个生成器分配唯一的值。另一方面,这样的ID不能保证是全局唯一的,它们很可能是唯一的。 (为了碰撞,一个或多个发生器将必须在同一时间创建相同的随机值。)沿着以下线的东西:

>最高有效32位:时间戳,ID的生成时间。

>最低有效32位:32位随机性,为每个ID重新生成。