snowflake替换为uid-generator

# snowflake算法

将long的64位分为4部分,时间戳、数据中心id、工作机器id和序列号,位数分配如下:

/**
 * <pre>{@code
 * +------+-------------+--------------+-----------+-----------+
 * | sign |  timestamp  | datacenterId | machineId | sequence  |
 * +------+-------------+--------------+-----------+-----------+
 *   1bit     41bits         5bits         5bits      12bits
 * }</pre>
*/
1
2
3
4
5
6
7
8

时间戳部分的时间单位一般为毫秒,也就是说1台工作机器1毫秒可产生4096个id(2的12次方)。

# uid-generator

uid-generator将long的64位分为3部分,时间戳、工作机器id和序列号,位数分配如下:

/**
 * <pre>{@code
 * +------+----------------------+----------------+-----------+
 * | sign |     delta seconds    | worker node id | sequence  |
 * +------+----------------------+----------------+-----------+
 *   1bit          28bits              22bits         13bits
 * }</pre>
* /
1
2
3
4
5
6
7
8
  • delta seconds:相对于时间戳的增量秒数,单位为秒,28bits最大可支持约8.7年。
  • worker node id:工作机器id,22bits最多可支持4194304次id分配。
  • sequence:序列号,每秒下的并发序列,13 bits可支持每秒8192个并发。

# 替换原因

uid-generator相对于snowflake的优势在于:

snowflake需要手动配置数据中心id和工作机器id,存在运维工作量,有出错风险。

uid-generator在启动时通过数据库表注册机器id,不需要手动配置,更加方便。

# 替换过程

uid-generatordelta seconds部分默认是28bits,最大可支持约8.7年,实际使用中需要调整更大一些。

可以将worker node id部分按实际情况缩小,增加delta seconds部分的位数。

例如将delta seconds调整为32位,worker node id调整为18位,则最大可以支持4294967295秒增量,约136年,支持最大262143次机器id分配。

由于之前使用的是snowflake,需要保证uid-generator生成的id始终大于之前的snowflake生成的id。

取一个当前时间snowflake生成的id,例如1846130381917519918。将其按uid-generator的位数分配拆分,得到delta seconds

Long uid = 1846130381917519918L;
//取32位到64位的值
Long deltaeconds  = uid >> 31;
1
2
3

得到秒差值,则只需要保证uid-generator的时间基准与当前时间的秒差值大于得到的秒差值即可。

之前使用snowflake作为id生成器时,是将snowflake对象作为springbean注入到spring容器中,然后通过@Autowired注入到需要使用的地方。

@Configuration
@Data
@ConfigurationProperties(prefix = "snowflake")
public class IdGenderConfig {

	//数据中心[0,31] 配置文件中不配置就是0
	private long datacenterId;

	//机器标识[0,31] 配置文件中不配置就是0
	private long machineId;

	@Bean
	public Snowflake getSnowflake(){
		return new Snowflake(machineId,datacenterId);
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

为了做最小化改动,可以再实现一个snowflake类,继承原有的snowflake类,并将生成id的方法替换为uid-generator的生成id方法。

@Component
public class Snowflake extends cn.hutool.core.lang.Snowflake {
	@Autowired
	private UidGeneratorUtil uidGeneratorUtil;

	@Override
	public  long nextId() {
		return uidGeneratorUtil.getUid();
	}

	@Override
	public String nextIdStr() {
		return uidGeneratorUtil.getUidStr();
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
上次更新: 2024/10/19, 04:02:06
最近更新
01
docker-compose笔记
01-12
02
MySQL数据迁移
11-27
03
Docker部署服务,避免PID=1
11-27
更多文章>