分布式系统里怎么搞个全局唯一序列号,思路分享和一些想法
- 问答
- 2025-12-24 21:41:09
- 2
在分布式系统里搞一个全局唯一序列号,这是个挺经典也挺实际的问题,想象一下,你有一个电商网站,订单系统部署在好几台机器上,如果每台机器自己生成订单号,那很可能就重复了,这就乱套了,我们需要一个方法,保证在所有机器上生成的ID都是唯一的,并且最好还能有点别的用处,比如能看出大致的生成顺序。
最直接了当的想法,可能就是用一个中心化的发号器,简单说,就是搞一台专门的服务器,或者一个专门的服务,整个系统里所有的ID都找它来要,这台服务器呢,就维护一个数字,比如从1开始,每来一个请求,就把这个数字加1然后返回去,这样肯定唯一,因为只有一个地方在发号,但问题也很明显,这个发号器成了单点,万一它挂了,整个系统都创建不了新ID了,我们得想办法让这个发号器高可用,比如给它弄个主从备份,主挂了从机立刻顶上去,但主从切换的时候又要小心别让号发重了,这又增加了复杂性,这个思路在很多公司的早期阶段其实够用了,比如用数据库的自增ID就能勉强应付。(来源:常见的基础架构设计思路)
为了应对更高的流量和避免单点问题,人们想出了很多办法,一个很著名的办法是Twitter的Snowflake算法(来源:Twitter早期工程师团队公开的设计方案),这个算法的思路很巧妙,它不再依赖一个中心化的计数器时刻保持同步,而是把ID本身设计成一个有结构的数字,有点像我们的身份证号,包含了地区、生日、顺序码等信息。

Snowflake生成的ID通常是一个64位的长整数,这64位分成了几个部分:
- 第一位:不用,恒为0,可以理解为符号位,保证生成的ID是正数。
- 时间戳部分:占用41位,这记录的是从某个自定义起始时间(比如公司成立那天)到现在的毫秒数,41位可以用很多年,所以不用担心用完。
- 工作机器ID:占用10位,这就用来区分不同的机器,比如你可以用5位表示机房ID,5位表示机器ID,这样理论上可以部署在32个机房,每个机房32台机器,总共1024台机器。
- 序列号:占用12位,这表示在同一毫秒内产生的序列号,12位意味着每台机器每毫秒可以生成4096个不重复的ID。
这样组合起来,只要保证每个机器的工作机器ID是唯一的(这个在部署时可以手动配置或通过服务发现分配),那么生成的ID就一定是全局唯一的,因为同一毫秒内,不同机器生成的ID其机器ID部分不同;同一机器在同一毫秒内,靠自增的序列号来区分,由于高位是时间戳,这些ID大体上是随时间递增的,如果你按ID排序,基本就相当于按创建时间排序了,这对数据库的索引非常友好。

Snowflake方案很好,但它也引出了新的小问题,就是怎么给每台机器分配唯一的工作机器ID?这又有点回到最初的问题了,不过这个问题好解决多了,因为机器数量是有限的,我们可以用一个简单的数据库表来分配,或者用ZooKeeper、Etcd这样的协调服务来分配。(来源:对Snowflake方案实践中的常见讨论)
除了Snowflake,还有一个常用的思路是“号段”模式,也叫Leaf-Segment(来源:美团技术团队公开的Leaf发号器系统设计),这个想法是,既然每次都访问中心发号器有压力,那我能不能一次多要一点?应用在启动时,或者号快用完时,去一个中心数据库申请一个号段,比如一次申请1000个ID(1到1000),数据库里把当前最大ID更新为1000,然后这1000个ID就由这台机器在内存里自己分配,发完了再去申请下一个号段(1001到2000),这样绝大部分时间发号都是在内存里完成的,性能极高,只有在号段用尽时才需要访问一次数据库,大大降低了数据库的压力,这也有个小缺点,就是如果应用重启,内存里还没用完的号段就浪费了,但这点浪费通常可以接受,这个方案在美团这样的公司有大规模的成功实践。
还有一种思路是借助数据库本身的能力,但做得更巧妙一点,比如用一个数据库表,字段很简单,就一个业务类型tag和一个最大的ID值,每次需要获取新ID时,不像传统那样用自增字段,而是执行一条SQL语句:UPDATE id_table SET max_id = max_id + 步长 WHERE tag = ‘order’,然后同时查询返回更新后的max_id,这样通过数据库的行级锁保证了ID不会重复,步长设置大一点(比如1000),也能减少数据库压力,其实这和号段模式的思想是相通的。(来源:数据库乐观锁在发号场景下的应用)
所以总结一下,搞全局唯一序列号,核心思路其实就是“组合”与“分段”,要么像Snowflake那样,把时间、机器、序列号组合在一起,分散压力;要么像号段模式那样,把ID范围分成一段一段的,批量获取,本地消费,选择哪种方案,要看你的具体场景:是追求极致的性能,还是要求绝对的有序,还是希望实现起来足够简单,没有完美的方案,只有最适合当前阶段的方案。
本文由凤伟才于2025-12-24发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/67785.html
