redis的分布式锁

分布式锁是一种用在分布式系统中实现同步和互斥访问的机制。

1、分布式锁概念

满足分布式系统或者集群模式下,多进程可见 并且互斥的锁。

分布式锁的核心思想就是让分布式集群中的节点都适用同一把锁,只要大家使用的是同一把锁,就能锁住线程,让程序串行执行。

分布式锁需要满足的条件:

  1. 可见性:多个线程都能看到相同的结果 --- > 不是并发编程中的内存可见性,而是多个进程之间能够互相感知变化
  2. 互斥:分布式锁的基本条件,是程序串行执行
  3. 高可用
  4. 高性能
  5. 安全性

常见的分布式锁:

  1. mysql:mysql本身就带有锁机制,但是因为性能一般,所有不常用做分布式锁
  2. redis:利用setnx这种互斥命令就可以简单实现分布式锁
  3. zookeeper:利用节点的唯一性和有序性实现互斥。
2、redis实现分布式锁的核心思路

利用redis的set nx 方法,多个线程进入时,只有第一个线程能够 setnx key 成功,成功则说明他抢到了锁,那么就可以继续执行业务,执行完毕删除锁,没有成功的则等待一定时间重试。

使用set nx 加锁的时候,一定要注意加上过期时间,否则,一旦获得锁的进程宕机,那么锁就永远无法释放,其他进程也就没办法获取锁了。

3、业务处理时间较长会出现什么情况?

场景:

  1. 线程1获取锁,然后处理业务,但是因为业务处理时间较长,直到锁过期了还没处理完,此时线程2获取到了锁,然后处理线程2的业务
  2. 一段时间后,线程1处理完了,处理释放锁的逻辑,但是此时是线程2持有锁,他就把线程2的锁给释放了 --- 这就会产生问题

解决方法:

  1. 加长锁的过期时间,并添加一个子线程,每10s去确认当前持有锁的线程是否在线,如果在线,就将过期时间重设延长
  2. 给锁加一个唯一的UUID,保证每把锁的key是和自己的进程是绑定的

我们开发中,可以直接用Redisson来解决上述的问题,我们常说的watch dog就是上述所说的确认当前线程是否存活的子线程。

4、如果redis采用的是主从集群模式,会有什么样的问题?

因为redis采用的是AP模式,也就是保证高可用和高性能,而不是去保证高一致性,加锁时只会往master节点设置锁,并直接返回结果(此时如果master节点掉线,锁还没有同步给slave节点,而redis的选举机制会重新推选一个新的master,但是这个新的master没有同步到刚刚加的锁,此时就会发送线程不安全问题)

Redisson的解决方案: RedLock

RedLock的逻辑是,需要把锁加锁的逻辑同步到集群中的所有节点上(master和slave),如果大多数的redis节点(>n/2+1)成功获取到了锁,并且获取锁的总消耗时间没有超过锁的有效时间,才会被认为成功获取锁,否则认为获取锁失败,如果获取锁失败了,那么客户端应该立即向所有的redis节点发起释放锁的操作,用LUA脚本。

相关推荐
是垚不是土2 分钟前
基于Blackbox Exporter的网络服务黑盒监控体系实践
网络·数据库·安全·http·微服务·prometheus
青w韵4 分钟前
Claude 高级工具使用解析:从上下文优化到程序化调用的工程实践
数据库·windows
像风一样自由20207 分钟前
Ray 分布式训练的多智能体路径规划强化学习踩坑记录
分布式
lang201509289 分钟前
Kafka副本管理核心机制全解析
分布式·kafka·linq
Hello.Reader12 分钟前
Flink SQL DROP 语句安全删除 Catalog / Table / DB / View / Function / Model
数据库·sql·flink
luluoluoa16 分钟前
科研业绩SCI、EI、会议、CSCD、CSSCI、中文核心、普刊介绍
数据库
liuzhilongDBA18 分钟前
论文精读|DBAIOps
数据库·postgresql·dbaiops
木风小助理20 分钟前
MySQL 存储过程与函数:核心辨析与应用指南
服务器·数据库·microsoft
普通网友29 分钟前
更优雅的测试:Pytest框架入门
jvm·数据库·python