id生成机制之---雪花算法

雪花算法是一种生成全局唯一ID的方法,适用于分布式环境。其特点包括ID的唯一性、排序性、固定长度及高查询效率。算法由64位组成,包含时间戳、机房ID、机器ID和序号,确保在多节点下生成的ID既唯一又有序。本文详细解析了雪花算法的工作原理,并提供了实践步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

雪花算法:
特性:
1,在多节点下,可以保证我们的全局id的唯一性,不会出现id重复的现象;
2,可以保证我们的id在单节点下是可以排序的;
3,id的位数固定,不会因为id的增长导致我们id的位数变更;
4,id的类型是long类型的数字,不会像uuid虽然保证了唯一性,但是为string类型,查询效率在mysql中要低于long类型;

算法解析:
在这里插入图片描述
雪花算法是一个64字节的long类型数字,其中各部分含义如下。
1,第一部分1个 bit:0,这个是无意义的,它保证了我们的二进制中的首位为0,如果为1则为负数。
2,第二部分41个 bit:表示的是单位为毫秒的时间戳,来保证我们的id是有序的。
4,第三部分是10个 bit:前5个bit表示的是机房id,最多可以有32个机房;后5个bit表示的是机器id,最多可以有32台机器;
6,最后部分是12个 bit:表示的序号,就是某个机房某台机器上这一毫秒内同时生成的 id 的序号,可以保证一毫秒内有4096个id;

使用步骤:
1,创建一个项目,将id包解压放入到项目中,调整package路径。
2,测试直接打开testcreateid.java类运行main方法。
3,项目中使用直接调用getid.createid();方法即可。
4,分布式环境下,根据不同的机房要配置不同的机房号和机器号,最多可以配置32*32个节点;在配置文件中配置相关的机房号和机器号;
在这里插入图片描述
在项目启动的时候,通过shell脚本设置机房好和机器号数值;

-Dsnowflake.workerId=1 -Dsnowflake.datacenterId=1 --启动时传入参数‘机房号’和‘机器号’
### MyBatis Plus 雪花算法 ID生成器返回 -1 的解决方案 当遇到MyBatis Plus中的雪花算法ID生成器返回`-1`的情况时,通常意味着存在配置错误或环境设置不当。具体原因可能涉及时间回拨、机器码冲突等问题。 #### 时间回拨处理 如果服务器经历了一次时间倒退(即NTP同步或其他因素引起的时间调整),这可能导致雪花算法认为当前时间为过去的一个时刻,在这种情况下会抛出异常并最终导致返回默认值 `-1` 。为了防止这种情况发生,可以考虑增加对负偏移量的容忍度或者完全禁用此保护机制: ```java public class CustomSnowflakeIdWorker extends DefaultIdentifierGenerator { private static final long twepoch = 1288834974657L; // 自定义起始时间戳 @Override protected synchronized long nextId() throws Exception { try{ return super.nextId(); }catch(IllegalStateException e){ if(e.getMessage().contains("Clock moved backwards")){ Thread.sleep(1); // 简单等待重试策略 return nextId(); // 尝试重新获取ID } throw e; } } } ``` 上述代码通过继承 `DefaultIdentifierGenerator` 并覆盖其方法来实现更健壮的行为[^2]。 #### 工作节点唯一性保障 另一个常见问题是多实例部署环境下工作节点编号重复分配给不同的服务进程,从而引发碰撞风险。确保每个应用实例拥有独一无二的工作节点ID非常重要。可以通过如下方式设定worker Id: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC main: allow-bean-definition-overriding: true mybatis-plus: global-config: db-config: id-type: ASSIGN_ID identifier-generator: com.example.CustomSnowflakeIdWorker # 注册自定义ID生成器 snowflake: worker-id: ${WORKER_ID} # 动态注入环境变量作为workderId ``` 这里展示了如何利用Spring Boot属性文件指定唯一的worker Id,并将其传递给自定义的雪花算法类[^4]。 此外,还应确认所使用的数据库表结构能够支持大数值类型的存储,以避免因数据类型不匹配而导致插入失败的问题。对于MySQL而言,建议采用UNSIGNED BIGINT字段用于保存这些较大的主键值[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值