Redis分布式锁--笔记

172 阅读2分钟

Redis分布式锁

「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战

使用场景

在同一个JVM内部,大家往往采用synchronized或者Lock的方式来解决多线程间的安全问题,但是在分布式架构下,在JVM之间,那么就需要一种更加高级的锁机制,来处理种跨JVM进程之间的线程安全问题,解决方案就是:使用分布式锁

image-20211130230401669.png

分布式锁一般有如下特征

  • 互斥性: 同一时刻只能有一个线程持有锁
  • 重入性: 同一节点上的同一个线程如果获取了锁之后能够再次获取锁
  • 锁超时:和J.U.C中的锁一样支持锁超时,防止死锁
  • 能够及时从阻塞状态中被唤醒

Redis分布式锁原理

Redis分布式锁机制,主要借助setnx和expire两个命令完成

  • setnx---当key不存在,将key设置为value,存在不做任何操作,返回0
  • expire---设置key过期时间

原理解析

  • key不存在时创建,并设置value和过期时间,返回值为1;成功获取到锁
  • 如key存在时直接返回0,抢锁失败
  • 持有锁的线程释放锁时,手动删除key;或者过期时间到,key自动删除,锁释放

Redis加锁问题

setnx成功

expire失败,如果没有收到释放,那么这个锁永远被占用,其他线程永远也抢不到锁

解决方法

  1. 使用set命令时,同时设置过期时间
  2. 使用lua脚本,将加锁的命令放在lua脚本中原子性的执行

加锁命令

调用SET key PX NX命令

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

锁过期问题

解决方法:

  1. 乐观锁方式,增加版本号
  2. watch dog自动延期