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

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容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
相关文章
|
8月前
|
设计模式 安全 Java
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
119 0
|
8月前
|
存储 分布式计算 Hadoop
Hadoop【基础知识 01】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)
【4月更文挑战第3天】Hadoop【基础知识 01】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)
269 3
|
2月前
|
存储 Dubbo Java
分布式 RPC 底层原理详解,看这篇就够了!
本文详解分布式RPC的底层原理与系统设计,大厂面试高频,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
分布式 RPC 底层原理详解,看这篇就够了!
|
1月前
|
机器学习/深度学习 存储 运维
分布式机器学习系统:设计原理、优化策略与实践经验
本文详细探讨了分布式机器学习系统的发展现状与挑战,重点分析了数据并行、模型并行等核心训练范式,以及参数服务器、优化器等关键组件的设计与实现。文章还深入讨论了混合精度训练、梯度累积、ZeRO优化器等高级特性,旨在提供一套全面的技术解决方案,以应对超大规模模型训练中的计算、存储及通信挑战。
84 4
|
3月前
|
分布式计算 Hadoop 网络安全
Hadoop-08-HDFS集群 基础知识 命令行上机实操 hadoop fs 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
Hadoop-08-HDFS集群 基础知识 命令行上机实操 hadoop fs 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
55 1
|
3月前
|
存储 机器学习/深度学习 缓存
Hadoop-07-HDFS集群 基础知识 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
Hadoop-07-HDFS集群 基础知识 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
71 1
|
8月前
|
存储 分布式计算 监控
Hadoop【基础知识 01+02】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
【4月更文挑战第3天】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
366 2
|
3月前
|
存储 缓存 数据处理
深度解析:Hologres分布式存储引擎设计原理及其优化策略
【10月更文挑战第9天】在大数据时代,数据的规模和复杂性不断增加,这对数据库系统提出了更高的要求。传统的单机数据库难以应对海量数据处理的需求,而分布式数据库通过水平扩展提供了更好的解决方案。阿里云推出的Hologres是一个实时交互式分析服务,它结合了OLAP(在线分析处理)与OLTP(在线事务处理)的优势,能够在大规模数据集上提供低延迟的数据查询能力。本文将深入探讨Hologres分布式存储引擎的设计原理,并介绍一些关键的优化策略。
191 0
|
4月前
|
网络协议 安全 Java
分布式(基础)-RMI的原理
分布式(基础)-RMI的原理
|
6月前
|
NoSQL Redis 数据库