UUID随机生成有重复项

时间:2015-01-15 19:29:04

标签: java random jvm uuid production

我正在使用以下函数生成UUID

UUID.randomUUID().toString()

在生产中,我们有50多台服务器(应用服务器 - 每台服务器本身就是一台JVM)以及落在这些服务器上的请求,作为第一步,我们生成一个基本上唯一标识事务的UUID。

我们观察到的是,在服务器6和服务器11中,生成的UUID每天至少匹配10到15条消息,这很奇怪,因为考虑到负载,即每天约100万条交易,这些UUID在内部重复同一天很奇怪。

这是我们到目前为止所做的工作

  1. 验证了应用程序日志 - 我们在那里找不到任何可疑的内容,所有日志都正常
  2. 尝试在测试环境中以类似的生产负载和50多台服务器复制此问题 - 但这在测试环境中没有发生
  3. 检查了应用程序逻辑 - 这似乎不是问题,因为除了6和11之外的所有其他48个服务器都具有相同代码库的副本,它们工作得非常好,并且它们每个事务都会生成唯一的UUID。
  4. 到目前为止,我们还无法追踪这个问题,我的问题基本上是在JVM级别有什么东西我们丢失了,或者我们需要为这一个问题设置UUID参数吗?

3 个答案:

答案 0 :(得分:4)

考虑到时间,我确定你会找到罪魁祸首。与此同时,有一条评论我认为值得提升回答:

您正在多个位置生成伪随机UUID。如果您没有发现其他错误,请考虑在一个位置生成所有伪随机UUID,或生成真正的随机UUID

所以创建一个UUID服务器。这只是一个产生UUID块的过程。每个块可能包含10,000个(或任何适当的)UUID。在进程验证块不包含重复项后,该进程将每个块写入磁盘。

创建另一个进程以分发UUID块。也许它只是一个Web服务,它在收到请求时返回一个未使用的块。事务服务器发出对块的请求,然后在创建事务时使用这些UUID。当服务器使用了大多数已分配的UUID时,它会请求另一个块。

答案 1 :(得分:0)

我不会浪费时间想知道UUID.randomUUID()是如何每天生成一些重复的UUID的。偶然发生的可能性很小。 (如果底层的RNG状态被复制,则可能生成一系列完整的复制品 ,但事实并非如此。)

相反,应查找一台服务器存储的UUID可能破坏另一台服务器存储的UUID的位置。为什么仅在50台服务器中的2台之间发生这种情况?这与尚未共享的环境和系统的细节有关。

答案 2 :(得分:0)

如上所述,合法碰撞的可能性很小。如果这些值曾经以不正确的方式在对象之间传输,则更有可能。

对于像Java这样的通过引用传递的语言,请考虑以下情形

set

在这种情况下,saveObject1和saveObject2将具有相同的值,因为它们都指向相同的对象引用(initObj的UUID引用)。

像这样的问题似乎比实际的UUID更有可能发生冲突,尤其是如果可以重现的话。自然,如果不是一直都发生这种情况,那可能是更复杂的情况,例如罕见的竞争状况,其中initObj不能及时重新初始化,导致saveObject1和2共享相同的对象引用。