Redis分布式锁

使用Redis实现分布式锁主要需要解决以下几点问题:

  1. 安全属性(Safety property): 独享(相互排斥)。在任意一个时刻,只有一个客户端持有锁。
  2. 活性A(Liveness property A): 无死锁。即便持有锁的客户端崩溃(crashed)或者网络被分裂(gets partitioned),锁仍然可以被获取。
  3. 活性B(Liveness property B): 容错。 只要大部分Redis节点都活着,客户端就可以获取和释放锁.

(以上,来自Redis 官方文档)

实现:

目前我们所使用的Redis 在2.6.12版本之后,已经推出了非常官方的解决方案。

使用set命令就可以解决该问题。(我看现在网上还有很多帖子还在教大家使用什么setnx命令,用Lua脚本实现事务,很复杂。可能是帖子时间太久了,做法已经非常过时了。官方已经明确表达了,在之后的版本会逐渐弱化setnx,并且抛弃。)

下面我们来看一下Set命令的最新文档:

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

选项:

  • EX seconds – Set the specified expire time, in seconds. (设置键key的过期时间,单位时秒)
  • PX milliseconds – Set the specified expire time, in milliseconds. (设置键key的过期时间,单位时毫秒)
  • NX – Only set the key if it does not already exist. (只有键key不存在的时候才会设置key的值)
  • XX – Only set the key if it already exist. (只有键key存在的时候才会设置key的值)

返回值:

simple-string-reply:如果SET命令正常执行那么回返回OK,否则如果加了NX 或者 XX选项,但是没有设置条件。那么会返回nil。

Redis中文文档,Set命令的地址:http://www.redis.cn/commands/set.html

可以看出,Redis在2.6.12之后对Set方法进行了增强。已经完全支持,在插入时判断是否存在的同时,进行有效时间的设置。这样就完全解决了我们实现锁的独享(相互排斥),的同时保证了因为客户端崩溃(一直不会释放锁)引起的死锁。

下面我们举个例子看一下怎么使用这个命令:

127.0.0.1:0>set key value EX 1000 NX
OK

127.0.0.1:0>exists key
1

127.0.0.1:0>ttl key
981

127.0.0.1:0>set key value EX 1000 NX
NULL

127.0.0.1:0>ttl key
955

应用:

上面介绍的增强版set命令已经可以帮我们解决分布式锁的大部分问题了,但是如果我们自己去使用还是会面临几个问题。

  • 释放锁(自己的锁必须只有自己来释放。)
  • 失败时重试(其他客户端对锁的等待时间控制)
  • 活性争议(防止锁过期时,多个客户端争抢锁引发脑裂)
  • 性能,崩溃恢复和Redis同步(当redis 服务端发生崩溃时引发的问题)

针对以上的问题Redis官方也给我们提供了非常简单可靠的解决方案RedLock

Redis的RedLock官方文档:http://www.redis.cn/topics/distlock.html

Redis针对我们Java程序员也是非常友好的同时为我们提供了相应的解决方案Redisson

Redis的Redisson官方文档:https://github.com/redisson/redisson

Redis针对Spring框架的使用者也提供了相应的使用文档

Redis的Redisson在Spring框架中的使用文档:https://github.com/redisson/redisson/wiki/14.-Integration-with-frameworks#141-spring-framework

Redis针对我们使用Spring Boot框架的使用者也提供了对应的Spring Boot Starter

Redis的Redisson针对Spring Boot Starter的使用文档:https://github.com/redisson/redisson/tree/master/redisson-spring-boot-starter#spring-boot-starter

(Redis 在官方文档上已经解释的非常清楚了,如果各位客官还有不明白的地方,我会考虑再写一篇关于Redisson的实现原理的博客)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值