簡體   English   中英

隨機生成的 UUID 有重復

[英]UUID Generated randomly is having duplicates

我正在使用下面的函數來生成 UUID

UUID.randomUUID().toString()

在生產環境中,我們有 50 多台服務器(應用程序服務器——每個服務器都是一個 JVM),對於登陸這些服務器的請求,第一步我們生成一個 UUID,它本質上唯一地標識了一個事務。

我們觀察到的是,在服務器 6 和服務器 11 中,生成的 UUID 每天至少匹配 10 到 15 條消息,這很奇怪,因為給定負載,即每天大約 100 萬個事務,這些 UUID 在同一天內重復很奇怪。

這是我們迄今為止所做的

  1. 驗證了應用程序日志 - 我們沒有發現任何可疑的東西,所有日志都正常
  2. 嘗試在具有類似生產負載和 50 多台服務器的測試環境中復制此問題 - 但這在測試環境中沒有發生
  3. 檢查應用程序邏輯 - 這似乎不是問題,因為除 6 和 11 之外的所有其他 48 台服務器都具有相同代碼庫的副本,它們運行良好,並且它們為每個事務生成唯一的 UUID。

到目前為止,我們還沒有能夠追蹤到這個問題,我的問題基本上是我們是否缺少 JVM 級別的某些東西,或者我們需要為這個問題設置 UUID 參數?

給定時間,我相信你會找到罪魁禍首。 與此同時,有一條評論我認為值得提升回答:

您正在多個位置生成偽隨機 UUID。 如果您沒有發現其他錯誤,請考慮在一個位置生成所有偽隨機 UUID,或者生成真正的隨機 UUID

所以創建一個UUID服務器。 這只是一個生成 UUID 塊的過程。 每個塊可能包含 10,000 個(或任何合適的)UUID。 在進程驗證塊不包含重復項后,進程將每個塊寫入磁盤。

創建另一個進程來分發 UUID 塊。 也許它只是一個 Web 服務,它在收到請求時返回一個未使用的塊。 交易服務器發出一個區塊請求,然后在創建交易時使用這些 UUID。 當服務器使用了大部分分配的 UUID 時,它會請求另一個塊。

我不會浪費時間想知道UUID.randomUUID()如何UUID.randomUUID()生成一些重復的 UUID。 這種偶然發生的可能性是無窮小的。 (生成一整套重復可能的——如果底層 RNG 狀態是重復的,但情況似乎並非如此。)

相反,尋找一個服務器存儲的 UUID 可能會破壞另一個服務器存儲的 UUID 的地方。 為什么這只會發生在 50 台服務器中的 2 台之間? 這與尚未共享的環境和系統的詳細信息有關。

如上所述,發生合法碰撞的可能性非常小。 更可能的情況是值是否曾經以不正確的方式在對象之間傳輸。

對於像 Java 這樣表現為通過引用傳遞的語言,請考慮以下場景

saveObject1.setUUID(initObj.getUUID())
initObj.setUUID(UUID.randomUUID());
saveObject2.setUUID(initObj.getUUID()) 

在這種情況下,saveObject1 和 saveObject2 將具有相同的值,因為它們都指向相同的對象引用(initObj 的 UUID 引用)。

像這樣的問題似乎比實際的 UUID 更可能發生碰撞,尤其是如果您可以重現它。 自然地,如果它不是一直發生,那么它可能會更復雜,比如罕見的競爭條件,其中 initObj 沒有及時重新初始化,導致 saveObject1 和 2 共享相同的對象引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM