剑指Offer(Redis)——实现分布式锁

孤街浪徒 提交于 2020-01-19 01:39:11

分布式锁是控制分布式系统或者不同系统之间共同访问共享资源的一种锁的实现,当不同主机共享了共享某一种资源时候往往通过互斥来除去彼此的干扰来保证一致性。

什么是分布式锁?分布式锁需要解决什么问题?

  • 互斥性

任意时刻只能有一个客户端获得锁

  • 安全性

锁只能被持有该锁的客户端删除,不能被其他客户端删除

  • 死锁

获得锁的客户端,出现意外宕机锁无法释放,资源也被永远锁住就出现了死锁

  • 容错性

客户端出现宕机,可以是实现高可用

Redis实现分布式锁

1、首先使用get < key >检查被上分布式锁的key,返回nil表示没有上锁,返回string是锁的名字
2、使用setnx < key > < lockname >设置锁住的key和锁的名字,被锁住返回0反之返回1
在这里插入图片描述
设置锁之后,给锁设置一个过期时间也是必须的,也不能一直锁着手动去释放,所以我们就需要设置所的过期时间:
给上面的锁设置失效时间,失效时间为2s,2s后检查锁的状态
在这里插入图片描述
设置锁之后发现锁的状态有了明显的转变,实现的伪代码如下:
在这里插入图片描述
但是存在一个问题,使用setnx设置锁之后,设置失效时间之前就失效了那么就会一直处于被锁的状态,其他线程无法获得锁,简单来说就是无法保证原子性。

Redis存在一种新的方法,将setnx和expire的功能结合在一起,开发出有过期时间的锁:

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

其中:
EX seconds:设置键的过期时间为second秒
PX milliseconds:设置键的过期时间为milliseconds毫秒
NX:只在键不存在的时候,才对键进行设置操作
XX:只在键已经存在的时候,才对键进行设置操作
set成功完成时候返回ok,否则返回nil。
在这里插入图片描述
实际开发中,伪代码操作如下,和Redis操作一样:
在这里插入图片描述

大量的key同时过期的注意事项

集中过期,因为清楚大量的key很耗时,会出现短暂的卡顿现象。

解决方案:设置key的过期时间时候给每个key加上一个随机值。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!