Twitter的Snowflake算法是在分布式系统中一种自增ID的算法,ID能够按照时间有序生成并且可以做到全局唯一。Twitter对雪花算法的需求:
性能
协调
对于数据中心内部和跨数据中心的高可用性,生成id的机器无需进行集群协调。也就是说无需再每个服务之间进行通讯进行协调。
直接排序
无需加载整个对象ID就能排序(时间戳)
紧凑
生成的ID要紧凑,换句话说就是ID所占的长度需要适中在完成业务需要的基础上。
高可用
ID生成服务要高可用,例如:存储服务
1.1 雪花算法的数据结构Tips: Twitter的雪花算法的说明https://github.com/twitter-archive/snowflake/tree/scala_28
雪花算法生产的ID所占8个字节64位,也就是长整型 long 的长度。
应该使用NTP来保持系统时钟的准确性。Snowflake 可以防止非单调时钟的影响,也就是时钟倒走。如果您的时钟运行得很快,并且NTP告诉它重复几毫秒,那么 Snowflake 将拒绝生成id,直到上次我们生成id之后的某个时间。在ntp不会让时钟倒转的模式下运行。
如果时间进行回拨那么生成的ID就有可能出现重复的情况。
2. 雪花算法Java实现/**
* @author mxsm
* @date 2022/4/9 21:17
* @Since 1.0.0
*/
public class SnowflakeGenerator {
private static final long FIXED_TIMESTAMP = 1649491204306L;
private int machineId;
private int sequenceNumber = 0;
//最后一次生成ID时间
private volatile long lastTimestamp = -1L;
public SnowflakeGenerator(int machineId) {
this.machineId = machineId;
}
public synchronized long nextId() {
//获取当前时间
long currentTimestamp = System.currentTimeMillis();
//同一个毫秒内生成ID
if(currentTimestamp == lastTimestamp){
sequenceNumber = 1;
//处理一秒超过4096个
if(sequenceNumber > 4096){
while (currentTimestamp <= lastTimestamp){
currentTimestamp = System.currentTimeMillis();
}
sequenceNumber = 0;
}
}else {
//重置序列号
sequenceNumber = 0;
}
lastTimestamp = currentTimestamp;
return ( (currentTimestamp - FIXED_TIMESTAMP) << 22) | (machineId << 12) | sequenceNumber;
}
}
Tips: 代码地址https://github.com/mxsm/distributed-id-generator/tree/main/generator-snowflake
以上代码是简单的实现。
3.优缺点优点:
缺点:
4. 总结Tips: 在本人公司没有单独部署雪花算法的生产服务器,而是将生成器直接集成到了每个项目的代码中。机器ID是IP地址取模32后的值。所以在高并发下可能会出现小概率的重复情况。在可允许的范围内
雪花算法的服务集群没有服务之间的协调和同步。可以说是用单机组成的高可用分布式ID可用集群。雪花算法依赖时间戳,如果时间戳出现回拨的情况就有可能ID重复的情况。总体来说雪花算法相对于Redis实现 UUID 以及MySQL有更优。
我是蚂蚁背大象,文章对你有帮助点赞关注我,文章有不正确的地方请您斧正留言评论~谢谢
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved