分布式锁-Redis

298 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

分布式锁

分布式锁的定义

分布式锁是控制分布式应用之间同时访问共享资源的的一种方式。

分布式锁应该具有哪些特征

  • 互斥性

在任意时刻,只有一个客户端持有该锁。

  • 不死锁

分布式锁本质是一个租借锁,如果A客户端获得锁后出现异常(如宕机),锁能够在一段时间后自动释放,资源不会被锁死,允许其他客户端获取该锁。

  • 一致性

当业务对互斥性的要求特别高。集群状态下,需要锁的服务端(如Redis),需要在master宕机后,replica成为master后,锁需要切换到新的master后保持原状态。

分布式锁比较常见的实现

  • zookeeper
  • 基于数据库实现
  • Redis

今天具体聊聊基于Redis实现的分布式锁

Redis实现分布式锁

实现

  • 加锁命令:SET key value NX EX 5(单位:秒) ,当key不存在时,对key进行设置操作并返回成功,否则返回失败。
  • 解锁命令:需要先判断是否是当前线程持有的锁。
if redis.call("get", KEYS[1]) == ARGV[1] then 

    return redis.call("del", KEYS[1]) 

else 

    return 0 

end 
  • 上述set命令中加了expire超时时间,到期自动释放锁方式死锁。这样会存在一个问题,当任务还没有执行完,就到了超时时间,然后锁被自动释放,这时候就需要对锁的超时时间进行一个续期(renew);
if redis.call("get",KEYS[1]) == ARGV[1] then 

    return redis.call("expire",KEYS[1], ARGV[2]) 
    
else 

    return 0 

end 

以下是客户端中加锁解锁的实现方式

image.png 客户端示例都放出来了,是不是很体贴

tempImage1632582127804.gif

一致性

  • 单机版:redis挂了锁就没了,基本无救;

  • 集群版:

    • 可以提高集群可用性
    • 官方推荐使用红锁
    • 使用wait命令

总结

今天简单讲了下基于redis实现分布式锁的方法,后续会将基于java的伪代码更新至本文章。