【问题标题】:Why are duplicate UUIDs being generated from python on GCP?为什么在 GCP 上从 python 生成重复的 UUID?
【发布时间】:2020-06-10 20:32:52
【问题描述】:

我正面临这个奇怪的问题。我的一些 (5%) celery 任务被默默地放弃了。

在 celery 日志中进行了一些挖掘,我发现在某些情况下,会为不同的任务生成相同的任务 ID。自然,任何新任务都会覆盖具有相同任务 ID 的现有任务;导致旧任务静默删除(如果未执行)。

在 1.5 小时内,相同的 UUID 生成了 3 次。我做了一些随机抽样,结果在同一台机器上出现了这种情况,时间跨度很短(1-2 小时)。服务器每天生成大约 100 万个 UUID。一个 7 位的小数与 38 位的数字相比 - 可能的 UUID 的数量。

我在 Linux VM 上运行 python 3.6 和 celery 4.4.2。

Celery使用python的uuid.uuid4:Reference

我不知道如何从这里开始。 python 版本(或 linux 内核)中是否存在错误、某些配置问题或硬件/VM 错误? 所有情况似乎都不太可能。

更新:

VM 是运行 ubuntu 18 LTS 的标准 Google Cloud Platform 计算实例。

【问题讨论】:

  • 有趣。 uuid4 just calls os.urandom 的字节来源,所以我猜这是一个特定于平台的随机性问题?
  • 你有任何关于虚拟机如何与底层硬件交互的细节吗?我很好奇在这样的设置中随机性实际上来自哪里。
  • @bnaecker 我在我的问题中添加了更多信息
  • 人们过去曾见过 uuid4 冲突 (github.com/ramsey/uuid/issues/80),但在这种特殊情况下得出的结论是这是系统问题
  • 您的可见性超时时间是多少?

标签: python google-cloud-platform celery uuid


【解决方案1】:

我不知道为什么,但我实施了一种解决方法。

我猴子修补了uuid.uuid4。出于某种原因,我无法对 celery.utils.uuidkombu.utils.uuid 做同样的事情。

我制作了一个非常简单的随机数生成器,它将系统纳米时间和主机名连接起来,并生成一个 UUID:

def __my_uuid_generator():
    time_hex = float.hex(time.monotonic())[4:-4]  # 13 chars
    host = hex(abs(hash(socket.gethostname())))[2:]  # 16 chars
    hashed = bytes(f'{time_hex}{host}', 'ascii').hex()[:32]  # always a 32 chars long hex string
    return uuid.UUID(hashed)

# Monkey patch uuid4, because https://stackoverflow.com/q/62312607/1396264. Sigh!
uuid.uuid4 = __my_uuid_generator

【讨论】:

  • 只是让你知道 - 运行重复任务是可能的,这不是因为 UUID 冲突,而是因为我在上面的评论中写的......
  • @DejanLekic 在时间范围内有重复acks_late。另外,在执行上述操作后,我没有得到重复。
猜你喜欢
  • 2016-02-25
  • 2011-03-15
  • 2014-08-17
  • 1970-01-01
  • 2019-04-01
  • 2018-11-15
  • 2019-08-20
  • 1970-01-01
  • 2019-02-03
相关资源
最近更新 更多