阿里面试官:这只是 Redis 分布式锁中的“热身”问题

阿里面试官:这只是 Redis 分布式锁中的“热身”问题

你有听说过 Redlock 吗?

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

Redis 热身知识

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


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

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

1、 SETNX

阿里面试官:这只是 Redis 分布式锁中的“热身”问题

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

2、SETEX

SETNX key seconds value

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

setex 是一个原子性操作

阿里面试官:这只是 Redis 分布式锁中的“热身”问题

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

3、PSETEX

PSETEX key milliseconds value

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

阿里面试官:这只是 Redis 分布式锁中的“热身”问题

注意:

从 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

阿里面试官:这只是 Redis 分布式锁中的“热身”问题

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

阿里面试官:这只是 Redis 分布式锁中的“热身”问题

注意:

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

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

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

5、采用 Lua 脚本来释放锁

阿里面试官:这只是 Redis 分布式锁中的“热身”问题

阿里面试官:这只是 Redis 分布式锁中的“热身”问题

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 的锁。

阿里面试官:这只是 Redis 分布式锁中的“热身”问题

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

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

@Python大星 | 文


分享到:


相關文章: