redis 锁 set nx 的顺序影响功能实现是什么原因
在实现防止重复提交功能时,采用 redis 锁来实现,写好了一版之后本地测试正常,但是放到线上发现还是有重复的内容
通过在网上搜索之后发现代码的不同之处进行修改,已成功修复问题,但是原理没看懂,测试代码如下,忽略未实现释放的逻辑
// 有问题的代码
$rs = Redis::set($key, $value, 'nx', 'ex', 3);
if (!$rs) {
return response()->json([], 204);
}
// 有效的代码
$rs = Redis::set($key, $value, 'ex', 3, 'nx');
if (!$rs) {
return response()->json([], 204);
}
可以看到唯一不同的地方就是nx的位置,问题是我本地测试第一种也是可行的
另线上环境采用负载均衡,部署了多个实例
本地通过使用 redis-cli monitor 监控运行的命令,发现最终运行的语句也只有顺序的不同,然后复制语句在线上的 redis-cli 中运行,也是正确的结果
线上 redis 版本为阿里云的 5.0.5
不知道大家有没有同样的问题,出现问题的原因有没有人能分析一下
可以直接使用
\Illuminate\Support\Facades\Cache::driver('reids')->lock($key, $value);
更方便处理缓存系统《Laravel 9 中文文档》
看 Redis::set 的源码啊
$rs = Redis::set($key, $value, 'ex', 3, 'nx'); 是标准写法,任何情况都不会出错
可以手动在线上redis-cli执行第一种的写法试试,应该是你本地和线上redis版本不一样导致的
doc.redisfans.com/string/set.html
如果你本地测试是用单个浏览器的
get
请求测试,那是没有并发问题的,加不加分布式锁都不会有并发问题