Redis SET 命令
语法
1 | SET key value [NX | XX] [GET] [EX seconds | PX milliseconds | |
可用版本
≥ 1.0.0
时间复杂度
$O(1)$
ACL类别
@write
, @string
, @slow
设置 key
保存字符串类型的 value
。如果 key
已经持有一个值,它将被覆盖,不管它是什么类型。在成功的 SET
操作中,任何先前与 key
相关的生存时间都会被丢弃。
选项
SET 命令支持以下选项:
- EX seconds — 设置指定的过期时间,单位为秒。
- PX milliseconds — 设置指定的过期时间,单位是毫秒。
- EXAT timestamp-seconds — 设置指定的 Unix 时间,key 将在该时间过期,单位是秒。
- PXAT timestamp-milliseconds — 设置指定的 Unix 时间,以毫秒为单位,key 将在该时间过期。
- NX — 只有在 key 不存在的情况下才会设置它。
- XX — 只设置已经存在的 key。
- KEEPTTL — 保留与 key 相关的生存时间。
- GET — 返回存储在 key 的旧字符串,如果 key 不存在,则返回
nil
。如果存储在键上的值不是字符串,将返回一个错误,并中止SET
操作。
注意:由于 SET
命令选项可以取代 SETNX
、SETEX
、PSETEX
、GETSET
,因此在 Redis 的未来版本中,这些命令有可能被废弃,并最终被删除。
返回值
返回简单的字符串:如果 SET
被正确执行,则返回 OK。
返回 Null:(nil)如果 SET
操作没有被执行,因为用户指定了 NX
或 XX
选项,但条件没有被满足。
如果命令是用 GET
选项发出的,上述情况不适用。相反,它的返回如下,不管 SET
是否真的被执行:
返回批量字符串:存储在 key
的旧字符串值。
返回 Null:(nil)如果键不存在。
示例 1
1 | redis> SET js "Rain rain" |
模式
注意:不鼓励使用该模式,推荐使用 Redlock 算法,该算法只是实现起来更复杂一点,但能提供更好的保证和容错性。
借助 Redis 实现锁系统的一个简单方法是使用 SET resource-name anystring NX EX max-lock-time
命令。
如果上述命令返回 OK,客户端可以获得锁(如果命令返回 Nil,则在一段时间后重试),而移除锁只需使用 DEL
命令。
在过期时间到达后,该锁将被自动释放。
可以通过修改解锁模式来使这个系统更加强大,具体如下:
- 不要设置一个固定的字符串,而是设置一个不可猜测的大的随机字符串,称为 token。
- 与其用
DEL
释放锁,不如发送一个脚本,只有在值匹配的情况下才删除钥匙。
这就避免了客户端在过期后试图释放锁,删除由另一个后来获得锁的客户端创建的密钥。
释放锁的脚本内容类似于以下:
1 | if redis.call("get",KEYS[1]) == ARGV[1] |
该脚本应该用 EVAL ...script... 1 resource-name token-value
来调用。
历史记录
- 从 Redis 2.6.12 版本开始:增加了
EX
、PX
、NX
和XX
选项。 - 从 Redis 6.0.0 版本开始:增加了
KEEPTTL
选项。 - 从 Redis 6.2.0 版本开始:增加了
GET
、EXAT
和PXAT
选项。 - 从 Redis 7.0.0 版本开始:允许
NX
和GET
选项一起使用。
(END)