java 分布式序列号_分布式序列号生成?

问题

我一般在过去使用数据库序列实现了序列号生成。

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

#1 热门回答(105 赞)

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

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

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

a)你可以使用Twitter's Snowflake ID network service.Snowflake是:

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

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

该服务具有高度可扩展性和(可能)高度可用性;每个实例每秒可以生成数千个ID,你可以在LAN / WAN上运行多个实例;

用Scala编写,在JVM上运行。

b)你可以使用从how UUIDs派生的方法在客户端本身生成唯一ID,并制作Snowflake的ID。有多种选项,但有些内容如下:

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

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

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

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

最重要的32位:时间戳,ID的生成时间。

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

#2 热门回答(15 赞)

你可以让每个节点都有一个唯一的ID(无论如何都可以使用),然后将其添加到序列号中。

例如,节点1生成序列001-00001 001-00002 001-00003等,节点5生成005-00001 005-00002

独特 :-)

或者,如果你想要某种集中式系统,你可以考虑让你的序列服务器以块的形式给出。这显着降低了开销。例如,不是从中央服务器为每个必须分配的ID请求新ID,而是从中央服务器请求10,000个块中的ID,然后在用完时只需要执行另一个网络请求。

#3 热门回答(13 赞)

现在有更多的选择。

你这个问题是"老",我来到这里,所以我认为留下我所知道的选项(到目前为止)可能是有用的:

你可以试试Hazelcast。在它的1.9版本中,它包含了java.util.concurrent.AtomicLong的Distributed实现

你也可以使用Zookeeper。它提供了创建序列节点的方法(附加到znode名称,我更喜欢使用节点的版本号)。你要小心这一点:如果你不想在你的序列中错过数字,那可能不是你想要的。

干杯

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值