基于雪花算法的Java版本的全局ID算法
GUID是用Java语言实现的全局唯一ID算法,它基于Twitter的雪花算法SnowFlake。不仅可以使用于单机环境,更适用于分布式/集群环境中生成全局唯一的ID。已经在公司内部使用。
1. 特点
GUID算法具有以下特点:
高性能:单节点,100万/秒
递增:各节点按时间趋势递增
长度短:64位长度的long类型整数,十进制表示时最长19位
高可用:各节点独立生成ID
可配置:各组成部分的长度可以根据需要在环境变量里配置
可解析:ID可以被解析出各个组成部分
轻量部署:分布式或集群环境里只需要为每台机器/JVM配置两个环境变量(数据中心ID和机器ID),不依赖数据库
2. ID结构
guid生成的ID包括6个部分: 0 - 41位时间戳 - 3位数据中心标识 - 7位机器标识 - 2位保留位 - 10位序列号
- 1为标识,0表示正数。
- 41位时间戳,当前时间的毫秒减去开始时间戳(2020-01-01 00:00:00)。可用 (2 ^ 41) / (1000L * 60 * 60 * 24 * 365) = 69年。
- 3位数据中心标识,可支持(2 ^ 3) = 8个数据中心。
- 7位机器标识,每个数据中心可支持(2 ^ 7) = 128个机器标识。
- 2位时钟回拨次数,可支持(2 ^ 2 - 1) = 3次时钟回拨。
- 10位序列号,每个节点每一毫秒支持(2 ^ 10) = 1024个序列号。
3. 参数配置
环境变量中可以配置以下参数,其中UUID_WORKER_ID必须配置,而且必须唯一:
参数名参数Key必需缺省值机器IDUUID_WORKER_ID是无数据中心IDUUID_DATACENTER_ID否0时间戳起点UUID_START_EPOCH否2020-01-01 00:00:00时钟回拨阈值UUID_CLOCK_BACK_THRESHOLD否50L时间戳长度UUID_TIMESTAMP_LEN否41L数据中心长度UUID_DATACENTER_ID_LEN否3L机器ID长度UUID_WORKER_ID_LEN否7L时钟回拨次数长度UUID_REMAIN_LEN否2L序列号长度UUID_SEQUENCE_LEN否10L
各部分的长度可以定制:时间戳长度、数据中心长度、机器长度、时钟回拨次数长度、序列号长度,总长是63
4. 用法
下载代码后本地编译打包上传到本地仓库
<dependency> <groupId>com.abc</groupId> <artifactId>guid</artifactId> <version>1.0</version> </dependency>
- 使用时需要为当前机器/JVM设置环境变量:GUID_WORKER_ID
- 集群环境下启动时需要执行以下两个脚本文件:
src/main/resources/start_guid.sh:根据IP地址设置集群里所有机器的ID
export GUID_DATACENTER_ID=1 export IP_192_168_1_100_GUID_WORKER_ID=1 export IP_192_168_1_101_GUID_WORKER_ID=2
src/main/resources/start.sh:集群机器启动脚本,根据本机IP地址从start_guid.sh获得机器ID设置为环境变量
BASEDIR=$(cd "$(dirname "$0")"; pwd) if [ -f "${BASEDIR}/start_guid.sh" ];then . ${BASEDIR}/start_guid.sh IP_ADDRESS=`hostname -i` GUID_WORKER_ID_NAME=IP_${IP_ADDRESS//\./\_}_GUID_WORKER_ID export GUID_WORKER_ID=$(eval echo '$'"$GUID_WORKER_ID_NAME") fi
long id = GIDGenerator.nextId();
结果:113274030270189578
String str = GUIDGenerator.id2Str(113274030270189578L);
结果:20201108T21:50:33.346-0-1-0-10
5. JMH测试结果
Benchmark Mode Cnt Score Error Units GUIDGeneratorBenchmarkTest.testNextId thrpt 10 1023.263 ± 4.812 ops/ms