关于分布式锁

2019-03-06 00:49:27 +08:00
 wyoumuw
这几天为了准备面试在看一些以前不算了解的知识,然后就看到了分布式锁。
那我想想锁应该有几个特性吧
1.能保证只有一个线程持有锁
2.要重入才能算好锁
3.解锁的必然是用锁锁了的线程

ps:如果有不对的指出一下 xiexie

那回到主题,现在 redisson 和很多博客上的锁都不会跨服务的,比如我们曾经 Aservice-》 Bservice 的时候 Aservice 使用了锁,Bservice 也使用了同一把锁,这就出了个问题了因为是一把锁,如果没有重入的特性的话将会发生死锁。为什么现在都没这样的实现呢?是因为业务场景是不会出现跨服务使用同一把锁的场景吗? ps:想想好像也有几分道理
2434 次点击
所在节点    Java
7 条回复
mmdsun
2019-03-06 08:32:20 +08:00
可以考虑自己写一个。

Java 语言里有个 ReentrantLock 就支持重入 。Redis 分布式锁如果要支持可重入,可对客户端的 set 方法进行包装,使用线程的 Threadlocal 变量存储当前持有锁的计数。不过,调整业务代码完全可以避免重入锁,没必要的
HunterPan
2019-03-06 09:52:24 +08:00
一般情况下使用 redLock 就行了,对一致性要求非常高的情况下就用 etcd,但是自己还是要做幂等的。
wyoumuw
2019-03-06 10:21:15 +08:00
@mmdsun 考虑了好久怎么写,突然想到好像莫得作用。。。谢谢指导
restlessdream
2019-03-06 10:38:54 +08:00
分布式锁在加一条吧:
一定要有 lease 机制,否则中间要是宕机了就永远都释放不了了。进程内锁一般不会有这个问题
HansCathy
2019-03-06 11:03:41 +08:00
不同的服务 业务上肯定是解耦的,一般不存在还要获取同一个锁的问题。分布式锁大部分的应用场景,是相同的业务,在不同机器的 JVM 上执行,操作相同的 redis 和 DB,此时需要保证同时只有一台机器执行。
mouer
2019-03-06 14:31:33 +08:00
tppppp
2019-03-22 14:53:41 +08:00
推荐用 redis 来实现乐观锁的分布式锁
1.满足分布式需求,redis 作为单独进程可共享数据,内部单线程,保证操作数据安全
2.首先根据你下面说的问题我就很奇怪了,无论是 synchronized 还是 ReentrantLock 都只是允许同一线程可冲入,可是他们都不满足分布式需求,可重入完全可以从代码层面解决,key 为同一的名字,value 则可以 ip+threadId,其他线程取值发现有值并且不同则等待,相同则可冲入,还可以根据 value 做一些保证数据一致性操作,幂等性等等
3.这个需求本身就有问题,如果服务器宕机,如果是代码层面的早就不复存在了,redis 本身提供 TTL 即时持有锁的线程宕机,也可以在 TTL 到期自动删除解锁

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/541544

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX