四时宝库

程序员的知识宝库

阿里面试官:这只是 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

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

2、SETEX

SETNX key seconds value

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

setex 是一个原子性操作

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

3、PSETEX

PSETEX key milliseconds value

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

注意:

从 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

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

注意:

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

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

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

5、采用 Lua 脚本来释放锁

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 面试中的热身问题,送分题啊,朋友们!

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

@Python大星 | 文

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接