Redis如何在并发下让自增key的值不超过某个固定的数?

发布于 2022-09-07 08:48:08 字数 749 浏览 21 评论 0

大致代码如下:

     func(id, ip){
         int countId = jedis.hget("count", id);
         int countIP = jedis.get("count", ip);
         if(countId >= 5 || countIP>=5){
             return;
         }
         ... //一些其他操作
         
         //再次判断,怕并发时被其他线程修改过
         int countId = jedis.hget("count", id);
         int countIP = jedis.get("count", ip);
         if(countId >= 5 || countIP>=5){
             doSomething();
             jedis.hincrBy("count", id, 1);
             jedis.hincrBy("count", ip, 1);
         }
     }
     

上述代码只是表达大致意思,因为显然在并发情况下会有问题

我的设想是,譬如做一个类似CAS的,casIncrBy("count", id, 1, 5), 这个原子操作对key值增1,如果>5则失败。然后判断是否失败,失败就不doSomething(),成功就doSomething().

如何达成?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

心作怪 2022-09-14 08:48:08

拿出来, 判断一下, 修改后发现大于5把数值改成5..

歌枕肩 2022-09-14 08:48:08

用Lua脚本。

eval "local curr = redis.call('get', KEYS[1]); if curr and tonumber(curr) >= tonumber(ARGV[2]) then return 0 else redis.call('incrby', KEYS[1], ARGV[1]); return curr + ARGV[1] end" 1 count 1 5
↘紸啶 2022-09-14 08:48:08

可以使用 @oraoto 的思路, 写个lua脚本.
如果lua脚本无法实现业务逻辑, 可以使用WATCH命令, 或者自己实现一个简单的锁, 锁住这个键.
可以参考Redis实战中《4.4 Redis事务》 和 《6.2分布式锁》

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文