前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分布式锁原理没搞懂,错失大厂offer

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

作者头像
灬沙师弟
发布2023-03-07 09:26:58
2060
发布2023-03-07 09:26:58
举报
文章被收录于专栏:Java面试教程

应用程序可支持多节点,集群运行,多个节点分别在不同的机器运行,访问共享资源,为了防止并发问题,数据不一致,所以需要才用分布式锁来保证数据的安全。今天我们来讨论一下使用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来解决,但是性能很低,如果不是必须要强保证数据的一致性,不推荐使用,使用上面方案就足够了。

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-01-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java面试教程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.简单设置key来加锁
  • 二. 给key加上超时时间
  • 三. 给key的value设置特定值
  • 四. 给key自动续期
  • 五.其他
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档