分布式 ID 生成方案从数据库自增到雪花算法目录自增 ID 的局限UUID数据库号段Redis INCR雪花算法时钟回拨方案对比小结自增 ID 的局限在很多系统刚开始建设的时候ID 并不是一个需要特别关注的问题。创建一张表设置一个自增主键数据库负责保证每条数据都有唯一编号这种方式简单、稳定而且几乎没有额外成本。但随着业务规模扩大系统从单体逐渐演变成多实例部署甚至开始进行分库分表后原本简单的自增 ID 就遇到了问题多个服务节点如何保证生成的 ID 仍然全局唯一单库场景下所有数据写入都经过同一个数据库自增序列天然是连续且唯一的。但到了分布式环境每个数据库节点都有自己的自增序列它们并不知道其他节点已经生成了哪些 ID。例如数据库A用户表分片1 数据库B用户表分片2 id1 张三 id1 李四 id2 王五 id2 赵六对于数据库 A 来说ID1 是合法的对于数据库 B 来说ID1 同样也是合法的。但放到整个系统来看两个 ID 已经发生冲突。有人可能会想到提前给不同节点划分 ID 范围比如让 A 使用奇数B 使用偶数或者给每个数据库设置不同的起始值和增长步长。但这种方式随着节点数量变化会越来越难维护。新增机器、数据迁移、业务扩容都可能导致原有规则失效。因此在分布式系统中ID 的生成不能再依赖某一个数据库实例的自增能力而需要设计一套独立的 ID 生成机制让不同节点在没有互相协调的情况下也能生成全局唯一的编号。UUIDUUID 最大的优点是简单。应用节点之间不需要协调本地直接生成就能用StringidUUID.randomUUID().toString();// 550e8400-e29b-41d4-a716-446655440000零依赖、无网络开销、理论上不会重复。但简单也意味着牺牲了一些数据库场景下比较重要的特性。做数据库主键性能差。InnoDB 的主键索引本质是一棵 B 树数据通常按照主键顺序插入。ID 不断递增时新数据基本追加到索引尾部而随机 UUID 会让数据插入位置更加分散增加 B 树页分裂和索引维护成本。加上 UUID 是 36 个字符的字符串比 8 字节的 Long 整数大好几倍索引占用空间也更大。可读性差。出了问题排查时user_id1001比user_id550e8400-e29b-41d4-a716-446655440000好认得多。UUID 适合做请求追踪 ID、日志关联 ID 这类不需要排序、不做主键的场景。拿来做数据库主键代价不小。数据库号段一种自然的思路是引入一个专门的 ID 服务由它统一分配编号。但如果每次生成 ID 都访问数据库本质上只是把压力从业务表转移到了发号表。号段模式解决的就是这个问题一次取一批用完了再取下一批。数据库只在号段用完时才被访问一次平时 ID 生成全在内存里完成。实际实现中通常用两个号段交替当前号段快用完时提前加载下一个号段避免用完时的数据库查询阻塞请求。美团的 Leaf 就是这个思路用双 Buffer 保证在任何时刻都有可用的号段。号段模式的 ID 有序递增对数据库索引友好也不依赖时钟。缺点是强依赖数据库号段表挂了就发不了号双 Buffer 和预加载可以缓解但不能完全消除。Redis INCRRedis 的INCR命令是原子操作天然适合做分布式 ID 生成publiclonggenerateId(Stringkey){returnredisTemplate.opsForValue().increment(key);}Redis 单线程模型保证了原子性不需要加锁高并发下也不会重复。实现比号段模式简单得多不需要维护号段加载逻辑。但它有自己的问题。号段模式一次数据库交互拿一批 ID之后全在内存里生成。Redis INCR 每次生成 ID 都要一次网络往返QPS 很高时网络开销会成为瓶颈。另外 Redis 宕机了 ID 就发不出来了虽然可以做主从切换但切换过程中有短暂的不可用窗口。还有 Redis 的持久化策略 —— 如果配置不当故障恢复后计数器可能回退导致 ID 重复需要额外保证持久化策略的正确性。Redis INCR 适合对性能要求不是极端高、已有 Redis 基础设施的场景。雪花算法Snowflake 是 Twitter 开源的分布式 ID 生成方案。它不依赖任何外部存储本地直接生成性能极高。核心思想是把一个 64 位的 Long 整数拆成几段每段有不同的含义41 位时间戳提供了约 69 年的使用周期对于绝大多数业务系统已经足够。12 位序列号意味着同一毫秒同一机器最多生成 4096 个 ID。5 位数据中心 5 位机器 ID最多支持 1024 个节点。生成逻辑取当前时间戳如果和上一次相同序列号自增如果不同序列号归零。序列号溢出时等下一毫秒再生成。nextId(): timestamp 当前时间戳 if timestamp lastTimestamp: 时钟回拨抛异常或等待恢复 if timestamp lastTimestamp: sequence if sequence maxSequence: 等待下一毫秒重新获取 timestamp else: sequence 0 lastTimestamp timestamp return (timestamp - epoch) 22 | datacenterId 17 | workerId 12 | sequence位运算的拆解 22把时间戳移到最高位 17和 12分别给数据中心和机器 ID 留出位置最后 12 位留给序列号。OR 操作把各段拼成一个完整的 64 位整数。雪花算法纯本地生成没有网络开销ID 整体递增对数据库索引友好。缺点是对系统时钟有依赖。时钟回拨雪花算法最大的隐患是时钟回拨。线上环境里更常见的是机器时间同步异常。例如某台机器因为时间同步配置异常时钟突然回拨几秒雪花算法会立即拒绝生成 ID最终表现为业务请求失败。正常情况下服务器时间是单调递增的但 NTP 同步、闰秒调整、虚拟机迁移这些场景都可能导致时间往回跳。处理方式通常有两种小幅回拨等待恢复。检测到回拨幅度在几毫秒以内时sleep 一小段时间再重试。大部分 NTP 同步造成的小幅回拨都能扛过去。if(timestamplastTimestamp){longoffsetlastTimestamp-timestamp;if(offset5){Thread.sleep(offset1);// 等待回拨恢复timestampSystem.currentTimeMillis();if(timestamplastTimestamp){thrownewRuntimeException(时钟回拨过大拒绝生成ID);}}else{thrownewRuntimeException(时钟回拨过大拒绝生成ID);}}大幅回拨直接报警。回拨几秒以上通常意味着运维问题这时候比兜底更有意义的是报警让运维介入排查根因。也有方案在 64 位中预留几位做回拨计数器每次检测到回拨就加一这样即使时间回退也不会重复。代价是留给时间戳或序列号的位数变少了。方案对比方案性能趋势递增适合作为主键运维成本适合场景数据库自增高是适合低单机部署数据量不大UUID高否一般低追踪 ID、日志关联数据库号段高是适合中业务主键已有数据库Redis INCR高是适合中已有 Redis 基础设施雪花算法极高是适合低大规模分布式系统小结分布式 ID 的设计是在业务规模和系统复杂度之间做取舍。对于早期系统数据库自增通常已经足够当业务发展到分库分表阶段可以考虑号段模式或者 Redis INCR如果需要更高并发、更大规模的分布式生成能力再引入雪花算法。很多时候问题并不是现有方案性能不够而是在业务还没有复杂到那个程度时就提前引入了复杂的分布式方案最终增加了系统维护成本。
企业数字化 ERP 产品动态
相关推荐
智能轨道插座哪家公司品质靠谱?多个热门品牌对比帮你轻松选好货 做过装修或者负责过商业空间配电规划的朋友都知道,传统固定插座的痛点实在突出:位置定死没法调整、多设备用电不够用、布线杂乱影响美观,还容易有安全隐患。随着用电需求的多样化,电源轨道系统逐渐成为家装、商用、工业场景的新选… · 2026/10/15 19:50:14
智能轨道插座生产厂家怎么挑?掌握这些实用技巧轻松选到靠谱商家 不管是家装做用电规划的业主、承接商装项目的设计师,还是负责工业空间配电的采购,近两年选电源轨道系统供应商的时候,大概率都有过迷茫:市面上做智能轨道插座的厂家越来越多,宣传点五花八门,怎么筛才能避开… · 2026/10/7 15:57:20
Miden VM路线图深度解读:2024年即将发布的5大革命性功能 Miden VM路线图深度解读:2024年即将发布的5大革命性功能 【免费下载链接】miden-vm STARK-based virtual machine 项目地址: https://gitcode.com/gh_mirrors/mi/miden
Miden VM是基于STARK技术的高性能虚拟机,2024年将迎来五大核心功能升级&… · 2026/8/24 23:46:24
枣庄学习电工证保姆级教程:急需特种作业证才能上岗找工作 枣庄学习电工证保姆级教程:急需特种作业证才能上岗找工作 你是不是正在找电工相关的工作,但苦于没有电工证?别急,枣庄学习电工证正是你最需要的“敲门砖”。今天我就手把手教你搞定枣庄电工证的报考流程、合格标准、通过率和注意事项,助你顺利上岗。… · 2026/11/15 22:55:52
昆山电工证去哪报名官方回应来了,工地太忙根本没时间复习考试 昆山电工证去哪报名官方回应来了,工地太忙根本没时间复习考试 工地太忙根本没时间复习考试,这是很多一线电工的共同烦恼。尤其是像昆山这样施工项目密集的城市,电工证报考和复审的时间安排,常常被各种紧急任务打乱节奏。最近,不少施工人员在咨询“… · 2026/11/15 22:55:52
焊工和特种工哪个好考在哪考别再交冤枉钱 焊工和特种工哪个好考在哪考别再交冤枉钱 怕考不过白交培训费?焊工和特种工哪个好考?其实很多人都搞不清这两个证的区别,也不清楚该在哪考,结果一不小心就踩坑了。尤其是像濮阳这样的小城市,很多建筑工人都是在工地上边干边打听,结果报了个培训班,交完… · 2026/11/15 22:55:52
登高架设证考试时间你知道吗?电子证书过期了怎么复审 登高架设证考试时间你知道吗?电子证书过期了怎么复审 证书过期了不知道怎么复审延期,你不是一个人。特别是像登高架设证这样的特种作业证,一旦失效,不仅影响日常工作,还可能面临法律风险。很多人以为拿到电子证书就万事大吉,但其实复审和继续教育同样关… · 2026/11/15 22:55:52
御工坊特种橡筋保姆级教程:怕考不过白交培训费?这些避坑技巧必须知道 御工坊特种橡筋保姆级教程:怕考不过白交培训费?这些避坑技巧必须知道 你是不是也担心,花了钱报名了御工坊特种橡筋培训,最后考试不过,钱打水漂?别急,这波保姆级教程帮你搞清楚流程、避坑点,让你一次性拿证不走弯路! ###… · 2026/11/15 22:55:52
上海应急电工证内部消息:工地太忙没时间复习?手把手教你搞定全流程 上海应急电工证内部消息:工地太忙没时间复习?手把手教你搞定全流程 工地太忙根本没时间复习考试,这种声音每天都在耳边回响。作为新乡应届工程类毕业生,我知道你们真正需要的不是一堆理论,而是 能快速拿到上海应急电工证的内部消息 和… · 2026/11/15 22:54:51
长春初级电工证怎么考?通过率揭秘全在这里 长春初级电工证怎么考?通过率揭秘全在这里 之前考的证在外省能不能转过来?这几乎是每个想从事电工工作的人都会问的问题。特别是那些在外地打拼多年、手里握着一张“外地电工证”的人,到了长春想继续干这一行,第一反应就是“我的证能用吗?”。今天我们就… · 2026/11/15 0:00:50
国内电工证报考条件与考试时间 低压电工证怎么考?学历不高也能报名,官方报名入口全在这 你是不是经常听说“电工证是入行门槛”,但又担心自己学历不够、经验不足,根本报不了名?别急,今天就带你从零了解【国内电工证】的报考流程、考试内容,还有怎么在 官方报名入口… · 2026/11/15 0:00:50
电工作业时如何断电?电子证书到底能不能全国通用? 电工作业时如何断电?电子证书到底能不能全国通用? 实操考试心里没底怕挂科,特别是电工作业时如何断电这一操作,不仅关系到你能不能拿到证书,更关系到以后能不能顺利上岗。很多人觉得这不过就是“断个电”,但其实这里面的门道可不少,稍有不慎就可能出错… · 2026/11/15 0:00:50
长春初级电工证怎么考?通过率揭秘全在这里 长春初级电工证怎么考?通过率揭秘全在这里 之前考的证在外省能不能转过来?这几乎是每个想从事电工工作的人都会问的问题。特别是那些在外地打拼多年、手里握着一张“外地电工证”的人,到了长春想继续干这一行,第一反应就是“我的证能用吗?”。今天我们就… · 2026/11/15 0:00:50
国内电工证报考条件与考试时间 低压电工证怎么考?学历不高也能报名,官方报名入口全在这 你是不是经常听说“电工证是入行门槛”,但又担心自己学历不够、经验不足,根本报不了名?别急,今天就带你从零了解【国内电工证】的报考流程、考试内容,还有怎么在 官方报名入口… · 2026/11/15 0:00:50
电工作业时如何断电?电子证书到底能不能全国通用? 电工作业时如何断电?电子证书到底能不能全国通用? 实操考试心里没底怕挂科,特别是电工作业时如何断电这一操作,不仅关系到你能不能拿到证书,更关系到以后能不能顺利上岗。很多人觉得这不过就是“断个电”,但其实这里面的门道可不少,稍有不慎就可能出错… · 2026/11/15 0:00:50
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/15 1:51:20
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/15 4:02:19
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/15 3:02:05