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

分布式系统生成全局唯一 ID 的方式请教

  •  
  •   jiobanma ·
    banmajio · 310 天前 · 8410 次点击
    这是一个创建于 310 天前的主题,其中的信息可能已经有所发展或是发生改变。

    咨询各位大佬们一个问题目前有两台服务器负载,使用 apache 的 SnowflakeShardingKeyGenerator 生成雪花算法作为 id ,业务上需要生成的 id 是递增的。 之前两台服务器的 SnowflakeShardingKeyGenerator 的 workId 都是默认的,高并发情况下,两台服务器的时间可能会有误差 就会导致生成的 id 是重复的。但是两台服务器根据不同的 workId 去生成虽然能解决重复的问题,但是会导致生成的 id 不是连续递增的。 有什么其他的方式实现吗(排过坑的[旺柴])。

    第 1 条附言  ·  309 天前
    解释一下为什么要求递增,已经目前的现状
    1. 历史原因,开发初期的同事没有考虑到负载已经后续并发的问题。项目最初的时候是单节点的所以还不会出现什么明显的问题。加上代码中存在大量的根据雪花算法生成的 id 排序比大小的操作。而目前换成了负载,两个节点轮训分担压力。就会导致两个节点生成的 id 会有碰撞的可能。别问为啥一定要求递增,问就是不想改动别人的之前写的逻辑,给自己挖坑。
    2. 出现重复的原因,a 用户的请求分发到了 A 节点,此时 b 用户的请求分发到了 B 节点,两个节点同时生成的 id 就出现碰撞的问题。

    3. 还有说使用有问题的各位,op 确实对雪花算法不太熟悉,没那么深入的了解,所以才发这个问题请教,抱着学习的太多。麻烦各位嘴下留情!
    114 条回复    2023-07-26 20:53:40 +08:00
    1  2  
    my3157
        1
    my3157  
       310 天前   ❤️ 7
    用一个专门的服务批量生成 ID , 其他服务直接从这个服务拿
    mineralsalt
        2
    mineralsalt  
       310 天前
    没用过 SnowflakeShardingKeyGenerator, 但是如果是我实现这样的需求, 能想到 2 种办法, 第一就是 redis 加锁, 但是会影响并发效率. 第二种就是发现 id 重复时递归生成一次,直到不重复为止
    mineralsalt
        3
    mineralsalt  
       309 天前
    1L 这种多引入一个服务感觉太重了, 多一个服务就多一份负担和不稳定性, 不是太优雅
    thevita
        4
    thevita  
       309 天前
    2L 提的第一个方法与 1L 本质上是一样的,都是引入一个全局一致的协调者(目前看这其实是比较现实的办法,功能简单,稳定性和性能应该能做很多优化,当然具体看你场景能否接受)
    thevita
        5
    thevita  
       309 天前
    2L 第二种也是一个办法,相当于 用 db 作为一致性保证?,乐观冲突检测的方式来做,但是 db 的事务的貌似还是得依赖全局锁的方式来支持 insert id 有序
    zhzy0077
        6
    zhzy0077  
       309 天前
    2 台服务器能承载的业务直接用数据库的 auto increment 不行吗
    CocaCola001
        7
    CocaCola001  
       309 天前
    我觉得还是新建一个服务用来生成 id 比较好,后期也方便扩展
    thevita
        8
    thevita  
       309 天前
    还不如看看你的需求只是要 “递增“ 呢,还是真的需要严格的全局有序
    SenLief
        9
    SenLief  
       309 天前   ❤️ 3
    有没有考虑过最简单的方案,使用一个大数,一台往上递增,一台往下递增
    luciankaltz
        10
    luciankaltz  
       309 天前   ❤️ 1
    > 两台服务器的时间可能会有误差 就会导致生成的 id 是重复的

    snowflake 算法初始化的时候会填入一个 machine id ,为什么两台服务器上生成出来的 id 会重复呢(
    还是说你故意设置成了一样的 machine id ,是希望所有生成出来的 id 在全局上单调递增并且唯一?

    如果是的话那就必须引入一个单点的算号服务,不管是一个 app 服务还是 db 的自增
    veike
        11
    veike  
       309 天前
    ulid 可行?
    Masoud2023
        12
    Masoud2023  
       309 天前   ❤️ 2
    想了半天为什么这东西能重复,一仔细看帖子原来没改 workerId...

    你如果非想要连续递增的 id ,那么只能考虑做个服务专门搞这种自增

    是不是某些架构设计出问题了,感觉不应该有这种问题..
    thevita
        13
    thevita  
       309 天前
    想到一个比较破的方案:

    就是你在 db 里面 预先 “生成, 分配” 一批 id (假设这里你的 全局有序 id 是主键)

    这样就能让服务来`抢` next id, 对 行加锁了,并发应该会好一些,

    就是不能回滚,需要让签名的 id 失效
    jiobanma
        14
    jiobanma  
    OP
       309 天前
    @mineralsalt #2
    @thevita #4
    @CocaCola001 #7 这个比较简单 缺点就是可能会有性能问题已经服务掉线之后的问题
    @luciankaltz #10 目前都是默认的 没有传参,所以你说的 machine id 应该是个默认值,两台服务器应该是一样的值
    @veike #11 uuid 缺点太多了
    nekolr
        15
    nekolr  
       309 天前
    大致上是趋势递增的就可以了呀,或者像楼上几位说的,独立出来一个服务
    dw2693734d
        16
    dw2693734d  
       309 天前
    @jiobanma 能讲讲 uuid 缺点吗
    bugmakerxs
        17
    bugmakerxs  
       309 天前
    https://github.com/Meituan-Dianping/Leaf/blob/master/README_CN.md
    为什么要连续?简单点引入这个就行
    nekolr
        18
    nekolr  
       309 天前
    @nekolr 没注意看楼主要求,楼主想要的是严格的单调递增是吗?如果是用雪花的话,那只能独立出来一个服务
    silentsky
        19
    silentsky  
       309 天前
    很简单的事情 搜 Redisson IdGenerator
    bugmakerxs
        20
    bugmakerxs  
       309 天前
    另外的简单方案是 timestamp + (redis.incr(key) % 100000)
    服务器时钟用 ntp 同步
    tabris17
        21
    tabris17  
       309 天前
    又要严格自增,又要分布式,你这是既要又要啊
    veike
        22
    veike  
       309 天前
    @jiobanma 我说的 ulid ,不是 uuid ,不是一个东西
    ns09005264
        23
    ns09005264  
       309 天前 via Android   ❤️ 5
    把 workid 放到最后试试,比如服务 1 生成序列号 123777701 服务 2 同一时间生成 123777702 ,这样不管从全局来看还是单个服务来看,id 都是连续的
    nekolr
        24
    nekolr  
       309 天前
    @dw2693734d 1 太长 2 可能的安全性问题 3 不是递增的,会导致数据存储不够紧凑,不能充分利用 B+ 树的优势
    Belmode
        25
    Belmode  
       309 天前
    修改一下 workerId ,你这问题不是迎刃而解了
    jiobanma
        26
    jiobanma  
    OP
       309 天前
    @Belmode #25 workId 影响的是中间的某几位,修改没法解决呀
    @bugmakerxs #17 这个我了解下
    crysislinux
        27
    crysislinux  
       309 天前 via Android
    @jiobanma machine id 如果都一样,那还设计这个位干嘛呢。
    opengps
        28
    opengps  
       309 天前   ❤️ 1
    “ id 是递增”天然的设计优势就是自增步长设置为 2 啊,一台 1 作为种子,一台 2 作为种子
    yangyaofei
        29
    yangyaofei  
       309 天前
    给机器分配 ID(0 到 N 的自然数)不就好了, 比如 10 台, 就找个 N=11, 每个机器自己生成的时候乘以 11 加上自己的 ID 就好了, N 可以有个比较大的余量, 虽然很工程但是感觉应该挺好用
    qingshengwen
        30
    qingshengwen  
       309 天前
    没太明白,时间戳是在最前面的,这样一定是可以做到大致递增的,跟 workId 有什么关系呢
    fuis
        31
    fuis  
       309 天前
    为什么需要严格的单调递增?
    icedir
        32
    icedir  
       309 天前
    了解一下美团的 leaf ,解决了这个场景
    cat
        33
    cat  
       309 天前
    或许可以看看这个:
    Sharding & IDs at Instagram
    https://instagram-engineering.com/sharding-ids-at-instagram-1cf5a71e5a5c
    leonshaw
        34
    leonshaw  
       309 天前
    这种需求不管怎么折腾都等效于一个单点
    taevas
        35
    taevas  
       309 天前
    @fuis 可读性呀,不必时间排序,仅通过主键可知时序
    bringyou
        36
    bringyou  
       309 天前   ❤️ 1
    美团开源过分布式 ID 的生成服务,并有写文章介绍,可以参考: https://tech.meituan.com/2019/03/07/open-source-project-leaf.html
    xiaoHuaJia
        37
    xiaoHuaJia  
       309 天前
    uuid 重写加入时间,可以实现是有排序的。目前我们系统的方案就是这个。除了 id 看起没没纯数字那么规整,差一点点性能,其它都是小问题
    yc8332
        38
    yc8332  
       309 天前
    写个服务预先生成好,放 redis 或者自己的服务。然后用的直接取就行了。。
    yaodong0126
        39
    yaodong0126  
       309 天前
    @mineralsalt 我倒是觉得 1L 非常优雅
    PythonYXY
        40
    PythonYXY  
       309 天前
    需要递增就没法采用分布式的方式,无论是 snowflake 还是基于数据库自增 id ,最后肯定还是会有单点问题。
    dddd1919
        41
    dddd1919  
       309 天前
    所有服务连同一个 redis ,使用同一个 key 的 incr 生成 id ,既能自增又分布式
    mineralsalt
        42
    mineralsalt  
       309 天前
    @yaodong0126 #39 多运行一个服务和使用 redis 加锁没有本质区别, 一般后端项目都会引入 redis, 所以几乎是没有额外成本的. 另外我简单说一下多运行一个服务的缺点.
    1. 浪费内存, java 后端项目启动就几百兆
    2. 稳定性降低, 本来他是分布式部署的项目强行被这个单点服务拖累了, 一旦这个服务挂掉, 其他服务都 GG
    3. 开发任务多了, 多维护一个模块, 也要多上线一个实例

    当然这是一个好的解决方案, 但是一个小项目, 我还是秉承着资源最小化的理念, 不要过多的引入服务和模块
    wendellup2018
        43
    wendellup2018  
       309 天前
    @mineralsalt 还是有区别的, 每个项目都引入 redis, 连接数要爆掉了。引入项目可以增加网关控制调用。
    quantal
        44
    quantal  
       309 天前
    直接用 ULID 吧,生成的 id 带时间戳精确到毫秒,毫秒级有序
    luciankaltz
        45
    luciankaltz  
       309 天前   ❤️ 1
    @dddd1919 热点 key 警告(
    IDAEngine
        46
    IDAEngine  
       309 天前
    @jiobanma 那直接用比特币钱包地址生成算法
    jiobanma
        47
    jiobanma  
    OP
       309 天前
    @luciankaltz #45 了解的有点少,想问下热点 key 可能会导致哪些问题
    jiobanma
        48
    jiobanma  
    OP
       309 天前
    @tabris17 #21 “自增” 和 “ 递增” 是有区别的,注意看
    jiobanma
        49
    jiobanma  
    OP
       309 天前
    @qingshengwen #30
    public static Comparable<?> geneSnowFlakeIDByWorkId(String workId) {
    shardingKeyGenerator.getProperties().setProperty("worker.id", workId);
    return shardingKeyGenerator.generateKey();
    }


    public static void main(String[] args) {
    System.out.println(geneSnowFlakeIDByWorkId("100")); // 890660284086501376
    System.out.println(geneSnowFlakeIDByWorkId("200")); // 890660284095299585
    System.out.println(geneSnowFlakeIDByWorkId("100")); // 890660284094889986
    System.out.println(geneSnowFlakeIDByWorkId("200")); // 890660284095299587
    }

    这样是不就理解了
    wangxiaoaer
        50
    wangxiaoaer  
       309 天前 via iPhone
    也没有大佬解释下 1 楼的方案?目前两台雪花算法在高并发下会重复,说明业务并发还是不低的,再加一个专门生成 id 的服务,是不是还是调用雪花服务器?如果这样的话这个服务就会面临瓶颈,服务如果再通过集群搞成分布式,感觉会面临同样的问题啊。
    joesonw
        51
    joesonw  
       309 天前 via iPhone
    通过一个中心服务器拿自增号码段

    https://cloud.tencent.com/developer/article/1352896
    lovelylain
        52
    lovelylain  
       309 天前 via Android
    @jiobanma 自己实现,时间戳放最高位,自增数放中间,workid 放最低位
    hsymlg
        53
    hsymlg  
       309 天前
    单调递增和趋势递增是 2 个概念,1L 其实就是解决方案,再起一个服务专门做 id 生成,另外其他楼说的美团的 leaf ,那个玩意儿的基于号段的和雪花的也是 2 种不同场景,要注意甄别
    IDAEngine
        54
    IDAEngine  
       309 天前
    @wangxiaoaer 他这个两台服务器的 machine id 用的同一个,当然有重复的可能性。
    luciankaltz
        55
    luciankaltz  
       309 天前 via Android
    @jiobanma 想象一下你对一张表的数据行做 10 次 update 。如果是 10 条记录,那么这些操作之间不会有并发锁问题;如果 10 次更新的是一条记录,那么 10 次操作会退化成串行执行

    热点问题会直接导致各种分片或者分布策略失效,大多数情况下直接退化到单机性能(甚至可能影响到其他的操作
    xiangyuecn
        56
    xiangyuecn  
       309 天前   ❤️ 2
    一言难尽
    说不懂吧,又用上了雪花 id 算法
    说懂吧,又不给服务器分配唯一编号🐶
    leonshaw
        57
    leonshaw  
       309 天前
    不知道你业务顺序是怎么定义的?
    两个不相关的客户端几乎同时发送的请求本身就是没有顺序的,网络随便抖一下到服务器的顺序就变了,更不要说还有相对论了。技术上讲,事件先后只有在同一个点比较才有意义,你分 ID 的时候就是要保证和这个顺序一致。比如来自同一个连接的请求在同一个线程处理。
    sampeng
        58
    sampeng  
       309 天前 via iPhone
    lz 始终没解释为啥一定要递增。
    产品需求?只有疯了的产品才关注这个。leader 的需求?那是技术不太行…
    dayudayupao
        59
    dayudayupao  
       309 天前
    @veike 万万不可,会降低 b 树的效率,降低 pagecache 的利用率
    chenluo0429
        60
    chenluo0429  
       309 天前 via Android   ❤️ 1
    1. 给定正确的 workerId ,
    2. 雪花算法中将代表时间的段放在高位
    xrzxrzxrz
        61
    xrzxrzxrz  
       309 天前   ❤️ 1
    跟 23L 说的一样。把 workId 放在 ID 的尾部,时间日期放在前面,这样两个机器生成出来的 id 就是近似连续递增的(当然没法做到绝对递增,要绝对,只能有一个中间服务处理)。例如,{yyyyymmdd} + {workId} + {Hms}。(自己写个雪花算法原理的 id 生成器)
    veike
        62
    veike  
       309 天前 via Android
    @dayudayupao 能见降低多少啊
    Macrow
        63
    Macrow  
       309 天前
    https://github.com/rs/xid
    零配置,可排序

    Features:

    Size: 12 bytes (96 bits), smaller than UUID, larger than snowflake
    Base32 hex encoded by default (20 chars when transported as printable string, still sortable)
    Non configured, you don't need set a unique machine and/or data center id
    K-ordered
    Embedded time with 1 second precision
    Unicity guaranteed for 16,777,216 (24 bits) unique ids per second and per host/process
    Lock-free (i.e.: unlike UUIDv1 and v2)

    Name Binary Size String Size Features
    UUID 16 bytes 36 chars configuration free, not sortable
    shortuuid 16 bytes 22 chars configuration free, not sortable
    Snowflake 8 bytes up to 20 chars needs machine/DC configuration, needs central server, sortable
    MongoID 12 bytes 24 chars configuration free, sortable
    xid 12 bytes 20 chars configuration free, sortable
    iwdmb
        64
    iwdmb  
       309 天前
    如果没有中心化服务的话
    没有这种可以严格递增的方法
    不然 Google 就不用搞原子钟了
    iwdmb
        65
    iwdmb  
       309 天前   ❤️ 1
    如果你能找到这样一个不依赖中心化服务、原子钟 GPS 硬体的方法
    去面试 Google 一定会上
    可以帮他们数据中心节省大量的成本
    iwdmb
        66
    iwdmb  
       309 天前
    美团的 Leaf 只有保证整体趋势递增 不保证严格递增
    UUID 有重复的可能 所以也不是严格递增
    iwdmb
        67
    iwdmb  
       309 天前
    分布式严格递增
    这个问题目前最简单、经济、性能最好的解法就是中心化服务
    信我一把
    mrjnamei
        68
    mrjnamei  
       309 天前
    你服务是分布式的,要求每个服务生成的 id 必须是全局自增,因此必须引入一个新的组件来通信,不然无法得知当前服务器生成的 id 是否是递增的?

    如果需要引入一个组件就比较好办了,高并发情况考虑高可用就行,高并发是指特别高的并发,假设服务 idGen 服务已经满足高可用的前提下,生成自增 id 显然不是问题,不管使用 redis 、还是自身内存都可以。

    你要解决的问题就是高可用。
    cosmic
        69
    cosmic  
       309 天前
    用 etcd cluster 实现一个全局唯一且连续递增的 sequence generator,确保 consistency 和 availability. 然后服务器每次请求获取一个 batch 的 id,然后服务器每次 assign 一个,当一个 batch 用完后,向 sequence generator service 请求下一个 batch
    tangtj
        70
    tangtj  
       309 天前
    雪花算法是有预留,数据中心 id, 机器 id 的位置. 你没改那就需要调整配置.使他们不一样. 这样就不会出现完全一样的.
    JohnChang
        71
    JohnChang  
       309 天前
    V 站到底多少人用这个头像啊?我怀疑是不是都抄我的
    walkerliu
        72
    walkerliu  
       309 天前
    什么业务哇需要这么精确严格的递增吗,snowflakeID 前 41 个 bit 是 timestamp ,都能精确到毫秒了 。我觉得不如倒退需求是否需要那么精确的递增
    conn457567
        73
    conn457567  
       309 天前 via Android
    雪花算法的前提条件就是每个实例的 workerid 不能相同啊,可以用分布式协调中间件 zookeper 给每个实例分唯一 id ,或者简单点用 redis 来实现给每个实例分配唯一 id
    L0L
        74
    L0L  
       309 天前
    高并发的场景下,雪花的递增不太可靠吧?最好说一下一定要递增的业务场景把,看看能不能换个角度解决这个问题?既然上了分布式 ID 了,尽量就避免用其作为业务含义上排序的用途吧,看看是否可以用时间戳之类的。否则 1 楼说的那个需要单独启动一个序列号服务,感觉如果只有两台服务器的话,代价反而有点高,不经济。
    jdOY
        75
    jdOY  
       309 天前
    就两台服务器搞这么复杂,服务器做一下时间同步,改一下生成雪花的几个参数就行了
    ryd994
        76
    ryd994  
       309 天前 via Android
    snowflak 本来就不保证是完全单调递增,而是保证 ID 大体上是单调连续递增,但是允许小规模,短时间的无序
    xuanbg
        77
    xuanbg  
       309 天前
    分布式系统你是很难保证严格按照时间同步递增的,保证单机单调递增就够了。
    franklu
        78
    franklu  
       309 天前
    我想问一下,在分布式下,你们怎么测试确保 id 是不重复的,要是有成熟测试方案,我觉得写代码会更简单。
    franklu
        79
    franklu  
       309 天前
    还是说只能用思维模型测试,只能理论上推理出没问题。
    trzzzz
        80
    trzzzz  
       309 天前 via iPhone
    为啥不用数据库的自增 id 呢
    wxd21020
        81
    wxd21020  
       309 天前
    借楼,请教大佬们,如何生成一个 10-13 位的唯一 id ,目前是通过雪花算法生成 id 后,将 id 顺序调转,然后一直循环除以 10 ,最终的到一个 10-13 位的数字,经过简单的并发测试都能是唯一的,不知道时间长了会不会有不唯一的值。
    msg7086
        82
    msg7086  
       309 天前
    全局层面上做成递增,那势必一台机器要依赖另一台机器产生的 ID ,那就没办法做并发。
    jiobanma
        83
    jiobanma  
    OP
       309 天前
    @xiangyuecn #56 认真审题好吗? 分配唯一编号现在会出现不是递增的。
    jiobanma
        84
    jiobanma  
    OP
       309 天前
    @sampeng #58 append 给出解释了刚才
    jiobanma
        85
    jiobanma  
    OP
       309 天前
    @JohnChang #71 同志你好!
    wqhui
        86
    wqhui  
       309 天前
    @wxd21020 雪花是时间戳+机器唯一标识+序列号,同一节点同一时间戳生成时序列号会递增,同一节点的情况下需要截取时间戳跟序列号才能保证唯一,你这种截取方式并发高点就冲突了
    MonkeyJon
        87
    MonkeyJon  
       309 天前
    @xrzxrzxrz #61 我们系统订单 id 跟你这个实现类似
    knightgao2
        88
    knightgao2  
       309 天前
    雪花算法多台机器也可以递增呀,只要机器的时钟对的就行
    zpf124
        89
    zpf124  
       309 天前
    非要保证递增,那就只能使用锁或者单独的 id 生成服务,以并发的代价来保证 id 生成同一时间唯一。
    lmmlwen
        90
    lmmlwen  
       309 天前
    你们业务并发多大啊?
    KickAssTonight
        91
    KickAssTonight  
       309 天前
    两个机器时钟不一致,那应该必然会出现不递增的情况吧
    leonshaw
        92
    leonshaw  
       309 天前
    问题的核心就是为什么需要递增,被你一句话带过去了?
    vanityfairn
        93
    vanityfairn  
       309 天前
    专门的服务批量生成 ID ,最通行,最常用
    zhh0000zhh
        94
    zhh0000zhh  
       309 天前
    有一次面阿里的时候面试题就是要求实现分布式单调递增主键生成,必须没有仲裁来实现,我不会,被阿里面试官鄙视了,最后我问他,他没告我咋弄。
    mark 一下看看有没有人能搞出来,我至今觉得面试官实际上是个糊涂蛋
    xiangyuecn
        95
    xiangyuecn  
       309 天前
    @jiobanma #84 我在#56 讲的是“ id 是重复的”这个问题

    只要你单个节点里面,时间不倒流,雪花算法是不可能产生重复 id 的,每个节点都要有唯一编号,最多 1024 个节点,这个是保证全局不重复的基础。

    雪花算法的时间精度是 1 毫秒,单个节点 1 毫秒内最多产生 4096 个 id (会加锁串行生成),单节点只要 1 毫秒内超过了 4096 个就会 sleep 等待下 1 毫秒再分配 id ,你开了 2 个节点,那就 1 毫秒能产生 4096*2=8192 个 id ,1 毫秒里面这些 id 只能通过节点 id 来区分保证不重复

    单个节点内生成的 id 因为是串行生成的因此是完全有序的,但同 1 毫秒内多个服务器生成的 id 就不能保证有序了,1 秒内看这 1000 毫秒生成的 id 又是有序的,这叫时间上粗略有序

    “id 碰撞” “重复” 每个节点分配了唯一编号,只要你不乱改服务器时间时间怎么可能出现这种情况
    gundam0603
        96
    gundam0603  
       309 天前
    雪花的 id 本来就不是连续的啊 ,按理说改下 workId 就行
    Aresxue
        97
    Aresxue  
       309 天前
    1.改下算法把 workId 放到 id 尾部(不依赖外部服务和中间件);
    2.使用 redis 自增序列(大多数项目已经引入 redis ,只有代码改造成本);
    3.号段 使用序列表按照 size 取号段到内存(更稳健的模式但改造成本大,且只有趋势递增失去了单调递增性);
    4.引入新服务(对原有服务耦合小,新增永远比修改更安全,但维护成本拉满);
    5.使用数据库代理层中间件(如果已经有了算是性价比最高的方案,不然就没有操作意义);

    顺便一提如果集群大了时钟同步是个麻烦的事情,基本上总是会有时钟回拨,对雪花算法有一定的影响,但本身也有一定措施缓解这个情况,如使用缓存的 id 等,还是要早做考虑。
    cheng6563
        98
    cheng6563  
       309 天前
    没得治,找个单独的组件生成 ID ,并且还得牺牲可用性。
    iamfenges
        99
    iamfenges  
       309 天前
    workId 放 id 的最后面会有什么问题吗
    daye
        100
    daye  
       309 天前
    把大家的回复都看了,提供一个新思路给 OP ,可以通过雪花算法 + Redis 的 increment 命令来实现,能保证在两台服务器生成的 ID 不重复、绝对的递增,那么 ID 里的时间戳值就不是真实的生成时间(雪花 id 优点之一)

    基本原理是:
    1. 判断 Redis 的 ID_KEY 是否存在,若不存在,则加分布式锁通过雪花算法生成 ID 设值
    2. 对 ID_KEY 进行 increment 命令获取递增后的值作为 ID
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5120 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 48ms · UTC 06:59 · PVG 14:59 · LAX 23:59 · JFK 02:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.