首页 > 数据库 >基于redis的分布式锁中的setnx+expire非原子操作问题

基于redis的分布式锁中的setnx+expire非原子操作问题

时间:2022-11-11 11:25:06浏览次数:48  
标签:set seconds redis value expire key setnx milliseconds

基于redis的分布式锁, 性能和稳定性都非常好. 但是redis中setnx+expire是非原子操作, 除了用LUA脚本保证实现原子操作, 其实可以直接使用redis自带的set方法直接实现.

setnx+expire操作过程中, 如果expire无法执行, 会导致死锁

原生命令格式:

SET key value [EX seconds] [PX milliseconds] [NX|XX]
EX seconds : 将键的过期时间设置为 seconds 秒。 执行 SET key value EX seconds 的效果等同于执行 SETEX key seconds value 。
PX milliseconds : 将键的过期时间设置为 milliseconds 毫秒(千分之一秒)。 执行 SET key value PX milliseconds 的效果等同于执行 PSETEX key milliseconds value 。
NX : 只在键不存在时, 才对键进行设置操作。 执行 SET key value NX 的效果等同于执行 SETNX key value 。
XX : 只在键已经存在时, 才对键进行设置操作。

在php的redis扩展中提供的函数的定义是:

    /**
     * Set the string value in argument as value of the key.
     *
     * @since If you're using Redis >= 2.6.12, you can pass extended options as explained in example
     *
     * @param string       $key
     * @param string|mixed $value string if not used serializer
     * @param int|array    $timeout [optional] Calling setex() is preferred if you want a timeout.<br>
     * Since 2.6.12 it also supports different flags inside an array. Example ['NX', 'EX' => 60]<br>
     *  - EX seconds -- Set the specified expire time, in seconds.<br>
     *  - PX milliseconds -- Set the specified expire time, in milliseconds.<br>
     *  - PX milliseconds -- Set the specified expire time, in milliseconds.<br>
     *  - NX -- Only set the key if it does not already exist.<br>
     *  - XX -- Only set the key if it already exist.<br>
     * <pre>
     * // Simple key -> value set
     * $redis->set('key', 'value');
     *
     * // Will redirect, and actually make an SETEX call
     * $redis->set('key','value', 10);
     *
     * // Will set the key, if it doesn't exist, with a ttl of 10 seconds
     * $redis->set('key', 'value', ['nx', 'ex' => 10]);
     *
     * // Will set a key, if it does exist, with a ttl of 1000 miliseconds
     * $redis->set('key', 'value', ['xx', 'px' => 1000]);
     * </pre>
     *
     * @return bool TRUE if the command is successful
     *
     * @link     https://redis.io/commands/set
     */
    public function set($key, $value, $timeout = null)
    {
    }

$redis->set('key', 'value', ['nx', 'ex' => 10]) 表示当key不存在时, 设置key且过期时间为10秒.

$redis->set('key', 'value', ['nx', 'px' => 500]) 表示当key不存在时, 设置key且过期时间为500毫秒(即0.5秒).
————————————————
版权声明:本文为CSDN博主「aben_sky」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/aben_sky/article/details/121515122

标签:set,seconds,redis,value,expire,key,setnx,milliseconds
From: https://www.cnblogs.com/rxbook/p/16879969.html

相关文章

  • Redis笔记
     编译redis   将redis安装到制定目录下面/usr/local/redis   查看安装目录       启动redis服务器   前台启动redis后台启动将r......
  • Redis-cluster
    Redis3.0之后引入了RedisCluster集群方案,它用来解决分布式扩展的需求,同时也实现了高可用机制。 集群要求至少有3个master,每个master负载均衡负责读写,同时每个mast......
  • redission分布式redis锁使用
    publicvoidlock(Stringkey,List<Long>idx){if(CollectionUtils.isEmpty(idx)){return;}idx.forEach(id->{RLocklock=redissonCl......
  • Linux上安装Redis教程
    1、执行下面的命令下载redis: wgethttps://download.redis.io/releases/redis-6.2.6.tar.gz 2、解压redis:sudotar-zxvfredis-6.2.6.tar.gz3、删除压缩包......
  • CentOS7.9安装twemproxy,实现redis集群
    1、twemproxy下载下载地址:https://github.com/twitter/twemproxy.gitcd/www/servermkdirtwemproxycdtwemproxygitclonehttps://github.com/twitter/twemproxy.......
  • 【Redis】散列表(Hash)和列表(List)的运用和理解以及Hash和List应用场景对比详解
    一.散列表(hash)Redis哈希是字符串类型字段和值的映射表。哈希特别适合存储对象。Redis中的每个哈希可以存储232-1个键值对(超过40亿)。1.1基本操作RedisHset命令......
  • java使用redis存储时出现乱码问题
    今天用springboot做项目的时候,使用到了redis来做缓存。然后在存入redis的时候遇到了乱码的问题,这个问题是出现在序列化上,但是这个问题很好解决,晚上的方法也很多。因为......
  • Caused by: io.lettuce.core.RedisCommandTimeoutException: Command timed out after
    Causedby:io.lettuce.core.RedisCommandTimeoutException:Commandtimedoutafter10second(s)atio.lettuce.core.ExceptionFactory.createTimeoutExcepti......
  • Redis数据结构简介-Set
     Set结构存储值与结构读写能力:包含字符串的无序收集器(unorderedcollection),且数据不重复.添加,获取,移除单个元素;检查一个元素是否存在于集合中;......
  • Redis数据结构简介-Hash
     Hash结构存储值与结构读写能力:包含键值对的无序散列表添加,获取,移除单个键值对;获取所有键值对.存储类似HashMap的数据 hash是日常开发过......