分布式 ID
分布式 ID 完整选型 落地方案生产可用分场景直接选一、主流 5 种方案优缺点总览1. UUID / UUID36优点本地生成无 RPC、简单缺点无序、太长 36 位、数据库索引差、泄露 MAC 地址旧版适用简单日志、临时业务 ID严禁做主键2. 数据库自增主键单库优点连续有序、稳定、最简单缺点单点瓶颈分库分表完全不能用适用单体小型系统3. 数据库号段模式Leaf、百度 UidGenerator原理业务一次性批量拿一段 ID 缓存本地用完再去 DB 申请下一号段优点有序、性能极高、稳定、可持久化、故障不重复缺点需要单独一张号段表轻微开发量适用绝大多数企业业务、订单、财务、主业务主键最稳妥通用选型4. Redis INCR / 号段优点性能爆炸原子自增缺点宕机丢未持久化增量、依赖 Redis 集群稳定性适用高并发秒杀、临时流水号5. Snowflake 雪花算法Twitter64bit 结构时间戳 (41) 机器 ID (10) 序列号 (12)优点全局有序、纯本地生成、不依赖第三方、64 位 long 型缺点时钟回拨致命问题、机器 ID 要手动分配维护适用高并发互联网业务、海量数据场景必须解决时钟回拨6. 美团 Leaf同时支持雪花 号段企业级成熟开源框架直接拿来用业界落地最多。二、明确选型决策表直接对照业务选场景 1传统 ERP/MES/ 财务 / 支付、要求绝对不重复、数据稳妥✅优先Leaf 号段模式强一致性、无时钟问题、运维简单、数据库可溯源分库分表天然支持场景 2超高并发、百万 QPS、海量流水、不在乎短暂时钟风险✅Snowflake自研 / Leaf 雪花模式必须配套时钟监控、回拨拒绝策略、机器 ID 注册中心场景 3简单临时 ID、内部埋点、非主键✅ UUID / 简单雪花场景 4秒杀短时效流水号✅ Redis 自增三、雪花算法详细落地关键点避坑核心64 位标准结构1bit 符号位 | 41bit 毫秒时间戳 | 10bit 机器 ID | 12bit 序列号机器 ID 10bit最多 1024 台机器序列号 12bit每毫秒单节点最多 4096 个 ID三大致命坑 解决方案时钟回拨最严重现象服务器 NTP 同步回拨生成重复 ID解决本机记录上一次生成时间当前时间 上次时间 → 直接抛出异常 / 自旋等待Leaf 雪花自带时间回拨补偿禁止虚拟机时间漂移机器 ID 重复方案启动注册到 Zookeeper/Redis自动分配唯一机器号物理机用 IP 最后 10 位、容器用 K8s pod 固定标识单机毫秒内 4096 序列号耗尽自旋等到下一毫秒即可四、号段模式落地架构强烈推荐制造业 / 企业系统1. 单独号段数据表CREATE TABLE id_segment ( business_tag VARCHAR(50) PRIMARY KEY COMMENT 业务标识:order,receivable, max_id BIGINT NOT NULL COMMENT 当前已分配最大号, step INT NOT NULL COMMENT 每次申请步长, update_time DATETIME );示例初始化一条ordermax_id10000step10002. 运行逻辑服务启动拉取一段10001~11000 缓存在内存业务直接内存取号无 DB 请求内存剩余 10% 阈值异步去 DB 抢占下一段号段CAS 更新 max_id数据库只有简单 UPDATEupdate id_segment set max_id max_id step where business_tag ?原子更新绝对不会重复3. 优势DB 宕机内存号段还能继续支撑很久完全没有时钟问题金融财务零风险有序数字 IDMySQL 主键索引性能拉满五、开源成熟框架直接落地不用重复造轮子美团 Leaf首选两种模式自由切换Segment 号段 Snowflake 支持监控、号段自动扩容、雪花时钟回拨处理、RPC 接入简单百度 UidGenerator基于雪花借助 Redis 解决机器 ID 与时钟滴滴 TinyId纯号段方案轻量六、Java 生产极简落地建议企业内部管理系统、MES、WMS、财务单据采用Leaf Segment 号段高并发 C 端业务、千万级订单采用Leaf Snowflake 模式开启时钟回拨保护禁止自己手写简易雪花时钟回拨一定会踩坑七、分库分表配套规则雪花 ID取 ID 取模分片号段 ID同样取模全局连续完全兼容分片三套完整可直接投产代码自研号段工具类 安全雪花算法 SpringBoot 接入美团 Leaf一、自研数据库号段分布式 ID企业 ERP/MES/ 财务最稳1、号段数据表CREATE TABLE id_segment ( business_tag varchar(50) NOT NULL COMMENT 业务标识order、receivable、work_order, max_id bigint NOT NULL DEFAULT 0 COMMENT 已分配最大ID, step int NOT NULL DEFAULT 1000 COMMENT 每次申请号段长度, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (business_tag) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT分布式号段表; -- 初始化测试数据 INSERT INTO id_segment(business_tag,max_id,step) VALUES (order,10000,2000);2、MyBatis MapperMapper public interface IdSegmentMapper { Update(UPDATE id_segment SET max_id max_id step WHERE business_tag #{tag}) int increaseSegment(Param(tag) String tag); Select(SELECT max_id,step FROM id_segment WHERE business_tag #{tag}) IdSegment selectByTag(Param(tag) String tag); } Data public class IdSegment { private Long maxId; private Integer step; }3、号段生成器核心工具类import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.Map; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicLong; Component public class SegmentIdGenerator { Resource private IdSegmentMapper idSegmentMapper; // 本地缓存号段 private final MapString, SegmentBuffer bufferMap new ConcurrentHashMap(); // 异步预加载线程池 private final ExecutorService pool Executors.newSingleThreadExecutor(); private static class SegmentBuffer { // 当前号段起始、截止、当前取值 AtomicLong current; long end; int step; volatile boolean isLoading; } public Long nextId(String businessTag) { SegmentBuffer buffer bufferMap.computeIfAbsent(businessTag, k - initBuffer(k)); long id buffer.current.getAndIncrement(); // 剩余10%阈值异步拉取下一号段 if (id buffer.end - buffer.step * 0.1 !buffer.isLoading) { loadNextAsync(buffer, businessTag); } if (id buffer.end) { synchronized (buffer) { while (id buffer.end) { try { buffer.wait(); } catch (InterruptedException e) { throw new RuntimeException(获取号段超时); } } id buffer.current.getAndIncrement(); } } return id; } private SegmentBuffer initBuffer(String tag) { IdSegment seg idSegmentMapper.selectByTag(tag); SegmentBuffer buf new SegmentBuffer(); buf.step seg.getStep(); buf.end seg.getMaxId(); buf.current new AtomicLong(buf.end - buf.step 1); return buf; } private void loadNextAsync(SegmentBuffer buffer, String tag) { if (!buffer.isLoading) { buffer.isLoading true; pool.submit(() - { try { // CAS原子递增 idSegmentMapper.increaseSegment(tag); IdSegment newSeg idSegmentMapper.selectByTag(tag); synchronized (buffer) { buffer.end newSeg.getMaxId(); buffer.current.set(buffer.end - buffer.step 1); buffer.notifyAll(); } } finally { buffer.isLoading false; } }); } } }使用Autowired private SegmentIdGenerator segmentIdGenerator; Long orderId segmentIdGenerator.nextId(order);二、自带时钟回拨防护的雪花算法可直接上线public class SafeSnowflakeIdGenerator { // 64位划分 private static final long TIME_BIT 41L; private static final long WORKER_BIT 10L; private static final long SEQ_BIT 12L; private static final long MAX_WORKER_ID (1L WORKER_BIT) - 1; private static final long MAX_SEQ (1L SEQ_BIT) - 1; private static final long WORKER_SHIFT SEQ_BIT; private static final long TIME_SHIFT SEQ_BIT WORKER_BIT; // 基准时间2025-01-01 private static final long EPOCH 1735689600000L; private final long workerId; private long lastTime 0L; private long sequence 0L; public SafeSnowflakeIdGenerator(long workerId) { if (workerId 0 || workerId MAX_WORKER_ID) { throw new IllegalArgumentException(机器ID超出0~1023); } this.workerId workerId; } public synchronized long nextId() { long now System.currentTimeMillis(); // 时钟回拨 if (now lastTime) { long offset lastTime - now; // 回拨小于50ms自旋等待超过直接抛异常拒绝生成 if (offset 50) { try { Thread.sleep(offset); now System.currentTimeMillis(); } catch (InterruptedException e) { throw new RuntimeException(时钟回拨生成ID失败); } } else { throw new RuntimeException(严重时钟回拨禁止生成ID); } } // 同一毫秒自增序列号 if (now lastTime) { sequence (sequence 1) MAX_SEQ; if (sequence 0) { // 序列号用尽等到下一毫秒 while (now lastTime) { now System.currentTimeMillis(); } } } else { sequence 0; } lastTime now; return ((now - EPOCH) TIME_SHIFT) | (workerId WORKER_SHIFT) | sequence; } }机器 ID 分配方案物理机IP最后两段取模1024K8s 容器注册到 Redis/ZK 自动分配唯一 workerId三、SpringBoot 接入美团 Leaf 完整配置生产首选1、架构选择同时部署Segment 号段做主业务 IDSnowflake 做高并发流水 ID2、application.ymlleaf: segment: enable: true url: jdbc:mysql://localhost:3306/leaf_db?useUnicodetrue username: root password: xxx snowflake: enable: true # 使用ZK自动分配workerId杜绝重复 zk-address: 127.0.0.1:21813、依赖 Mavendependency groupIdcom.sankuai.inf.leaf/groupId artifactIdleaf-core/artifactId version1.0.4/version /dependency4、注入使用Autowired private SegmentIDGenImpl segmentIDGen; Autowired private SnowflakeIDGenImpl snowflakeIDGen; // 号段ID订单、财务单据 Long orderId segmentIDGen.get(order).getId(); // 雪花ID高并发流水 Long flowId snowflakeIDGen.get(flow).getId();四、三种方案选型极简总结MES/WMS/ 财务 / ERP 单据、要求绝对稳定无时钟风险→ 自研号段 / Leaf Segment高并发千万级 C 端订单、海量数据→ 安全雪花 / Leaf 雪花小型单体项目→ 简单雪花即可

相关新闻

Belt工具库在实际项目中的应用案例分享

Belt工具库在实际项目中的应用案例分享

Belt工具库在实际项目中的应用案例分享 【免费下载链接】belt A handful of tools for PHP developers. 项目地址: https://gitcode.com/gh_mirrors/be/belt Belt工具库是一款专为PHP开发者打造的实用工具集,提供了丰富的数组操作、集合处理等功能&#xff0…

2026/10/7 3:40:54 阅读更多 →
Node API for .NET完全指南:如何在JavaScript中无缝调用.NET API

Node API for .NET完全指南:如何在JavaScript中无缝调用.NET API

Node API for .NET完全指南:如何在JavaScript中无缝调用.NET API 【免费下载链接】node-api-dotnet Advanced interoperability between .NET and JavaScript in the same process. 项目地址: https://gitcode.com/gh_mirrors/no/node-api-dotnet Node API f…

2026/10/6 4:47:55 阅读更多 →
OpenClaw小龙虾部署教程,本地与云端全平台方案

OpenClaw小龙虾部署教程,本地与云端全平台方案

一、本地部署:手把手教你搭建“小龙虾”厨房 夏天到了,谁能拒绝一盘麻辣鲜香的小龙虾?可你知道吗,在程序员的世界里,也有一道名为“OpenClaw小龙虾”的硬菜——它不是什么网红美食,而是一套开源的网络爬虫部…

2026/10/9 7:30:33 阅读更多 →

最新新闻

JavaScript sort排序原理与常见陷阱解析

JavaScript sort排序原理与常见陷阱解析

先说个我自己的真实经历。有次帮同事排查一个列表排序问题,数据是几组数字,他写了 arr.sort() ,结果排出来是 [1, 10, 2, 22, 3] 这种完全看不懂的顺序。他盯着屏幕看了半天,第一反应是"sort排序坏了"。其实不是坏了…

2026/10/14 18:21:46 阅读更多 →
MATLAB动态仿真牛顿环:从光程差公式到GIF动图实现

MATLAB动态仿真牛顿环:从光程差公式到GIF动图实现

简介:基于MATLAB开发的牛顿环动态光学仿真资源,面向光电信息科学与工程专业本科生、高校教师及光学实验研究者,涉及等厚干涉、光程差等核心概念,用于直观理解厚度变化对干涉条纹的影响。资源仅4个文件,包含可自定义参数…

2026/10/14 18:21:46 阅读更多 →
刚注册完不会核销?卡点在建店和授权:商户 → 门店 shopId → 美团/抖音授权

刚注册完不会核销?卡点在建店和授权:商户 → 门店 shopId → 美团/抖音授权

核销服务由无限聚核提供,美团、抖音团购核销一站式接入。账号注册好了,开发者中心也能看到 API Key,一点核销却报「门店不存在」「未授权」——现场最常见的不是接口写错,而是还没建具体门店,或者建了商户却拿商户 ID …

2026/10/14 18:21:46 阅读更多 →
AI视频生成时间一致性难题:从DiT架构到VAE的时空建模与后处理全解析

AI视频生成时间一致性难题:从DiT架构到VAE的时空建模与后处理全解析

1. AI视频生成的核心痛点:为什么时间一致性这么难1.1 从单帧到连续画面,问题出在哪做AI视频生成的人都有一个共同体会:单张图看着挺惊艳,一连起来就露馅。人物的脸在第三帧还是张三,到第八帧就变成了李四;衣…

2026/10/14 18:21:46 阅读更多 →
具身智能的底层逻辑:实时音视频与VLA模型如何驱动机器人

具身智能的底层逻辑:实时音视频与VLA模型如何驱动机器人

1. 从一句提问说起:人形机器人真的是具身智能的终点吗前阵子在一个技术交流群里,有人抛出一个问题:“人形机器人是不是具身智能的终极形态?”底下吵成一片。做机械臂的说不一定,做四足的说人形只是其中一种载体&#x…

2026/10/14 18:21:46 阅读更多 →
快速阅读不靠眼快:筛选与理解的实用框架

快速阅读不靠眼快:筛选与理解的实用框架

经常有人问我:“你读书怎么那么快?是不是一目十行、走马观花?”说实话,我刚开始试水快速阅读的时候也踩过不少坑,最典型的表现是字都看完了,合上书一问三不知。后来我花了很长时间去拆解“快速阅读”和“快…

2026/10/14 18:20:44 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →