分布式序列号生成?

新手上路,请多包涵

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

例如使用 Postgres SERIAL 类型 http://www.neilconway.org/docs/sequences/

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

原文由 Jonathan Holloway 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 365
1 个回答

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

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

唯一 ID 是另一回事,有几种以去中心化方式生成唯一 ID 的好方法:

a) 你可以使用 Twitter 的 Snowflake ID 网络服务 雪花是一个:

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

b) 您可以使用 源自 UUID 和 Snowflake 的 ID 生成方式的方法在客户端上生成唯一的 ID。 有多种选择,但大致如下:

  • 最重要的 40 位左右: 时间戳; ID的生成时间。 (我们使用时间戳的最高有效位来使 ID 按生成时间排序。)

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

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

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

  • 最高32位: Timestamp, ID的生成时间。
  • The least significant 32 bits: 32位随机数, 为每个ID重新生成。

d) 简单的出路, 使用 UUIDs / GUIDs

原文由 user84609 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题