redis实现分布式锁(redis实现分布式锁设计)

 2021-11-19 5:00    77  

和大家分享我的经验,如何用redis提供的一个简单接口,轻松实现redis分布式锁redis实现分布式锁。

redis实现分布式锁(redis实现分布式锁设计)

在开始之前redis实现分布式锁,我先简单介绍下redis的性能。

redis实现分布式锁(redis实现分布式锁设计)

高效的RedisRedis本身是单线程的,这样带来的好处是能够提高读写效率redis实现分布式锁。多线程通常来说会有上下文切换带来的时间损耗,而redis通过绑定单个CPU到某块内存,实现了上下文切换的最小开销,因此这种场景反而比多线程还要高效。

不安全的Redis但是,如果有不同的节点同时要对Redis中的同一个数据进行操作,由于是来自不同Redis服务器,就会发生线程不安全的情况。

举例有两个功能函数X和Y(也可以看做是两个服务器节点),二者功能相同,都要执行读取Redis中变量P,并且对其加一的操作。如果是线程安全的,那么X和Y分别执行完之后,P的值应该比原来增加2,但是由于函数XY互相独立,那就可能发生下面这种情况:

1 X读取P

2 Y读取P

3 X将P+1写回Redis

4 Y将P+1写回Redis

执行结束后,P的值却变成了P+1,而不是P+2。

这就是线程不安全导致的结果。

redis的分布式锁那么如何用Redis来避免上面的情况呢。

Redis对外开放了一个非常厉害的api,目前经常被大家用来做分布式锁,是绝对的线程安全,这个函数就是SET key field value加上NX参数。这个NX参数可是了不得,通常来说,set函数是不管field字段是否存在,只要写入成功就会返回1,但是如果增加了NX参数,那么如果field值在redis中已经存在,就会返回nil,否则才返回1。因此可以通过这个函数来执行加锁操作,如果返回值不为nil,则加锁成功,否则代表有其他线程在操作数据,当前请求需要等待。

不仅如此,为了避免死锁,SET还有一个参数为EX,即EX毫秒后,field会自动清空。

此外,还有PX,XX参数,具体含义见如下文档。

以上就是我在工作中总结的防止redis并发的方式,如果你有其他想法,欢迎在下方评论区与我沟通。

我是苏苏思量,来自BAT的java开发工程师,每天分享技术见闻,欢迎关注我,与我共同进步。

如何优雅地用Redis实现分布式锁?

首先明确分布式锁应该具备什么特性:获取锁的业务无论正常与否,都必须能释放锁,这样才能避免死锁;锁应该具有高可用性。

redis实现分布式锁(redis实现分布式锁设计)

我们来看看redis是怎么来实现锁的的。

redis实现分布式锁(redis实现分布式锁设计)

redis主要是通过setnx、get、getset、del命令来完成加锁,抢锁和释放锁的操作的,这里我用两个客户端来模拟下加锁的过程。下面有实际操作的截图。

redis实现分布式锁(redis实现分布式锁设计)

1、客户端1使用setnx获取到锁,并设置锁的当前时间。设置超时时间就是为了业务挂了,锁不能释放成为死锁。

redis实现分布式锁(redis实现分布式锁设计)

执行命令

redis实现分布式锁(redis实现分布式锁设计)

setnx lock 0

为了方便举例,我们假定锁的当前时间是从0秒开始的,超时时间为3秒。如果结果返回为1,表明加锁成功,可以执行业务逻辑了。

2、当第一秒钟客户端2使用setnx获取锁,执行命令

setnx lock 1

返回值为0,则加锁失败。

3、客户端2接收到加锁时间的回应后,会去查看锁是否超时。执行命令

get lock

返回值为加锁的时间,假设现在时间已经到第4秒了,客户端会使用返回的时间0加上超时时间3小于当前时间4,锁已经超时了。

4、客户端2使用getset命令去获取锁。

getset lock 4

这时候返回的是前一次加锁的时间,如果这个时间是0,证明加锁成功,因为和前一次get的值相同。如果不同,说明锁已经被别人抢占了,加锁失败,继续重复步骤3和4。

5、业务执行完成后,判断下锁是否超时,没有超时,不用管了。如果没有超时,调用del命令释放锁即可。

redis存在的问题

1、redis如果是单机的话是有单点问题的,不满足高可用性。redis集群因为是ap模型,是不能保证一致性的,官方提供了redlock算法来解决这个问题,但是至少需要3个master-slave节点才能完成,成本也较大。redlock相当于是来实现一致性协议的。

2、锁的超时时间设定问题,太长太短都不合适,太长了如果服务挂掉了会一直阻塞业务,太短了有可能业务还没执行完成就释放了。当然可以用官方提供redisson解决。

可以关注我,我在文章里面还分享了zk,etcd怎么实现分布式锁的。

本文标签:实现分布式优雅

原文链接:https://www.xgfox.com/jsyd/34590.html

本文版权:如无特别标注,本站文章均为原创。