一个工作了7年的Java程序员,私信我关于分布式锁的问题。

一上来就两个灵魂拷问:

  • Redis锁超时怎么办?
  • Redis主从切换导致锁失效怎么办?

我说,别着急,这些都是小问题。

那么,关于“分布式锁的理解和实现”这个问题,我们看看普通人高手的回答。

普通人:

嗯,分布式锁,就是可以用来实现锁的分布性,嗯…

就是可以解决跨进程的应用对于共享资源访问的冲突问题。

可以用Redis来实现分布式锁。

高手:

分布式锁,是一种跨进程的跨机器节点的互斥锁,它可以用来保证多机器节点对于共享资源访问的排他性。

我觉得分布式锁和线程锁本质上是一样的,线程锁的生命周期是单进程多线程,分布式锁的声明周期是多进程多机器节点。

在本质上,他们都需要满足锁的几个重要特性:

  • 排他性,也就是说,同一时刻只能有一个节点去访问共享资源。
  • 可重入性,允许一个已经获得锁的进程,在没有释放锁之前再次重新获得锁。
  • 锁的获取、释放的方法
  • 锁的失效机制,避免死锁的问题

所以,我认为,只要能够满足这些特性的技术组件都能够实现分布式锁。

  1. 关系型数据库,可以使用唯一约束来实现锁的排他性,

    如果要针对某个方法加锁,就可以创建一个表包含方法名称字段,

    并且把方法名设置成唯一的约束。

    那抢占锁的逻辑就是:往表里面插入一条数据,如果已经有其他的线程获得了某个方法的锁,那这个时候插入数据会失败,从而保证了互斥性。

    这种方式虽然简单啊,但是要实现比较完整的分布式锁,还需要考虑重入性、锁失效机制、没抢占到锁的线程要实现阻塞等,就会比较麻烦。

  2. Redis,它里面提供了SETNX命令可以实现锁的排他性,当key不存在就返回1,存在就返回0。然后还可以用expire命令设置锁的失效时间,从而避免死锁问题。

    当然有可能存在锁过期了,但是业务逻辑还没执行完的情况。 所以这种情况,可以写一个定时任务对指定的key进行续期。

    Redisson这个开源组件,就提供了分布式锁的封装实现,并且也内置了一个Watch Dog机制来对key做续期。

    我认为Redis里面这种分布式锁设计已经能够解决99%的问题了,当然如果在Redis搭建了高可用集群的情况下出现主从切换导致key失效,这个问题也有可能造成

    多个线程抢占到同一个锁资源的情况,所以Redis官方也提供了一个RedLock的解决办法,但是实现会相对复杂一些。

  3. 在我看来,分布式锁应该是一个CP模型,而Redis是一个AP模型,所以在集群架构下由于数据的一致性问题导致极端情况下出现多个线程抢占到锁的情况很难避免。

    那么基于CP模型又能实现分布式锁特性的组件,我认为可以选择Zookeeper或者etcd,

    • 在数据一致性方面,zookeeper用到了zab协议来保证数据的一致性,etcd用到了raft算法来保证数据一致性。
    • 在锁的互斥方面,zookeeper可以基于有序节点再结合Watch机制实现互斥和唤醒,etcd可以基于Prefix机制和Watch实现互斥和唤醒。

以上就是我对于分布式锁的理解!

总结

我认为,回答这个问题的核心本质,还是在技术底层深度理解的基础上的思考。

可以从高手的回答中明显感受到,对于排它锁底层逻辑的理解是很深刻的,同时再技术的广度上也是有足够的积累。

所以在回答的时候,面试官可以去抓到求职者在回答这个问题的时候的技术关键点和技术思维。

我认为,当具备体系化的技术能力的时候,是很容易应对各种面试官的各种刁难的。

好的,本期的普通人VS高手面试系列就到这里结束了,喜欢的朋友记得点赞和收藏。

另外,有任何技术上的问题,职业发展有关的问题,都可以私信我,我会在第一时间回复。

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Mic带你学架构

如果本篇文章对您有帮助,还请帮忙点个关注和赞,您的坚持是我不断创作的动力。欢迎关注「跟着Mic学架构」公众号公众号获取更多技术干货!

【面试普通人VS高手系列】请说一下你对分布式锁的理解,以及分布式锁的实现的更多相关文章

  1. 【面试普通人VS高手系列】说说缓存雪崩和缓存穿透的理解,以及如何避免?

    听说10个人去互联网公司面试,有9个人会被问到缓存雪崩和缓存穿透的问题. 听说,这9个人里面,至少有8个人回答得不完整. 而这8个人里面,全都是在网上找的各种面试资料去应付的,并没有真正理解. 当然, ...

  2. 【面试普通人VS高手系列】Spring Boot中自动装配机制的原理

    最近一个粉丝说,他面试了4个公司,有三个公司问他:"Spring Boot 中自动装配机制的原理" 他回答了,感觉没回答错误,但是怎么就没给offer呢? 对于这个问题,看看普通人 ...

  3. 【面试普通人VS高手系列】死锁的发生原因和怎么避免

    一个去阿里面试的小伙伴私信我说:今天被一个死锁的问题难到了. 平常我都特意看了死锁这块的内容,但是回答的时候就想不起来. 这里可能存在一个误区,认为技术是要靠记的. 大家可以想想,平时写代码的时候,这 ...

  4. 【面试普通人VS高手系列】volatile关键字有什么用?它的实现原理是什么?

    一个工作了6年的Java程序员,在阿里二面,被问到"volatile"关键字. 然后,就没有然后了- 同样,另外一个去美团面试的工作4年的小伙伴,也被"volatile关 ...

  5. 【面试普通人VS高手系列】讲一下wait和notify这个为什么要在synchronized代码块中?

    一个工作七年的小伙伴,竟然不知道"wait"和"notify"为什么要在Synchronized代码块里面. 好吧,如果屏幕前的你也不知道,请在评论区打上&qu ...

  6. 【面试普通人VS高手系列】为什么要使用Spring 框架?

    一个工作了4年的小伙伴,他说他从线下培训就开始接触Spring,到现在已经快5年时间了. 从来没有想过,为什么要使用Spring 框架. 结果在面试的时候,竟然遇到一个这样的问题. 大脑一时间短路了, ...

  7. 【面试普通人VS高手系列】Spring中事务的传播行为有哪些?

    一个工作了2年的粉丝,私信了一个比较简单的问题. 说: "Spring中事务的传播行为有哪些?" 他说他能记得一些,但是在项目中基本上不需要配置,所以一下就忘记了. 结果导致面试被 ...

  8. 【面试普通人VS高手系列】说一说Mybatis里面的缓存机制

    一个工作了 5年的程序员,在私信里面不断向我诉苦. 他说,他用了Mybatis这么久,怎么滴也算是精通Mybatis了吧. 结果竟然在Mybatis这个面试题上翻车了! 真的好烦! 好吧,我们今天来看 ...

  9. 【面试普通人VS高手系列】谈谈你对AQS的理解

    AQS是AbstractQueuedSynchronizer的简称,是并发编程中比较核心的组件. 在很多大厂的面试中,面试官对于并发编程的考核要求相对较高,简单来说,如果你不懂并发编程,那么你很难通过 ...

随机推荐

  1. 如何进行Hibernate的性能优化?

    大体上,对于HIBERNATE性能调优的主要考虑点如下: l 数据库设计调整 l HQL优化 l API的正确使用(如根据不同的业务类型选用不同的集合及查询API) l 主配置参数(日志,查询缓存,f ...

  2. 使用SpringDataJdbc无法注册的情况

    当 EnableJdbcRepositories 注解无法注册Repository仓库的时候,你可以查看下 你的实体是否存在@Table注解,没有请加上,这样就能扫描到了 @Table("b ...

  3. Java 中 notify 和 notifyAll 有什么区别?

    notify() 方法不能唤醒某个具体的线程,所以只有一个线程在等待的时候它才有 用武之地.而 notifyAll()唤醒所有线程并允许他们争夺锁确保了至少有一个线程 能继续运行.

  4. python模块 | 随机数模块—random模块

    python随机数模块 random - 生成伪随机数,该模块实现了各种分布的伪随机数生成器. 对于整数,从范围中有统一的选择. 对于序列,存在随机元素的统一选择.用于生成列表的随机排列的函数.以及用 ...

  5. 原来 flexbox 是这么工作的

    Flexbox 是一种 CSS 布局机制,可以说是目前浏览器原生支持的最好.使用最广泛的布局机制了.本文通过一些例子来说明 Flexbox 布局的工作原理,可以让我们更好的使用 Flexbox. 与 ...

  6. call、apply和 bind的简单使用方法

    - call.apply:在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. J ...

  7. 主线程中的Looper.loop()为什么不会造成ANR

    引子: 正如我们所知,在android中如果主线程中进行耗时操作会引发ANR(Application Not Responding)异常. 造成ANR的原因一般有两种: 当前的事件没有机会得到处理(即 ...

  8. 使用 IDEA 创建 SpringBoot 项目(详细介绍)+ 源码案例实现

    使用 IDEA 创建 SpringBoot 项目 一.SpringBoot 案例实现源码 二.SpringBoot 相关配置 1. 快速创建 SpringBoot 项目 1.1 新建项目 1.2 填写 ...

  9. vscode代码格式化快捷键及保存时自动格式化

    一.实现vs code中代码格式化快捷键:[Shift]+[Alt]+ F 二.实现保存时自动代码格式化: 1)文件 ------.>[首选项]---------->[设置]: 2)搜索  ...

  10. Blazor组件自做八 : 使用JS隔离封装屏幕键盘kioskboard.js组件

    1. 运行截图 演示地址 2. 在文件夹wwwroot/lib,添加kioskboard子文件夹,添加kioskboards.js文件 2.1 常规操作,懒加载js库, export function ...