V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
CUMTProgrammer
V2EX  ›  程序员

分布式高并发情况下 UUID 会重复吗?

  •  
  •   CUMTProgrammer · 2018-09-12 09:05:07 +08:00 · 40177 次点击
    这是一个创建于 2255 天前的主题,其中的信息可能已经有所发展或是发生改变。
    23 条回复    2018-09-13 11:16:53 +08:00
    lihongming
        1
    lihongming  
       2018-09-12 09:19:28 +08:00 via iPhone
    会,但概率比中 500 万低多了,一般没必要花时间在这个问题上,因为这点错误通常不值那么多钱(远低于开发成本)
    zeromake
        2
    zeromake  
       2018-09-12 09:21:46 +08:00 via Android
    可以考虑加入些变量,比如每个节点的 IP 之类的
    geelaw
        3
    geelaw  
       2018-09-12 09:35:03 +08:00   ❤️ 2
    上古时期的生成算法直接存下来了 MAC,所以不同机器上的不会重复。同一个机器上,只要时间没有回跳,(好像)是 340 年内不会重复的。

    我不清楚最新的生成算法是怎么样的,据说基本上全是伪随机数生成器出来的。

    扩展阅读:

    CoCreateGuid API

    https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cocreateguid

    Use CoCreateGuid when you need an absolutely unique number that you will use as a persistent identifier in a __distributed__ environment.

    UuidCreate API

    https://docs.microsoft.com/en-us/windows/desktop/api/rpcdce/nf-rpcdce-uuidcreate
    puperSB
        4
    puperSB  
       2018-09-12 10:00:44 +08:00
    @zeromake uuid 的生成不是包括了网卡 mac 地址吗
    mcfog
        5
    mcfog  
       2018-09-12 10:14:44 +08:00 via Android
    先说清楚 uuid 几再讨论
    kkk330
        6
    kkk330  
       2018-09-12 10:26:11 +08:00
    id 生成器
    w292614191
        7
    w292614191  
       2018-09-12 10:35:08 +08:00
    加入毫秒数啊,我觉得这种问题特别弱。
    tinybaby365
        8
    tinybaby365  
       2018-09-12 11:04:10 +08:00
    完全的分布式,会,小概率。实际可以加上机器标识,时间信息,同时保证服务器时间不回退( Google 用原子钟)。
    CUMTProgrammer
        9
    CUMTProgrammer  
    OP
       2018-09-12 11:04:12 +08:00
    @mcfog 就是 java.util.UUID
    CUMTProgrammer
        10
    CUMTProgrammer  
    OP
       2018-09-12 11:05:55 +08:00
    @tinybaby365
    @w292614191
    UUID 已经 32 位了,再加太长了吧
    gsggwbz
        11
    gsggwbz  
       2018-09-12 11:14:41 +08:00 via Android
    snowflake 了解下
    LittlePaper
        12
    LittlePaper  
       2018-09-12 11:14:56 +08:00 via Android
    找个第三方库生成 version 1 的 uuid。java.util.UUID 好像只支持生成 version 3 和 version 4,用随机数的话数据量大,时间长了还是会重的。
    blless
        13
    blless  
       2018-09-12 11:22:04 +08:00 via Android
    用一个计数器服务生成呗 用得时候批量取就好
    w292614191
        14
    w292614191  
       2018-09-12 11:26:36 +08:00
    @CUMTProgrammer 我的做法是生成毫秒数,插入到 UUID 中间去,然后截取 32 位。
    geelaw
        15
    geelaw  
       2018-09-12 13:29:13 +08:00
    @LittlePaper #12 如果用随机来建模,前 6.8*10^(33) 个数出现重复的概率不超过 0.0001%

    @w292614191 #14 这个做法是错误的。

    @CUMTProgrammer #10 GUID 是 128 位二进制数,你是指 GUID 是 32 位十六进制数吗?
    br00k
        16
    br00k  
       2018-09-12 13:35:59 +08:00 via iPhone
    还不如直接用 ObjectId😂
    kernel
        17
    kernel  
       2018-09-12 14:31:17 +08:00
    @tinybaby365 随机的 32 字节 UUID 怎么可能会重复?你生成到太阳爆炸的那一天都不可能
    kernel
        18
    kernel  
       2018-09-12 14:48:34 +08:00
    >>> (256**16)/1000000000/86400/365
    1.0790283070806015e+22
    每秒生成 1 亿条都要这么多年,这没算错吧
    loveCoding
        19
    loveCoding  
       2018-09-12 15:36:49 +08:00
    雪花算法试试
    zhangwugui
        20
    zhangwugui  
       2018-09-12 17:09:03 +08:00
    正常来说,你的并发量如果不是贼大,基本上不会出现重复;
    另外,Twitter 的 Snowflake 也是现在经常使用的。
    w292614191
        21
    w292614191  
       2018-09-13 09:34:22 +08:00
    @geelaw 请问,为什么是错误的呢?
    LittlePaper
        22
    LittlePaper  
       2018-09-13 10:03:20 +08:00   ❤️ 2
    @kernel uuid 不是 32 字节,是 128 位 16 字节。

    上面说加变量、加毫秒的都属于歪门邪道,uuid 的格式是有标准的。自己改了就不叫 uuid 了,当然你也可以自定义一个 id 格式,只要能解决问题就行。实际上 version 1 的 time based uuid 本身就是网卡地址加时间,并且按照标准时间戳是 100 纳秒级别的(实际实现不一定)。

    关于各种类型 UUID,其优缺点,冲突概率的计算,看看维基百科就都清楚了: https://en.wikipedia.org/wiki/Universally_unique_identifier

    另外我觉得单纯依赖于随机数除了依赖于随机数生成器的质量,就完全看脸了。500 万概率虽小,2000 万还有人中呢。randomUUID() 重复的情况网上一搜就会发现有人遇到过,如果对唯一性有很高的要求的话还是可以优化一下,很多人提到的 snowflake 也是一个很好的方案。
    CUMTProgrammer
        23
    CUMTProgrammer  
    OP
       2018-09-13 11:16:53 +08:00
    @LittlePaper 谢谢了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2762 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 00:24 · PVG 08:24 · LAX 16:24 · JFK 19:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.