适用于Kubernetes的分布式ID生成服务SnowflakeID,解决时钟回拨问题

最近准备上马Kubernetes的项目,之前已经把传统单机部署的Java应用程序,改为微服务Microservice架构。
相同的微服务跑在多个不同的容器内,需要为每条业务数据(transaction)分配唯一的ID,并且需要保证在各自容器跑的微服务生成的ID不会出现重复。
当时调研了多种UUID生成工具和算法,最终看上了浓眉大眼的推特Snowflake雪花ID生成算法。

Snowflake是由twitter开源的分布式ID生成算法。(当然Twitter现在已经被特斯拉老板马斯克买下来,并且改名为X了。)

这里没有直接使用snowflake算法,而是进行了改造。WorkerID由Zookeeper分配,利用了Zookeeper的持久顺序节点(PERSISTENT_SEQUENTIAL),因为在K8s环境里,Pod自动分配,可能有成百上千个,一个个去给它分配WorkerID显然不大可能。
还有就是从原先算法里的序列号位数里拿出4位来解决时钟回拨问题。

改造后的SnowflakeID的组成

SnowflakeID是一个64位的Long类型数字,对于bit的分配如下:

1
2
3
4
5
+----------------------------------------------------------------------------------------------+
| 标识位 | 41位时间戳 | 10位机器号 | 4位时钟回拨掩码 | 8位序列号 |
+----------------------------------------------------------------------------------------------+
| 1 Bit Unused | 41 Bit Timestamp | 10 Bit Worker ID | 4 Bit Sequence Mask | 8 Bit Sequence ID |
+----------------------------------------------------------------------------------------------+

1 + 41 + 10 + 4 + 8 = 64 bit

Read more