【引言】
Redis的所有命令操作都是单线程的,本身提供像 incr 和 increby 这样的自增原子命令,所以能保证生成的 ID 肯定是唯一有序的,本篇博客将继续分享如何使用Redis实现全局性ID。
在上篇文章中,我们已经搭建好Spring Boot集成Redis的项目,接下来我们就基于该项目实现Redis生成全局性ID的方案。
【代码实现】
代码实现上只需要两个核心方法,一个方法是从redis中获取自增数据,另一个是拿到自增值后拼接为我们需要生成的唯一性ID。
获取自增数据代码如下:
/**
* 从redis中获取自增数据(redis保证自增是原子操作)
* @param key
* @return
*/
private long incrementNum(String key) {
RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
if (null == factory) {
log.error("Unable to connect to redis.");
}
RedisAtomicLong redisAtomicLong = new RedisAtomicLong(key, factory);
long increment = redisAtomicLong.incrementAndGet();
if (1 == increment) {
// 如果数据是初次设置,需要设置超时时间
redisAtomicLong.expire(1, TimeUnit.DAYS);
}
return increment;
}
根据规则生成对应单号方法:
/**
* 根据获取的自增数据,添加日期标识构造分布式全局唯一标识
* @param changeNumPrefix
* @return
*/
public String getNumFromRedis(String changeNumPrefix) {
String dateStr = LocalDate.now().format(dateTimeFormatter);
Long value = incrementNum(changeNumPrefix + dateStr);
return dateStr + StringUtils.leftPad(String.valueOf(value), 6, '0');
}
完整代码地址:基于Redis实现全局性ID生成测试
【总结】
基于Redis的实现方案优点在于不依赖于数据库,灵活方便,且性能优于数据库,缺点在于如果系统中没有Redis,还需要引入新的组件,增加系统复杂度,并且需要占用网络资源,性能要比本地生成慢,此外,也需要考虑到Redis出现宕机的情况。