分布式锁原理没搞懂,错失大厂offer

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 分布式锁原理没搞懂,错失大厂offer

应用程序可支持多节点,集群运行,多个节点分别在不同的机器运行,访问共享资源,为了防止并发问题,数据不一致,所以需要才用分布式锁来保证数据的安全。今天我们来讨论一下使用redis怎么实现分布式锁。

一.简单设置key来加锁

**setnx : **对应的key为空,就设置值,并返回1 ;对应的key非空,不设置值,并返回0

举例说明:

A节点:setnx lock_key  1 ,返回1 ,A节点获取分布式锁成功

B节点:setnx lock_key  1 ,返回0,B节点获取分布式锁失败,可重试不断获取

A节点获取到分布式锁后执行业务逻辑,执行完后,执行 del lock_key  操作,把锁释放。

这个方案是否简单完美呢?简单是很简单,但是并不完美,如果A节点在执行业务逻辑时或者是执行del操作失败了,那锁是不是就没有释放,其他节点就永远没有办法获取锁了。

二. 给key加上超时时间

A节点获取到分布式锁后,通过EXPIER命令给key设置过期时间,但是这样也会有方案一出现的问题,如果A节点给key设置过期时间之前发生了宕机了,因为获取锁和给锁设置过期时间不是原子操作导致的。

那redis有没有命令支持设置key的同时设置过期时间呢?

有的:set lock_key 1 ex 10 nx ,代表 key不存在时设置1,并设置过期时间为10s,成功返回OK,否则返回NIL

给key设置了过期时间后,及时A节点没有释放锁的情况,等待过期时间,锁也会被redis当做过期key释放掉。这要求我们设置的过期时间要比执行业务的时间要长。

这个方案还有问题吗?我们想一下,如果A节点执行业务逻辑的时间太长,超过了锁的过期时间,锁就会被释放;B节点会获取到,等待A节点执行完,会释放锁,这时候会把B节点持有的锁释放掉,这个是不正确的,怎么防止这个问题呢?

三. 给key的value设置特定值

A节点设置value的时候,设置成UUID, 解锁的时候,先获取key值,如果相等才解锁,如果不相同就不解锁;

获取key值和解锁可以使用lua脚本实现,redis是支持执行lua脚本的

加锁:

set lock_key UUID ex 10 nx

解锁:

if redis.call('EXISTS', UUID) == _1 _then

  redis.call('DEL', UUID)

这个方案可以防止A节点解锁时,把其他节点的锁释放了,现在还有其他问题吗?给key设置的过期时间其实是不好把握的,我们并不确定业务执行所需要的时间,所以还是会出现锁过期了,业务还是执行的情况,这时候就会出现多个节点同时执行共享资源代码的情况,这个怎么解决呢?

四. 给key自动续期

A节点获取到锁后,启动一个线程,定时检查,锁是否还是属于A节点的(如果锁对应的key值等于A节点设置的值),就延长过期时间,定时检查时间要小于过期时间

这样就可以确保及时超过了设置的过期时间,还没执行完业务逻辑,也不会导致锁过期被其他节点获取的情况了。

这个其实是有现成的框架(redisson)已经实现好了,我们直接就可以拿来使用了,大家如果有需求可以直接使用,它底层是通过一个叫看门狗的线程来实现续期的,大家感兴趣也可以去看看源码。

五.其他

到目前为止,大家觉得还会有其他问题吗?

如果redis是集群或者是哨兵部署的话,还是有可能存在多个节点获取到锁的情况

A节点获取到锁,这时候发生了主从切换,A节点的锁在新的主节点还没同步过来,所以还不存在,这时候其他节点就可以获取锁。

这时候需要使用redlock来解决,但是性能很低,如果不是必须要强保证数据的一致性,不推荐使用,使用上面方案就足够了。

今天的分享就到此结束,如果觉得本文不错的还请伙伴们帮忙点赞转发,欢迎持续关注我们!

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
NoSQL Java 测试技术
字节二面:Spring Boot Redis 可重入分布式锁实现原理?
字节二面:Spring Boot Redis 可重入分布式锁实现原理?
163 1
|
3月前
|
监控 Dubbo Java
深入理解Zookeeper系列-2.Zookeeper基本使用和分布式锁原理
深入理解Zookeeper系列-2.Zookeeper基本使用和分布式锁原理
61 0
|
4月前
|
NoSQL 关系型数据库 MySQL
分布式锁的原理解析与实现工具介绍
分布式锁的原理解析与实现工具介绍
37 1
|
2月前
|
存储 数据采集 监控
SkyWalking全景解析:从原理到实现的分布式追踪之旅
SkyWalking全景解析:从原理到实现的分布式追踪之旅
366 1
|
29天前
|
设计模式 安全 Java
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
33 0
|
3月前
|
存储 安全 JavaScript
【分布式技术专题】「授权认证体系」深度解析OAuth2.0协议的原理和流程框架实现指南(授权流程和模式)
在传统的客户端-服务器身份验证模式中,客户端请求服务器上访问受限的资源(受保护的资源)时,需要使用资源所有者的凭据在服务器上进行身份验证。资源所有者为了给第三方应用提供受限资源的访问权限,需要与第三方共享它的凭据。这就导致一些问题和局限:
373 2
【分布式技术专题】「授权认证体系」深度解析OAuth2.0协议的原理和流程框架实现指南(授权流程和模式)
|
3月前
|
NoSQL 中间件 API
分布式锁【数据库乐观锁实现的分布式锁、Zookeeper分布式锁原理、Redis实现的分布式锁】(三)-全面详解(学习总结---从入门到深化)(下)
分布式锁【数据库乐观锁实现的分布式锁、Zookeeper分布式锁原理、Redis实现的分布式锁】(三)-全面详解(学习总结---从入门到深化)
82 2
|
3月前
|
NoSQL Java API
分布式锁【数据库乐观锁实现的分布式锁、Zookeeper分布式锁原理、Redis实现的分布式锁】(三)-全面详解(学习总结---从入门到深化)(上)
分布式锁【数据库乐观锁实现的分布式锁、Zookeeper分布式锁原理、Redis实现的分布式锁】(三)-全面详解(学习总结---从入门到深化)
74 0
|
4天前
|
存储 NoSQL 分布式数据库
【Flink】Flink分布式快照的原理是什么?
【4月更文挑战第21天】【Flink】Flink分布式快照的原理是什么?
|
29天前
|
缓存 算法 关系型数据库
深度思考:雪花算法snowflake分布式id生成原理详解
雪花算法snowflake是一种优秀的分布式ID生成方案,其优点突出:它能生成全局唯一且递增的ID,确保了数据的一致性和准确性;同时,该算法灵活性强,可自定义各部分bit位,满足不同业务场景的需求;此外,雪花算法生成ID的速度快,效率高,能有效应对高并发场景,是分布式系统中不可或缺的组件。
深度思考:雪花算法snowflake分布式id生成原理详解

热门文章

最新文章