雪花、号段、Leaf 三种分布式 ID:我们日增 2 亿数据的表,最终换掉了雪花
三年前我们的订单 ID 用的是雪花算法Snowflake跑了两年一直没问题。直到业务量冲到日增 2 亿条机器扩容、容器频繁重建时钟回拨开始密集出现订单 ID 出现重复对账直接崩了。那次之后我们系统性对比了雪花、号段、Leaf 三种方案最后切到了 Leaf-segment。这篇把三种方案的原理、代码、各自的坑讲清楚并附上我们选型时的真实数据。为什么不能用数据库自增先说为什么需要分布式 ID分库分表后单库自增 ID 会撞车两个库都从 1 开始而且自增暴露了业务量竞争对手能靠订单号猜你一天卖多少。分布式 ID 一般要求全局唯一、趋势递增BTree 索引友好、高性能、最好带时间信息。// 不推荐分库分表后自增 ID 直接撞车 TableId(type IdType.AUTO) // 1. 单库自增分到库2又从1开始 private Long id; // 库1 插入 id1库2 也插入 id1 - 主键冲突或跨库乱序逐行第 1 行IdType.AUTO依赖数据库自增分库后每个库各自计数库间必然重复且无法跨库排序。所以必须上分布式 ID 生成器下面三种是主流。雪花算法64 位里塞进时间、机器、序号雪花把 64 位 long 拆成1 位符号恒 0 41 位时间戳 10 位机器 ID 12 位序列号。同一毫秒内靠序列号区分不同毫秒靠时间戳递增。// 雪花算法核心简化版便于理解 public synchronized long nextId() { long timestamp System.currentTimeMillis(); // 1. 当前毫秒 if (timestamp lastTimestamp) { // 2. 时钟回拨 - 直接抛异常 throw new RuntimeException(时钟回拨拒绝生成); } if (timestamp lastTimestamp) { sequence (sequence 1) 4095; // 3. 同一毫秒序列号112位上限4095 if (sequence 0) { // 4. 本毫秒用尽等下一毫秒 timestamp waitNextMillis(lastTimestamp); } } else { sequence 0; // 5. 新毫秒序列号归零 } lastTimestamp timestamp; return ((timestamp - EPOCH) 22) // 6. 时间戳左移22位1012 | (workerId 12) // 7. 机器ID左移12位 | sequence; // 8. 拼上序列号 }逐行第 2 行处理时钟回拨——这是雪花最大的雷下面专门讲第 3 行同一毫秒内序列号递增最多 4096 个/毫秒第 6-8 行把三段按位拼成 64 位 long。单机能做到约 400 万 ID/秒4096 × 1000性能足够。但它依赖机器时钟单调而时钟回拨在容器化环境里太常见了。我们那天翻车的具体场景K8s 节点重启后NTP 把系统时间往回拨了 3 秒多个 Pod 的 workerId 又因为配置失误重复结果生成了和 3 秒前完全相同的 ID两笔订单主键冲突下游对账直接报错停服。时钟回拨 workerId 重复是雪花的两大杀手。号段模式一次取一段本地慢慢发号段模式segment的思路是不在每次生成时访问 DB而是从 DB 一次性申请一段区间比如 [1, 1000]在本地内存里挨个发发完了再去 DB 取下一段。DB 压力从每次一条降到每 1000 条一次。// 号段模式核心逻辑简化 class Segment { private long cur; // 1. 当前已发到哪 private long max; // 2. 本段上限从 DB 申请的 maxId private long step 1000; // 3. 每次申请 1000 个 } public synchronized long nextId() { if (cur max) { // 4. 本段用尽去 DB 取下一段 // UPDATE id_segment SET max_id max_id step WHERE biz order // 拿到新区间 [oldMax, newMax] cur dbOldMax 1; max dbNewMax; } return cur; // 5. 本地自增返回无 DB 交互 }逐行第 4 行号段用尽才去 DB 申请下一段平时nextId()只是内存自增性能极高、不依赖时钟第 5 行返回并自增。号段的优势是不怕时钟回拨ID 来自 DB 自增区间缺点是一旦 DB 挂了、当前段又正好发完就生成不了——可用性受 DB 约束。另外号段有号浪费服务重启没发完的号段就丢了但这是可接受的代价。Leaf把两种方案都做成服务美团开源的 Leaf 把上面两种做成可切换的服务。我们用的是Leaf-segment它在号段基础上加了双 buffer——当前段用到一定比例比如 10%就异步去预取下一个段避免段用尽才去 DB那一下卡顿。// Leaf-segment 双 buffer逻辑还原 class SegmentBuffer { Segment[] segments new Segment[2]; // 1. 两段缓冲 int currentPos 0; // 2. 当前在用哪段 boolean nextReady false; // 3. 下一段是否已预取好 } public long nextId() { Segment cur segments[currentPos]; if (cur.cur cur.max) { // 4. 当前段用完切到下一段 if (nextReady) { // 5. 下一段已就绪直接切换 currentPos ^ 1; nextReady false; asyncLoadNext(); // 6. 异步预取下下一段 } else { Thread.sleep(1); // 7. 还没就绪短暂等待极少触发 } } return segments[currentPos].nextId(); }逐行第 3 行nextReady标记下一段是否备好第 5 行当前段用尽且下一段已就绪就无缝切换第 6 行切换后立刻异步去取新的下一段保证永远有一段在内存候着。这把号段的段用尽卡顿彻底抹平了。我们压测时单实例 Leaf-segment 轻松到 5 万 ID/秒且 DB 每秒只被访问几次。Leaf 还提供Leaf-snowflake用 ZooKeeper/雪花 workerId 分配 时钟回拨时的借号策略缓解雪花痛点回拨一小段时间内用扩展位发号、记录回拨时长告警。但 workerId 仍需外部协调我们没选它。三种方案横向对比维度雪花 Snowflake号段 SegmentLeaf-segment趋势递增是按毫秒是是依赖时钟强依赖回拨致命不依赖不依赖性能极高纯本地极高本地偶尔DB极高双 buffer 平滑可用性依赖仅需本地时钟依赖 DB 段未耗尽依赖 DB 段未耗尽部署复杂度低嵌应用中需 DB 表中高独立服务 DB主要风险时钟回拨、workerId 冲突DB 挂段耗尽、号浪费DB 挂段耗尽、号浪费一句话雪花最轻量但最怕时钟回拨号段/Leaf 不怕时钟但依赖 DB 且不轻量。如果你的机器时钟可信、部署稳定雪花够用一旦上容器、频繁扩缩容雪花的风险会非线性放大。我的取舍日增 2 亿我们选 Leaf-segment我的观点很直接容器化、高并发、对 ID 重复零容忍的业务别用裸雪花。我们当初坚持用雪花是嫌 Leaf 要起服务、多一个依赖结果时钟回拨那次停服 2 小时损失比多运维一个 Leaf 服务大得多。切到 Leaf-segment 后我们做了三件事独立部署 Leaf 集群至少 2 个节点 DB 主从ID 生成不再和业务的容器生命周期绑定容器重建不影响发号DB 段表单独库不和业务库混避免业务库抖动拖垮发号监控号段消耗速率在段快耗尽前告警杜绝段耗尽 DB 抖动双重打击。如果业务量小、部署简单、机器时钟稳定物理机、有 NTP 防护我仍然推荐雪花——它零依赖、性能好、调试直观。但凡上云、上容器、日增量过千万我建议直接上 Leaf-segment把时钟风险从根上移出 ID 生成链路。补充一句Leaf-segment 的段步长step也别拍脑袋步长太小 DB 访问频繁太大重启丢号多。我们按单节点峰值 QPS × 60 秒估算线上 step 设为 50 万DB 每分钟才被访问一次单节点重启最多浪费 50 万号在日增 2 亿的量级下完全可接受。另外 Leaf 的 DB 段表建议用独立的 biz_tag 区分不同业务线避免一个业务把段用爆影响其他业务的发号。思考题假设你的 workerId 用IP 后 10 位取模 1024生成容器重启后 IP 变了导致 workerId 和上一次重复同时发生时钟回拨。这时雪花算法会分别触发什么问题如果用 Leaf-segment这两类问题还存在吗写在最后雪花、号段、Leaf 不是谁更好是适用面不同。雪花轻量但怕时钟回拨和 workerId 冲突号段/Leaf 用内存发号 DB 批量取段绕开时钟问题代价是多一个服务依赖。我们日增 2 亿的表最终选 Leaf-segment是因为容器化让雪花的风险变得不可控。选 ID 方案先问自己我的部署环境时钟可信吗ID 重复我能承受吗答案决定选型而不是哪个听起来更先进。

相关新闻

HunterPie终极指南:3分钟打造你的《怪物猎人:世界》智能狩猎助手

HunterPie终极指南:3分钟打造你的《怪物猎人:世界》智能狩猎助手

HunterPie终极指南:3分钟打造你的《怪物猎人:世界》智能狩猎助手 【免费下载链接】HunterPie-legacy A complete, modern and clean overlay with Discord Rich Presence integration for Monster Hunter: World. 项目地址: https://gitcode.com/gh_mi…

2026/7/29 15:38:21 阅读更多 →
Arduino传感器扩展板设计:解决多传感器接口、供电与信号调理难题

Arduino传感器扩展板设计:解决多传感器接口、供电与信号调理难题

1. 项目概述:一块“万能钥匙”的诞生 最近在整理工作室的传感器盒子,看着里面堆得满满当当的DFrobot、Seeed Studio以及其他各种品牌的传感器模块,接线、供电、电平匹配这些琐事总是让人头疼。特别是当你想快速验证一个想法,或者带…

2026/7/30 16:21:56 阅读更多 →
3大技术创新解析:ClearerVoice-Studio如何重塑语音处理技术栈

3大技术创新解析:ClearerVoice-Studio如何重塑语音处理技术栈

3大技术创新解析:ClearerVoice-Studio如何重塑语音处理技术栈 【免费下载链接】ClearerVoice-Studio An AI-Powered Speech Processing Toolkit and Open Source SOTA Pretrained Models, Supporting Speech Enhancement, Separation, and Target Speaker Extractio…

2026/7/29 15:37:21 阅读更多 →

最新新闻

告别抢票焦虑:DamaiHelper全能抢票王帮你轻松搞定热门演出门票

告别抢票焦虑:DamaiHelper全能抢票王帮你轻松搞定热门演出门票

告别抢票焦虑:DamaiHelper全能抢票王帮你轻松搞定热门演出门票 【免费下载链接】damaihelper 支持大麦网,淘票票、缤玩岛等多个平台,演唱会演出抢票脚本 项目地址: https://gitcode.com/gh_mirrors/dam/damaihelper 还在为抢不到演唱会…

2026/7/30 16:26:07 阅读更多 →
科研与科技成果分类全解析:从论文专利到产业化应用

科研与科技成果分类全解析:从论文专利到产业化应用

1. 科研与科技成果的“家谱”:从实验室到应用的全景图 干了这么多年科研,也参与过不少成果转化和项目评审,我发现一个挺有意思的现象:很多刚入行的研究生,甚至一些工作了几年的科研人员,对“科技成果”的理…

2026/7/30 16:26:07 阅读更多 →
Scrapy+Redis构建亿级分布式爬虫架构实战

Scrapy+Redis构建亿级分布式爬虫架构实战

1. 项目概述:构建企业级分布式爬虫的核心要素 在大规模数据采集场景中,传统单机爬虫面临着性能瓶颈和可靠性问题。我经历过多个日采集量超过千万级的项目后,发现基于ScrapyRedis的分布式架构是性价比最高的解决方案之一。这种架构的核心在于将…

2026/7/30 16:26:07 阅读更多 →
机器人电控系统硬件设计:从输入保护到稳压的电路实战指南

机器人电控系统硬件设计:从输入保护到稳压的电路实战指南

1. 项目概述:从零搭建一个“抗造”的机器人电控系统 搞机器人,无论是参加RoboMaster、Robocon这类大赛,还是自己做一台智能小车或机械臂,最让人头疼的往往不是算法写不出来,而是硬件系统“抽风”。程序跑得好好的&…

2026/7/30 16:26:07 阅读更多 →
AI文本降重工具原理与应用实践

AI文本降重工具原理与应用实践

1. 项目概述:千笔降AI率助手的核心价值最近在内容创作圈子里,有个工具被频繁提及——千笔降AI率助手。作为每天需要处理大量文字内容的从业者,我最初也是抱着试试看的心态接触这个工具,没想到它彻底改变了我处理AI生成内容的工作流…

2026/7/30 16:26:06 阅读更多 →
接单做训练反馈APP,我算了三笔账

接单做训练反馈APP,我算了三笔账

这单适不适合用 AI 生成 APP,我用三笔账判断:原型账、返工账、上线账。算完以后,我没有全手写,也没把交付完全交给生成工具,而是把可重复的页面先跑出来,复杂数据留给自己收口。 客户是一个只有 4 名教练的…

2026/7/30 16:25:06 阅读更多 →

日新闻

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 您是否曾因Windows系统盘空间不足而烦恼?是否遇到过设…

2026/7/30 0:00:13 阅读更多 →
如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 你是否曾经在浏览…

2026/7/30 0:00:13 阅读更多 →
“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

更多请点击: https://intelliparadigm.com 第一章:AI 教师备课辅助 AI 教师备课辅助系统正逐步成为教育数字化转型的核心支撑工具,它并非替代教师,而是通过语义理解、知识图谱与多模态生成能力,将教师从重复性劳动中解…

2026/7/30 0:00:13 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/29 22:18:20 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/29 15:00:03 阅读更多 →

月新闻