Redis怎么实现分布式锁
1个回答
展开全部
阿粉最近迷上了 Redis,为什么呢?感觉 Redis 确实功能很强大呀,一个基于内存的系统 Key-Value 存储的数据库,竟然有这么多的功能,而阿粉也要实实在在地把 Redis 来弄一下,毕竟面试的时候,Redis 可以说是一个非常不错的加分项。
为什么需要分布式锁?
目前很多的大型项目全部都是基于分布式的,而分布式场景中的数据一致性问题一直是一个不可忽视的问题,大家知道关于分布式的 CAP 理论么?
CAP 理论就是说任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance),最多只能同时满足两项。
而我们的系统最终满足的永远都是最终一致性,而这种最终一致性,有些时候有人会喜欢问关于分布式事务,而有些人则偏重在分布式锁上。
但是阿粉选择的就是使用缓存来实现分布式锁,也就是我们在项目中最经常使用的 Redis ,谈到 Redis,那真是可以用在太多地方了,比如说:
我们今天就来实现用 Redis 来实现分布式锁,并且要学会怎么使用。
1.准备使用 Jedis 的 jar 包,在项目中导入 jar 包。
jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); 这个加锁的姿势才是我们最需要了解的,不然你用的时候都不知道怎么使用。
key:加锁的键,实际上就是相当于一个唯一的标志位,不同的业务,你可以使用不同的标志位进行加锁。
requestId:这个东西实际上就是用来标识他是哪一个请求进行的加锁,因为在分布式锁中,我们要知道一件事,就是加锁的和解锁的,必须是同一个客户端才可以。
而且还有一种比较经典的就是 B 把 A 的锁给释放了,导致释放混乱,如果你不加相同的请求,A 线程处理业务,执行了加锁,锁的过期时间是5s, B线程尝试获取锁,如果 A 处理业务时间超过5s,这时候 A 就要开始释放锁,而B在这时候没有检测到这个锁,从而进行了加锁,这时候加锁的时候,A还没处理完对应业务,当他处理完了之后,再释放锁的话,要是就是直接把 B 刚加的锁释放了,要么就是压根都没办法释放锁。
SET_IF_NOT_EXIST:看字面意思,如果 key 不存在,我们进行Set操作,如果存在,啥都不干,也就不在进行加锁。
SET_WITH_EXPIRE_TIME:是否过期
expireTime:这是给 key 设置一个过期的时间,万一你这业务一直被锁着了,然后之后的业务想加锁,你直接给一直持有这个这个锁,不进行过期之后的释放,那岂不是要凉了。
上面的方法中 tryGetDistributedLock 这个方法也就是我们通常使用的加锁的方法。
大家看到这个 script 的时候,会感觉有点奇怪,实际上他就是一个 Lua 的脚本,而 Lua 脚本的意思也比较简单。
其实这时候就有些人说,直接 del 删除不行么?你试试你如果这么写的话,你们的领导会不会把你的腿给你打断。
这种不先判断锁的拥有者而直接解锁的方式,会导致任何客户端都可以随时进行解锁,也就是说,这锁就算不是我加的,我都能开,这怎么能行呢?
在这里给大家放一段使用的代码,比较简单,但是可以直接用到你们的项目当中
我们先把这个实现方式实现了,然后我们再来说说大家最不愿意看的理论知识,毕竟这理论知识是你面试的时候经常会被问到的。
分布式CAP理论:
加州大学伯克利分校的 Eric Brewer 教授在 ACM PODC 会议上提出 CAP 猜想。2年后,麻省理工学院的 Seth Gilbert 和 Nancy Lynch 从理论上证明了 CAP。之后,CAP 理论正式成为分布式计算领域的公认定理。
也就是说,在二十年前的时候,CAP 理论只是个猜想。结果两年之后被证实了,于是,大家在考虑分布式的时候,就有根据来想了,不再是空想了。
什么是分布式的 CAP 理论 ?
一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项
这个和(Atomicity)不太一样,因为之前看有些人说,在 CAP 理论中的 A 和数据库事务中的 A 是一样的,单词都不一样,那能一样么?
Availability :分布式中的 A 表示的是可用性,也就是说服务一直可用,而且是正常响应时间。
而你在搭建分布式系统的时候,要保证每个节点都是稳定的,不然你的可用性就没有得到相对应的保证,也谈不上是什么分布式了。只能称之为一个伪分布式。
Consistency: 一致性
也就是说你的更新操作成功并返回客户端完成后,所有节点在同一时间的数据完全一致,这个如果你在使用 Redis 做数据展示的时候,很多面试官都会问你,那你们是怎么保证数据库和缓存的一致性的呢?
毕竟你只是读取的话,没什么问题,但是设计到更新的时候,不管是先写数据库,再删除缓存;还是先删除缓存,再写库,都有可能出现数据不一致的情况。
所以如果你对这个很感兴趣,可以研究一下,比如说:
如果你能在面试的时候把这些都给面试官说清楚,至少感觉你应该能达到你自己的工资要求。
Partition tolerance:分区容错性
分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务。
其实在 CAP 理论当中,我们是没有办法同时满足一致性、可用性和分区容错性这三个特性,所以有所取舍就可以了。
关于使用 Redis 分布式锁,大家学会了么?
为什么需要分布式锁?
目前很多的大型项目全部都是基于分布式的,而分布式场景中的数据一致性问题一直是一个不可忽视的问题,大家知道关于分布式的 CAP 理论么?
CAP 理论就是说任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance),最多只能同时满足两项。
而我们的系统最终满足的永远都是最终一致性,而这种最终一致性,有些时候有人会喜欢问关于分布式事务,而有些人则偏重在分布式锁上。
但是阿粉选择的就是使用缓存来实现分布式锁,也就是我们在项目中最经常使用的 Redis ,谈到 Redis,那真是可以用在太多地方了,比如说:
我们今天就来实现用 Redis 来实现分布式锁,并且要学会怎么使用。
1.准备使用 Jedis 的 jar 包,在项目中导入 jar 包。
jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); 这个加锁的姿势才是我们最需要了解的,不然你用的时候都不知道怎么使用。
key:加锁的键,实际上就是相当于一个唯一的标志位,不同的业务,你可以使用不同的标志位进行加锁。
requestId:这个东西实际上就是用来标识他是哪一个请求进行的加锁,因为在分布式锁中,我们要知道一件事,就是加锁的和解锁的,必须是同一个客户端才可以。
而且还有一种比较经典的就是 B 把 A 的锁给释放了,导致释放混乱,如果你不加相同的请求,A 线程处理业务,执行了加锁,锁的过期时间是5s, B线程尝试获取锁,如果 A 处理业务时间超过5s,这时候 A 就要开始释放锁,而B在这时候没有检测到这个锁,从而进行了加锁,这时候加锁的时候,A还没处理完对应业务,当他处理完了之后,再释放锁的话,要是就是直接把 B 刚加的锁释放了,要么就是压根都没办法释放锁。
SET_IF_NOT_EXIST:看字面意思,如果 key 不存在,我们进行Set操作,如果存在,啥都不干,也就不在进行加锁。
SET_WITH_EXPIRE_TIME:是否过期
expireTime:这是给 key 设置一个过期的时间,万一你这业务一直被锁着了,然后之后的业务想加锁,你直接给一直持有这个这个锁,不进行过期之后的释放,那岂不是要凉了。
上面的方法中 tryGetDistributedLock 这个方法也就是我们通常使用的加锁的方法。
大家看到这个 script 的时候,会感觉有点奇怪,实际上他就是一个 Lua 的脚本,而 Lua 脚本的意思也比较简单。
其实这时候就有些人说,直接 del 删除不行么?你试试你如果这么写的话,你们的领导会不会把你的腿给你打断。
这种不先判断锁的拥有者而直接解锁的方式,会导致任何客户端都可以随时进行解锁,也就是说,这锁就算不是我加的,我都能开,这怎么能行呢?
在这里给大家放一段使用的代码,比较简单,但是可以直接用到你们的项目当中
我们先把这个实现方式实现了,然后我们再来说说大家最不愿意看的理论知识,毕竟这理论知识是你面试的时候经常会被问到的。
分布式CAP理论:
加州大学伯克利分校的 Eric Brewer 教授在 ACM PODC 会议上提出 CAP 猜想。2年后,麻省理工学院的 Seth Gilbert 和 Nancy Lynch 从理论上证明了 CAP。之后,CAP 理论正式成为分布式计算领域的公认定理。
也就是说,在二十年前的时候,CAP 理论只是个猜想。结果两年之后被证实了,于是,大家在考虑分布式的时候,就有根据来想了,不再是空想了。
什么是分布式的 CAP 理论 ?
一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项
这个和(Atomicity)不太一样,因为之前看有些人说,在 CAP 理论中的 A 和数据库事务中的 A 是一样的,单词都不一样,那能一样么?
Availability :分布式中的 A 表示的是可用性,也就是说服务一直可用,而且是正常响应时间。
而你在搭建分布式系统的时候,要保证每个节点都是稳定的,不然你的可用性就没有得到相对应的保证,也谈不上是什么分布式了。只能称之为一个伪分布式。
Consistency: 一致性
也就是说你的更新操作成功并返回客户端完成后,所有节点在同一时间的数据完全一致,这个如果你在使用 Redis 做数据展示的时候,很多面试官都会问你,那你们是怎么保证数据库和缓存的一致性的呢?
毕竟你只是读取的话,没什么问题,但是设计到更新的时候,不管是先写数据库,再删除缓存;还是先删除缓存,再写库,都有可能出现数据不一致的情况。
所以如果你对这个很感兴趣,可以研究一下,比如说:
如果你能在面试的时候把这些都给面试官说清楚,至少感觉你应该能达到你自己的工资要求。
Partition tolerance:分区容错性
分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务。
其实在 CAP 理论当中,我们是没有办法同时满足一致性、可用性和分区容错性这三个特性,所以有所取舍就可以了。
关于使用 Redis 分布式锁,大家学会了么?
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
力控科技
2024-08-19 广告
2024-08-19 广告
ForceSCADA是力控科技信创产品的重要组成部分,具备完全自主知识产权,支持部署在Linux桌面版、服务器版、嵌入式等系统架构下。使用ForceSCADA可以搭建创新性高、扩展性佳、融合度强的SCADA平台,进而构建高效、智能化的监控中...
点击进入详情页
本回答由力控科技提供
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询