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脚本。

相关推荐
_oP_i27 分钟前
Pinpoint 是一个开源的分布式追踪系统
java·分布式·开源
mmsx30 分钟前
android sqlite 数据库简单封装示例(java)
android·java·数据库
zpjing~.~2 小时前
Mongo 分页判断是否有下一页
数据库
2401_857600952 小时前
技术与教育的融合:构建现代成绩管理系统
数据库·oracle
秋恬意2 小时前
Mybatis能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别
java·数据库·mybatis
潇湘秦2 小时前
一文了解Oracle数据库如何连接(1)
数据库·oracle
雅冰石2 小时前
oracle怎样使用logmnr恢复误删除的数据
数据库·oracle
web前端神器2 小时前
mongodb给不同的库设置不同的密码进行连接
数据库·mongodb
从以前2 小时前
Berlandesk 注册系统算法实现与解析
数据库·oracle
Muko_0x7d22 小时前
Mongodb
数据库·mongodb