说说生成唯一 ID 的雪花算法是怎么样的?

1,060 阅读3分钟

这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战

作者简介:悟空,8年一线互联网开发和架构经验,用故事讲解分布式、架构设计、Java 核心技术。《JVM性能优化实战》专栏作者,开源了《Spring Cloud 实战 PassJava》项目,公众号:悟空聊架构。本文已收录至 www.passjava.cn

大家好,我是悟空。

今天给大家带来的大厂面试题是:

说说生成唯一 ID 的雪花算法是怎么样的?

**雪花算法**

雪花算法 Snowflake:Twitter 开源的分布式 id 生成算法,64 位的 long 型的 id,分为 4 部分:

  • 1 bit:不用,统一为 0

  • 41 bits:毫秒时间戳,可以表示 69 年的时间。

  • 10 bits:5 bits 代表机房 id,5 个 bits 代表机器 id。最多代表 32 个机房,每个机房最多代表 32 台机器。

  • 12 bits:同一毫秒内的 id,最多 4096 个不同 id,自增模式

优点:

  • 毫秒数在高位,自增序列在低位,整个ID都是趋势递增的。

  • 不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成ID的性能也是非常高的。

  • 可以根据自身业务特性分配bit位,非常灵活。

缺点:

  • 强依赖机器时钟,如果机器上时钟回拨( 如 2017 年闰秒 7:59:60),会导致发号重复或者服务会处于不可用状态。


补充:

百度的 UIDGenerator 算法

UIDGenerator 算法

基于 Snowflake 的优化算法。 借用未来时间和双 Buffer 来 解决时间回拨 与生成性能等问题,同时结合 MySQL 进行 ID 分配。

优点 : 解决了时间回拨和生成性能问题。

缺点 :依赖 MySQL 数据库。

美团的 Leaf-Snowflake 算法

  • 为什么叫 Leaf(叶子):来自数学家莱布尼茨的一句话:“世界上没有两片相同的树叶”,也就是说这个算法生成的 ID 是唯一的。

图片来源于美团

获取 id 是通过代理服务访问数据库获取一批 id(号段)。

双缓冲:当前一批的 id 使用 10%时,再访问数据库获取新的一批 id 缓存起来,等上批的 id 用完后直接用。

优点:

  • Leaf服务可以很方便的线性扩展,性能完全能够支撑大多数业务场景。

  • ID号码是趋势递增的8byte的64位数字,满足上述数据库存储的主键要求。

  • 容灾性高:Leaf服务内部有号段缓存,即使DB宕机,短时间内Leaf仍能正常对外提供服务。

  • 可以自定义max_id的大小,非常方便业务从原有的ID方式上迁移过来。

  • 即使DB宕机,Leaf仍能持续发号一段时间。

  • 偶尔的网络抖动不会影响下个号段的更新。

缺点:

  • ID号码不够随机,能够泄露发号数量的信息,不太安全。

怎么选择:一般自己的内部系统,雪花算法足够,如果还要更加安全可靠,可以选择百度或美团的生成唯一 ID 的方案。

·······END·······

如果你的朋友也 在准备面试、考试,

欢迎 转发分享 给 TA,