基于redis的分布式锁中的setnx+expire非原子操作问题
基于redis的分布式锁, 性能和稳定性都非常好. 但是redis中setnx+expire是非原子操作, 除了用LUA脚本保证实现原子操作, 其实可以直接使用red...
·
基于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秒).
更多推荐
已为社区贡献7条内容
所有评论(0)