我过去通常使用数据库序列实现 序列号生成。
例如使用 Postgres SERIAL 类型 http://www.neilconway.org/docs/sequences/
我很好奇如何为没有数据库的大型分布式系统生成序列号。是否有人对以 线程安全 方式为多个客户端实现序列号生成的最佳实践有任何经验或建议?
原文由 Jonathan Holloway 发布,翻译遵循 CC BY-SA 4.0 许可协议
我过去通常使用数据库序列实现 序列号生成。
例如使用 Postgres SERIAL 类型 http://www.neilconway.org/docs/sequences/
我很好奇如何为没有数据库的大型分布式系统生成序列号。是否有人对以 线程安全 方式为多个客户端实现序列号生成的最佳实践有任何经验或建议?
原文由 Jonathan Holloway 发布,翻译遵循 CC BY-SA 4.0 许可协议
4 回答1.4k 阅读✓ 已解决
4 回答1.3k 阅读✓ 已解决
1 回答2.6k 阅读✓ 已解决
2 回答741 阅读✓ 已解决
2 回答1.7k 阅读
2 回答1.7k 阅读
2 回答1.3k 阅读
好的,这是一个非常古老的问题,我现在第一次看到它。
您需要区分 序列号 和 唯一 ID ,它们(可选)可根据特定标准(通常是生成时间)松散排序。真正的序列号意味着知道所有其他工作人员所做的事情,因此需要共享状态。没有简单的方法可以以分布式、大规模的方式执行此操作。您可以查看网络广播、每个工作人员的窗口范围以及 唯一工作人员 ID 的分布式哈希表等 内容,但这需要大量工作。
唯一 ID 是另一回事,有几种以去中心化方式生成唯一 ID 的好方法:
a) 你可以使用 Twitter 的 Snowflake ID 网络服务。 雪花是一个:
b) 您可以使用 源自 UUID 和 Snowflake 的 ID 生成方式的方法在客户端上生成唯一的 ID。 有多种选择,但大致如下:
最重要的 40 位左右: 时间戳; ID的生成时间。 (我们使用时间戳的最高有效位来使 ID 按生成时间排序。)
接下来的 14 位左右: 每个生成器计数器, 每个生成器都会为每个生成的新 ID 递增 1。这确保在同一时刻(相同时间戳)生成的 ID 不会重叠。
最后 10 位左右: 每个生成器的唯一值。 使用它,我们不需要在生成器之间进行任何同步(这非常困难),因为所有生成器都会因为这个值而产生不重叠的 ID。
c) 您可以仅使用 时间戳和随机值在客户端生成 ID。 这避免了了解所有生成器并为每个生成器分配唯一值的需要。另一方面,不能 保证 此类 ID 是全局唯一的,它们 很可能 是唯一的。 (要发生碰撞,一个或多个生成器必须同时创建相同的随机值。)大致如下:
d) 简单的出路, 使用 UUIDs / GUIDs 。