mirror of
https://github.com/Snailclimb/JavaGuide
synced 2025-06-16 18:10:13 +08:00
[docs update]分布式id解决方案增加IdGenerator(开源框架)
This commit is contained in:
parent
f0a75ccbd4
commit
7a18ac2ebf
@ -268,23 +268,21 @@ int version = uuid.version();// 4
|
|||||||
|
|
||||||
Snowflake 是 Twitter 开源的分布式 ID 生成算法。Snowflake 由 64 bit 的二进制数字组成,这 64bit 的二进制被分成了几部分,每一部分存储的数据都有特定的含义:
|
Snowflake 是 Twitter 开源的分布式 ID 生成算法。Snowflake 由 64 bit 的二进制数字组成,这 64bit 的二进制被分成了几部分,每一部分存储的数据都有特定的含义:
|
||||||
|
|
||||||
- **第 0 位**:符号位(标识正负),始终为 0,没有用,不用管。
|

|
||||||
- **第 1~41 位**:一共 41 位,用来表示时间戳,单位是毫秒,可以支撑 2 ^41 毫秒(约 69 年)
|
|
||||||
- **第 42~52 位**:一共 10 位,一般来说,前 5 位表示机房 ID,后 5 位表示机器 ID(实际项目中可以根据实际情况调整)。这样就可以区分不同集群/机房的节点。
|
|
||||||
- **第 53~64 位**:一共 12 位,用来表示序列号。 序列号为自增值,代表单台机器每毫秒能够产生的最大 ID 数(2^12 = 4096),也就是说单台机器每毫秒最多可以生成 4096 个 唯一 ID。
|
|
||||||
|
|
||||||

|
- **sign(1bit)**:符号位(标识正负),始终为 0,代表生成的 ID 为正数。
|
||||||
|
- **timestamp (41 bits)**:一共 41 位,用来表示时间戳,单位是毫秒,可以支撑 2 ^41 毫秒(约 69 年)
|
||||||
|
- **datacenter id + worker id (10 bits)**:一般来说,前 5 位表示机房 ID,后 5 位表示机器 ID(实际项目中可以根据实际情况调整)。这样就可以区分不同集群/机房的节点。
|
||||||
|
- **sequence (12 bits)**:一共 12 位,用来表示序列号。 序列号为自增值,代表单台机器每毫秒能够产生的最大 ID 数(2^12 = 4096),也就是说单台机器每毫秒最多可以生成 4096 个 唯一 ID。
|
||||||
|
|
||||||
如果你想要使用 Snowflake 算法的话,一般不需要你自己再造轮子。有很多基于 Snowflake 算法的开源实现比如美团 的 Leaf、百度的 UidGenerator,并且这些开源实现对原有的 Snowflake 算法进行了优化。
|
在实际项目中,我们一般也会对 Snowflake 算法进行改造,最常见的就是在 Snowflake 算法生成的 ID 中加入业务类型信息。
|
||||||
|
|
||||||
另外,在实际项目中,我们一般也会对 Snowflake 算法进行改造,最常见的就是在 Snowflake 算法生成的 ID 中加入业务类型信息。
|
|
||||||
|
|
||||||
我们再来看看 Snowflake 算法的优缺点:
|
我们再来看看 Snowflake 算法的优缺点:
|
||||||
|
|
||||||
- **优点**:生成速度比较快、生成的 ID 有序递增、比较灵活(可以对 Snowflake 算法进行简单的改造比如加入业务 ID)
|
- **优点**:生成速度比较快、生成的 ID 有序递增、比较灵活(可以对 Snowflake 算法进行简单的改造比如加入业务 ID)
|
||||||
- **缺点**:需要解决重复 ID 问题(ID 生成依赖时间,在获取时间的时候,可能会出现时间回拨的问题,也就是服务器上的时间突然倒退到之前的时间,进而导致会产生重复 ID)、依赖机器 ID 对分布式环境不友好(当需要自动启停或增减机器时,固定的机器 ID 可能不够灵活)。
|
- **缺点**:需要解决重复 ID 问题(ID 生成依赖时间,在获取时间的时候,可能会出现时间回拨的问题,也就是服务器上的时间突然倒退到之前的时间,进而导致会产生重复 ID)、依赖机器 ID 对分布式环境不友好(当需要自动启停或增减机器时,固定的机器 ID 可能不够灵活)。
|
||||||
|
|
||||||
针对雪花算法的时间回拨问题和依赖机器 ID 的问题,一些基于雪花算法的开源框架都有自己的解决方案,比如百度的 UIDGenerator 和 美团的 Leaf (后面会提到)。
|
如果你想要使用 Snowflake 算法的话,一般不需要你自己再造轮子。有很多基于 Snowflake 算法的开源实现比如美团 的 Leaf、百度的 UidGenerator(后面会提到),并且这些开源实现对原有的 Snowflake 算法进行了优化,性能更优秀,还解决了 Snowflake 算法的时间回拨问题和依赖机器 ID 的问题。
|
||||||
|
|
||||||
并且,Seata 还提出了“改良版雪花算法”,针对原版雪花算法进行了一定的优化改良,解决了时间回拨问题,大幅提高的 QPS。具体介绍和改进原理,可以参考下面这两篇文章:
|
并且,Seata 还提出了“改良版雪花算法”,针对原版雪花算法进行了一定的优化改良,解决了时间回拨问题,大幅提高的 QPS。具体介绍和改进原理,可以参考下面这两篇文章:
|
||||||
|
|
||||||
@ -297,11 +295,11 @@ Snowflake 是 Twitter 开源的分布式 ID 生成算法。Snowflake 由 64 bit
|
|||||||
|
|
||||||
[UidGenerator](https://github.com/baidu/uid-generator) 是百度开源的一款基于 Snowflake(雪花算法)的唯一 ID 生成器。
|
[UidGenerator](https://github.com/baidu/uid-generator) 是百度开源的一款基于 Snowflake(雪花算法)的唯一 ID 生成器。
|
||||||
|
|
||||||
不过,UidGenerator 对 Snowflake(雪花算法)进行了改进,生成的唯一 ID 组成如下。
|
不过,UidGenerator 对 Snowflake(雪花算法)进行了改进,生成的唯一 ID 组成如下:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
- **sign(1bit)**:符号位(标识正负),始终为 0,没有用,不用管。
|
- **sign(1bit)**:符号位(标识正负),始终为 0,代表生成的 ID 为正数。
|
||||||
- **delta seconds (28 bits)**:当前时间,相对于时间基点"2016-05-20"的增量值,单位:秒,最多可支持约 8.7 年
|
- **delta seconds (28 bits)**:当前时间,相对于时间基点"2016-05-20"的增量值,单位:秒,最多可支持约 8.7 年
|
||||||
- **worker id (22 bits)**: 机器 id,最多可支持约 420w 次机器启动。内置实现为在启动时由数据库分配,默认分配策略为用后即弃,后续可提供复用策略。
|
- **worker id (22 bits)**: 机器 id,最多可支持约 420w 次机器启动。内置实现为在启动时由数据库分配,默认分配策略为用后即弃,后续可提供复用策略。
|
||||||
- **sequence (13 bits)**: 每秒下的并发序列,13 bits 可支持每秒 8192 个并发。
|
- **sequence (13 bits)**: 每秒下的并发序列,13 bits 可支持每秒 8192 个并发。
|
||||||
@ -316,7 +314,7 @@ UidGenerator 官方文档中的介绍如下:
|
|||||||
|
|
||||||
#### Leaf(美团)
|
#### Leaf(美团)
|
||||||
|
|
||||||
**[Leaf](https://github.com/Meituan-Dianping/Leaf)** 是美团开源的一个分布式 ID 解决方案 。这个项目的名字 Leaf(树叶) 起源于德国哲学家、数学家莱布尼茨的一句话:“There are no two identical leaves in the world”(世界上没有两片相同的树叶) 。这名字起得真心挺不错的,有点文艺青年那味了!
|
[Leaf](https://github.com/Meituan-Dianping/Leaf) 是美团开源的一个分布式 ID 解决方案 。这个项目的名字 Leaf(树叶) 起源于德国哲学家、数学家莱布尼茨的一句话:“There are no two identical leaves in the world”(世界上没有两片相同的树叶) 。这名字起得真心挺不错的,有点文艺青年那味了!
|
||||||
|
|
||||||
Leaf 提供了 **号段模式** 和 **Snowflake(雪花算法)** 这两种模式来生成分布式 ID。并且,它支持双号段,还解决了雪花 ID 系统时钟回拨问题。不过,时钟问题的解决需要弱依赖于 Zookeeper(使用 Zookeeper 作为注册中心,通过在特定路径下读取和创建子节点来管理 workId) 。
|
Leaf 提供了 **号段模式** 和 **Snowflake(雪花算法)** 这两种模式来生成分布式 ID。并且,它支持双号段,还解决了雪花 ID 系统时钟回拨问题。不过,时钟问题的解决需要弱依赖于 Zookeeper(使用 Zookeeper 作为注册中心,通过在特定路径下读取和创建子节点来管理 workId) 。
|
||||||
|
|
||||||
@ -359,6 +357,29 @@ Tinyid 的原理比较简单,其架构如下图所示:
|
|||||||
|
|
||||||
Tinyid 的优缺点这里就不分析了,结合数据库号段模式的优缺点和 Tinyid 的原理就能知道。
|
Tinyid 的优缺点这里就不分析了,结合数据库号段模式的优缺点和 Tinyid 的原理就能知道。
|
||||||
|
|
||||||
|
#### IdGenerator(个人)
|
||||||
|
|
||||||
|
和 UidGenerator、Leaf 一样,[IdGenerator](https://github.com/yitter/IdGenerator) 也是一款基于 Snowflake(雪花算法)的唯一 ID 生成器。
|
||||||
|
|
||||||
|
IdGenerator 有如下特点:
|
||||||
|
|
||||||
|
- 生成的唯一 ID 更短;
|
||||||
|
- 兼容所有雪花算法(号段模式或经典模式,大厂或小厂);
|
||||||
|
- 原生支持 C#/Java/Go/C/Rust/Python/Node.js/PHP(C 扩展)/SQL/ 等语言,并提供多线程安全调用动态库(FFI);
|
||||||
|
- 解决了时间回拨问题,支持手工插入新 ID(当业务需要在历史时间生成新 ID 时,用本算法的预留位能生成 5000 个每秒);
|
||||||
|
- 不依赖外部存储系统;
|
||||||
|
- 默认配置下,ID 可用 71000 年不重复。
|
||||||
|
|
||||||
|
IdGenerator 生成的唯一 ID 组成如下:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- **timestamp (位数不固定)**,时间差,是生成 ID 时的系统时间减去 BaseTime(基础时间,也称基点时间、原点时间、纪元时间,默认值为 2020 年) 的总时间差(毫秒单位)。初始为 5bits,随着运行时间而增加。如果觉得默认值太老,你可以重新设置,不过要注意,这个值以后最好不变。
|
||||||
|
- **worker id (默认 6 bits)**: 机器 id,机器码,最重要参数,是区分不同机器或不同应用的唯一 ID,最大值由 `WorkerIdBitLength`(默认 6)限定。如果一台服务器部署多个独立服务,需要为每个服务指定不同的 WorkerId。
|
||||||
|
- **sequence (默认 6 bits)**,序列数,是每毫秒下的序列数,由参数中的 `SeqBitLength`(默认 6)限定。增加 `SeqBitLength` 会让性能更高,但生成的 ID 也会更长。
|
||||||
|
|
||||||
|
Java 语言使用示例:<https://github.com/yitter/idgenerator/tree/master/Java>。
|
||||||
|
|
||||||
## 总结
|
## 总结
|
||||||
|
|
||||||
通过这篇文章,我基本上已经把最常见的分布式 ID 生成方案都总结了一波。
|
通过这篇文章,我基本上已经把最常见的分布式 ID 生成方案都总结了一波。
|
||||||
|
@ -5,7 +5,7 @@ tag:
|
|||||||
- 练级攻略
|
- 练级攻略
|
||||||
---
|
---
|
||||||
|
|
||||||
> **推荐语**:这是[《Java面试指北》](https://javaguide.cn/zhuanlan/java-mian-shi-zhi-bei.html)练级攻略篇中的一篇文章,分享了我对于如何快速学习一门新技术的看法。
|
> **推荐语**:这是[《Java 面试指北》](https://javaguide.cn/zhuanlan/java-mian-shi-zhi-bei.html)练级攻略篇中的一篇文章,分享了我对于如何快速学习一门新技术的看法。
|
||||||
>
|
>
|
||||||
> 
|
> 
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user