redis setnx 过期时间_阿里面试官:你确定你用过 Redis 分布式锁吗?

686908932bef83eed890ffabb411773d.png

你有听说过 Redlock 吗?

别整些花里胡哨的,Redlock 全称 Redis Distributed Lock,即用 Redis 实现的分布式锁。

Redis 热身知识

Redis 命令参考:http://doc.redisfans.com/index.html

面试中经常听到说用 SETNX 做分布式锁,我们在 Redis 客户端里看看

setnx 是 SET if Not eXists (如果不存在,则 SET) 的简写。

1、 SETNX

72ba453df893777791da44fbb0b468b6.png

从图中,如果 key 不存在,返回 1,存在,返回 0;

2、SETEX

SETNX key seconds value

Redis setex 命令为指定的 key 设置值及其过期时间。如果 key 已经存在, SETEX 命令将会替换旧的值。

setex 是一个原子性操作

5a9ad9f657a546b34f49e04336a788f5.png

其中 ttl (Time To Live),命令以秒为单位返回 key 的剩余过期时间,负数表示已过期。

3、PSETEX

PSETEX key milliseconds value

这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。pttl 命令以毫秒为单位返回 key 的剩余过期时间,负数表示已过期。

9f71d35280918c5a015be914311b4bd4.png

注意:

从 Redis 2.6.12 版本开始, SET 命令的行为可以通过一系列参数来修改。

因为 SET 命令可以通过参数来实现和 SETNX 、 SETEX 和 PSETEX 三个命令的效果,所以将来的 Redis 版本可能会废弃并最终移除 SETNX 、 SETEX 和 PSETEX 这三个命令。

SET key value [EX seconds] [PX milliseconds] [NX|XX]

① EX second :设置键的过期时间为 second (秒)。 SET key value EX second 效果等同于 SETEX key second value 。

② PX millisecond :设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond 效果等同于 PSETEX key millisecond value 。

③ NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。

④ XX :只在键已经存在时,才对键进行设置操作。

4、推荐使用 SET NX PX 获取锁

SET key value NX PX 6000

61d2e7dc6dd0d6a677d8c1d4e6112799.png

我们在实际项目中,还会增加一个获取锁的时间,去循环获取锁。

330b1c2ac8727a121206077d07b72554.png

注意:

key : 资源名字,加锁对象的唯一标记。

value: 通常存储加锁方的唯一标记,如 “UUID+ThreadID”。是由客户端生成的一个随机字符串,相当于是客户端持有锁的标志。

先思考下,为什么 value 要设置为唯一标记???

5、采用 Lua 脚本来释放锁

8796f4008da86f2efbd10e43dcd94cc3.png
33950020d6a879d79426af7ba3dd53cc.png

Lua 脚本是原子性的,成功返回 1 ,失败返回 0;

KEYS [1] 的值为 key,ARGV [1] 的值为 value。原理就是先获取 lock 对应的 value 值,保证和客户端穿进去的 value 值相等,相等的时候才会执行 del 命令释放锁。

注意:

① 为什么 value 要设置为唯一标记???

如果不设置成唯一标记,那客户端 2 可能释放掉客户端 1 的锁;

② 为什么释放 lock 用 Lua 脚本?

释放 lock 经历的步骤:

① 获取 key 对应的值 value;

② 判断 value 是否和客户端生成的随机值一样;

③ 如果一样,执行 del 命令

这三步非原子性操作,如果不使用 Lua 脚本,由于锁有过期时间,会出现如下图的情况。

客户端 1 先获取锁,执行到了第 ② 步,但是卡住了,锁失效。

客户端 2 获取锁,执行任务中;

客户端 1 执行了 del 命令,会释放客户端 2 的锁。

e98621819dce0c2b1d4e0798f0907447.png

以上属于 Redis 面试中的热身问题,送分题啊,朋友们!

如果有不对的地方,欢迎评论留言指正,有话你就说啊。如果对你有帮助,转发点赞收藏一波,下节继续分析分布式锁中问题,关注 @Python大星 ,一个会点 Python 的 Java 程序猿。

@Python大星 | 文

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值