分布式序列号生成?
我过去通常使用数据库序列实现序列号生成。
例如,使用Postgres SERIAL type http://www.neilconway.org/docs/sequences/
我很好奇如何为没有数据库的大型分布式系统生成序列号。是否有人对以线程安全的方式为多个客户端实现序列号生成最佳实践有任何经验或建议?
我过去通常使用数据库序列实现序列号生成。
例如,使用Postgres SERIAL type http://www.neilconway.org/docs/sequences/
我很好奇如何为没有数据库的大型分布式系统生成序列号。是否有人对以线程安全的方式为多个客户端实现序列号生成最佳实践有任何经验或建议?
好吧,这是一个非常古老的问题,我现在第一次看到。
您需要区分序列号和唯一 ID,这些 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)简单的方法,使用UUID / GUID。
您可以让每个节点都有一个唯一的 ID(您可能有),然后将其附加到序列号之前。
例如,节点 1 生成序列 001-00001 001-00002 001-00003 等,节点 5 生成序列 005-00001 005-00002
独特:-)
或者,如果你想要某种集中式系统,你可以考虑让你的序列服务器以块的形式给出。这大大降低了开销。例如,您不必为必须分配的每个 ID 从中央服务器请求一个新 ID,而是从中央服务器请求 10,000 个块的 ID,然后只需在用完时执行另一个网络请求。