1.概要
之前的流水号实现是使用的 redis分布式锁,加数据递增的方式实现的。这种方式有什么问题呢。
分布式锁,对于在系统竞争激烈的情况下,会导致系统串行执行。另外本身数据库执行的效率也不高。
2.解决办法
redis 是一个单线执行的缓存服务。因此我们可以使用 redis 执行 lua 脚本。执行lua 脚本的时候,由于是单线程的,那么使用脚本并发的安全性是可以保证的。
下面就是相关的代码:
private Long getNo(String key,Integer initVal,Short step,Integer timeout){
DefaultRedisScript<Long> redisScript= new DefaultRedisScript<>();
//setex (key,timeout,val)
String script="if(redis.call('exists',KEYS[1])==0) then redis.call('setex',KEYS[1], tonumber(KEYS[4]), tonumber(KEYS[2])) else redis.call('incrby',KEYS[1],tonumber(KEYS[3])) end return tonumber(redis.call('get',KEYS[1]))";
redisScript.setScriptText(script);
List list=new ArrayList<>();
//键
list.add(key);
//初始值
list.add(initVal.toString());
//步长
list.add(step.toString());
//超时时间
list.add(timeout.toString());
redisScript.setResultType(Long.class);
Long rtn=(Long) redisTemplate.execute(redisScript,list);
return rtn;
}
其中 脚本中的KEYS ,表示为系统的参数。
lua 脚本的下标,是从1 开始的。
3. RESIS需要配置持久化
另外我们需要保证redis 的存储。
我们可以使用AOF模式
修改redis配置文件
//启动AOf
appendonly yes
//每秒同步
appendfsync everysec
文档更新时间: 2022-06-04 17:57 作者:zyg