Redis进阶(七):分布式锁

在分布式系统下,涉及到多个节点访问同一个公共资源的情况,此时需要通过 锁 进行互斥控制:避免出现 线程安全问题。

1.分布式锁的基本实现

超卖问题:

解决:

采用redis实现分布式锁

可用采取:在购票的时候,操作过程中需要先加锁。在redis上设置一个key - value,完成上述买票操作,再把key - value 删掉。如果发现key - value 存在,就加锁失败,无法进行购票

上述可用保证,第一个服务器执行(查询 - 更新)过程中,第二个服务器不会执行 (查询)操作

具体实现:

redis中的setnx命令(不存在就设置进去,当前key值存在就失败)解锁使用del

考虑一下特殊情况:

某个服务器加锁成功后,在执行后续逻辑的过程中,程序崩溃了,没有执行到解锁操作?

不可以采取finally:这种做法只是针对进程内的锁有用,针对分布式锁无效,比如说服务器直接掉电,进程异常终止,后面的del逻辑都走不到~

还可以使用过期时间来实现~

给set的key设置一个过期时间,时间到了key自动被删去了。

可以使用 set ex nx

异常情况:

这个时候还有一个问题,服务器1给redis上锁,服务器2给解锁了,会引起超卖问题

为了解决上述问题,就需要加入校验机制

1、给服务器编号,每个服务器有自己的身份标识

2、进行加锁的时候,设置key-value。key 对应着要针对哪一个资源进行加锁 ~,value 就可以存储刚才服务器的编号~~这样可以表示出,这个锁是哪一个服务器加上的。

因此后续解锁的时候,就可以进行校验了。

1、解锁的时候,先查询一下这个锁对应的服务器编号,然后判定一下这个编号 是否就是 当前执行的解锁的服务器编号。

2、如果是 ,才去执行del,如果不是,则失败

问题:解锁时,查询判定和del是非原子操作

一个服务器内部,这是俩个行为,会出现线程安全问题,可以使用lua脚本实现原子性

但上述还有问题:设置过期时间后,仍然存在一定的可能性,任务没执行完,key先过期了,导致锁提前失效。也就是过期时间的续约问题

这样负责动态续约 专门独立出来的 线程 叫 看门狗

高可用

如果使用redis作为分布式锁,还需要考虑redis挂了的情况,因此要想保证高可用需要一套预案去保证高可用。

搞几个哨兵节点

redlock算法

简而言之:冗余

具体展现为:

相关推荐
勘察加熊人18 分钟前
fastapi房产销售系统
数据库·lua·fastapi
m0_7482546636 分钟前
MySQL和SQL server的区别
数据库·mysql
补三补四38 分钟前
Yashan DB 实例
数据库·oracle·dba
morris1311 小时前
【redis】布隆过滤器的Java实现
java·redis·布隆过滤器
椰椰椰耶1 小时前
【redis】全局命令set、get、keys
数据库·redis·缓存
月落星还在1 小时前
Redis 内存淘汰策略深度解析
数据库·redis·缓存
五行星辰1 小时前
Java链接redis
java·开发语言·redis
左灯右行的爱情1 小时前
Redis- 切片集群
数据库·redis·缓存
LKAI.1 小时前
MongoDB用户管理和复制组
linux·数据库·mongodb
周小闯2 小时前
Easyliev在线视频分享平台项目总结——SpringBoot、Mybatis、Redis、ElasticSearch、FFmpeg
spring boot·redis·mybatis