我想出了一种蒙特卡洛方法,以便在将 UUID 用于必须序列化而不会发生冲突的分布式系统时能够安全地睡觉。
from random import randint
from math import log
from collections import Counter
def colltest(exp):
uniques = []
while True:
r = randint(0,2**exp)
if r in uniques:
return log(len(uniques) + 1, 2)
uniques.append(r)
for k,v in Counter([colltest(20) for i in xrange(1000)]):
print k, "hash orders of magnitude events before collission:",v
会打印出类似的东西:
5 hash orders of magnitude events before collission: 1
6 hash orders of magnitude events before collission: 5
7 hash orders of magnitude events before collission: 21
8 hash orders of magnitude events before collission: 91
9 hash orders of magnitude events before collission: 274
10 hash orders of magnitude events before collission: 469
11 hash orders of magnitude events before collission: 138
12 hash orders of magnitude events before collission: 1
我之前听过这个公式:如果你需要存储 log(x/2) 键,请使用至少具有键空间 e**(x) 的散列函数。
重复的实验表明,对于 1000 个 log-20 空间的群体,有时早在 log(x/4) 时就会发生碰撞。
对于 122 位的 uuid4,这意味着我可以安全地睡觉,而几台计算机会随机选择 uuid,直到我有大约 2**31 个项目。我正在考虑的系统中的峰值事务大约是每秒 10-20 个事件,我假设平均为 7 个。考虑到极端的偏执,这给了我大约 10 年的操作窗口。