生成全局唯一 ID
- 全局唯一 ID 需要满足以下要求:
- 唯一性:在分布式环境中,要全局唯一
- 高可用:在高并发情况下保证可用性
- 高性能:在高并发情况下生成 ID 的速度必须要快,不能花费太长时间
- 递增性:要确保整体递增的,以便于数据库创建索引
- 安全性:ID 的规律性不能太明显,以免信息泄露
从上面的要求可以看出,全局 ID 生成器的条件还是比较苛刻的,而 Redis 恰巧可以满足以上要求。
Redis 本身就是就是以性能著称,因此完全符合高性能的要求,其次使用 Redis 的 incr 命令可以保证递增性,配合相应的分布式 ID 生成算法便可以实现唯一性和安全性,Redis 可以通过哨兵、主从等集群方案来保证可用性。因此 Redis 是一个不错的选择。
下面我们就写一个简单的示例,来让大家感受一下,实际工作中大家可以根据需要进行调整:
[code]@Componentpublic class IDUtil{ //开始时间戳(单位:秒) 2000-01-01 00:00:00 private static final long START_TIMESTAMP = 946656000L; //Spring Data Redis 提供的 Redis 操作模板 @Resource private StringRedisTemplate stringRedisTemplate; /** * 获取 ID 格式:时间戳+序列号 * @param keyPrefix Redis 序列号前缀 * @return 生成的 ID */ public long getNextId(String keyPrefix){ //获取当前时间戳 LocalDateTime now = LocalDateTime.now(); long nowTimestamp = now.toEpochSecond(ZoneOffset.UTC); //获取 ID 时间戳 long timestamp = nowSecond - START_TIMESTAMP; //获取当前日期 String date = now.format(DateTimeFormatter.ofPattern("yyyyMMdd")); //生成 key String key = "incr:" + keyPrefix + ":" + date; //获取序列号 long count = stringRedisTemplate.opsForValue().increment(key); //生成 ID 并返回 return timestamp |