雪花算法遇上时钟回拨,我们布了三道防线

举报
yd_264617019 发表于 2026/10/29 09:45:05 2026/10/29
【摘要】 雪花ID的结构:64位等于1位符号加41位毫秒时间戳加10位机器位加12位序列,单机每毫秒4096个,够绝大多数场景。它的命门是强依赖时钟单调——NTP校时把时钟拨回几十毫秒,同一毫秒内序列重用,ID就撞了。生产上真遇过:虚拟机宿主机时间漂移,NTP一次回拨37ms,上游开始报主键冲突。处理代码的三道防线:longnow=System.currentTimeMillis();if(now&l...

雪花 ID 的结构:64 位等于 1 位符号加 41 位毫秒时间戳加 10 位机器位加 12 位序列,单机每毫秒 4096 个,够绝大多数场景。它的命门是强依赖时钟单调——NTP 校时把时钟拨回几十毫秒,同一毫秒内序列重用,ID 就撞了。

生产上真遇过:虚拟机宿主机时间漂移,NTP 一次回拨 37ms,上游开始报主键冲突。处理代码的三道防线:

long now = System.currentTimeMillis();
if (now < lastTimestamp) {
    long offset = lastTimestamp - now;
    if (offset <= 5) {
        // 小回拨:自旋等待时钟追上
        LockSupport.parkNanos(offset * 100_000L);
        now = System.currentTimeMillis();
    } else {
        // 大回拨:拒服务并告警,人工介入
        throw new ClockBackwardsException(
            "offset=" + offset + "ms");
    }
}

第一道,回拨小于 5ms 自旋等待;第二道,大于 5ms 拒绝发号并告警,宁可短暂不可用也不发重复 ID;第三道在部署层:机器统一用 chrony 做平滑校时(slew 渐进模式,禁止 step 跳变),从源头减少回拨。

彻底不依赖时钟的替代方案也评估过:号段模式(美团 Leaf-segment,DB 批量发号)吞吐低一档但与时间解耦;Redis 自增简单但有持久化窗口的重复风险。我们的定版是核心交易用雪花加三道防线,边缘业务用号段,各自安心。发号器这种基础组件,出问题的瞬间影响面是全业务,防线宁多勿少。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。