这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战
高并发情况下的数据库自增ID会出现重复情况,导致新增失败。
解决办法就是使用分布式ID
分布式ID的生成方式有以下几种
- UUID
- 数据库不同步长自增
- 雪花算法
- redis
- 滴滴出品(TinyID)
- 百度 (Uidgenerator)
- 美团(Leaf)
UUID
生成唯一ID,最简单的就是UUID,具有唯一性,但是结果太长了,保存在数据库中,会导致索引太大,消耗太大。
数据库不同步长自增ID
设置起始值和自增步长,就可以保证唯一ID是自增有序,而且还不会重复,缺点就是不利于扩容,增加维护成本。
- mysql 1 配置:
1 | sql复制代码set @@auto_increment_offset = 1; -- 起始值 |
- mysql 2 配置:
1 | sql复制代码set @@auto_increment_offset = 2; -- 起始值 |
雪花算法(Snowflake)
雪花算法(Snowflake)是twitter公司内部分布式项目采用的ID生成算法,理论上单机每秒400W+,最多每秒可以生成41亿+的ID
分段 | 作用 | 说明 |
---|---|---|
1bit | 保留 | — |
41bit | 时间戳,精确到毫秒 | 可以支持69年的跨度 |
5bit | DatacenterId | 可以最多支持32个节点 |
5bit | WorkerId | 可以最多支持32个节点 |
12bit | 毫秒内的计数 | 支持每个节点每毫秒产生4096个ID |
- 优点
- ID趋势递增
- 生成效率高,单机每秒400W+
- 支持线性扩充
- 稳定性高,不依赖DB等服务
- 缺点
- 依赖服务器时间,如果服务器时间发生回拨,可能导致生成重复ID
- 在单机上是递增的,但是由于涉及到分布式环境,每台机器上的时钟不可能完全同步,也许有时候也会出现不是全局递增的情况
Redis生成ID
Redis可以作为集中式ID生成器,数据库的表记录最后分配的ID也是集中式ID生成器。
目前使用的ID生成器结合了这两种,实现如下:
- redis累加器
1 | java复制代码public int getId() { |
- 数据库
1 | xml复制代码<select id="getLastId" resultType="java.lang.Integer"> |
参考
本文转载自: 掘金