分布式序列号生成?

过去我通常使用数据库序列来实现序列号生成

e、 g.使用Postgres串行类型http://www.neilconway.org/docs/sequences/

不过,我很好奇如何为没有数据库的大型分布式系统生成序列号。对于以线程安全方式为多个客户端生成序列号的最佳实践,是否有人有任何经验或建议

好的,这是一个非常古老的问题,我现在第一次看到它。

您需要区分序列号唯一ID,它们(可选)可以根据特定标准(通常是生成时间)进行松散排序。真正的序列号意味着知道所有其他工作人员都做了什么,因此需要共享状态。没有一种简单的方法可以以分布式、大规模的方式实现这一点。您可以查看网络广播、每个工作程序的窗口范围,以及针对唯一工作程序ID的分布式哈希表,但这需要大量的工作

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

a)您可以使用Twitter的Snowflake ID网络服务。Snowflake是:

  • 网络服务,即您通过网络呼叫获取唯一ID
  • 生成按生成时间排序的64位唯一ID
  • 该服务具有高度可扩展性和(潜在)高可用性;每个实例每秒可以生成数千个ID,您可以在LAN/WAN上运行多个实例
  • 用Scala编写,在JVM上运行

b) 您可以使用从UUID和Snowflake的ID的制作方式衍生出来的方法在客户机上生成唯一的ID。有多种选择,但大致如下:

  • 最高有效位约40位:时间戳ID的生成时间。(我们使用时间戳的最高有效位使ID可以按生成时间排序。)

  • 接下来的14位左右:每个生成器一个计数器,每个生成器为生成的每个新ID递增一位。这确保了在同一时刻(相同的时间戳)生成的ID不会重叠

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

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

  • 最高有效32位:时间戳,ID的生成时间
  • 最低有效32位:32位随机性,为每个ID重新生成

d) 简单的解决方法是使用uuid/guid

发表评论