一、全局唯一ID
(一)在用户抢购时,就会生成订单并保存到数据库中,而订单表如果使用自增ID就会存在以下几种情况:
- 自增ID规律性太强
- 受单表数据量的限制
(二)全局ID生成器,是一种在分布式系统下用来生成全局唯一ID的工具,一般要满足下列特性:
- 唯一性
- 高可用
- 高性能
- 递增性
- 安全性
(三)全局唯一ID生成策略
- UUID
- Redis自增
- snowflake算法
- 数据库自增
(四)Redis自增ID策略
- 每天一个key,方便统计订单量
- ID构造是 时间戳 + 计数器
(五)使用Redis进行全局唯一ID生成,采用HyperLog类型进行组合 64 位的全局ID
- 第一位为符号位,表示永远为正数
- 添加 31 bit 的时间戳
- 添加 32 bit 的序列号
(六)使用Reids创建全局ID生成器
@Component
public class RedisIdBuilder {
private static final long BEGIN_TIMESTAMP = 1687910400L;
private static final int SERIAL_BITS = 32;
private StringRedisTemplate stringRedisTemplate;
public RedisIdBuilder(StringRedisTemplate stringRedisTemplate){
this.stringRedisTemplate = stringRedisTemplate;
}
public long nextId(String keyPrefix){
//1、生成时间戳
LocalDateTime now = LocalDateTime.now();
long nowSecond = now.toEpochSecond(ZoneOffset.UTC);
long timestamp = nowSecond - BEGIN_TIMESTAMP;
//2、生成序列号
//获取当前日期,精确到天
String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
//自增长序列号
Long serial = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date);
//3、拼接并返回
return timestamp << SERIAL_BITS | serial;
}
}