【发布时间】:2014-05-11 02:40:47
【问题描述】:
我有一个用例,我想拥有一个全局分布式锁。我们开始使用SELECT .. FOR UPDATE,但随着我们扩大服务器数量,很快就开始出现问题。它也没有考虑检查锁然后死亡并且未能返回锁的进程。
我们需要能够设置锁的过期时间(即如果签出锁的进程在 2 小时内没有返回它,锁会自动返回到池中)。我意识到这引入了我们忽略锁的问题,但我们相当肯定如果没有在 2 小时内完成,该过程已经死亡。而且这项工作是幂等的,所以如果它被多次完成也没什么大不了的。
我查看了许多分布式锁定系统并遇到了非常有用的this questions。所有解决方案都从 Java 的java.util.concurrency.locks.Lock 扩展而来,这实际上可能是我遇到的问题,因为该接口没有我需要的过期功能。我们有与mongo-java-distributed-lock 类似的策略,我们使用MongoDB 的findAndModify。我们正在考虑:
作为我们的分布式锁定机制(都恰好实现了java.util.concurrency.locks.Lock)。
最大的问题是因为java.util.concurrency.locks.Lock 没有使锁过期的选项,所以这些不适合所有目标。 answer 可能与 hazelcast 最接近,但它依赖于整个服务器的故障,而不仅仅是一个线程花费太长时间。另一种选择可能是使用带有 hazelcast 的 Samophore,如 here 所述。我可以有一个收割线程,如果他们花费的时间太长,它可以取消其他人的锁。使用 Mongo 和 Redis,我可以利用它们使对象过期的能力,但这似乎不是这两个库的一部分,因为它们最终只是实现了 java.util.concurrency.locks.Lock。
所以这只是一个冗长的询问方式,是否有分布式锁定机制可以在 N 秒后自动过期?在这种情况下,我是否应该考虑与java.util.concurrency.locks.Lock 完全不同的机制?
【问题讨论】:
-
如果您对自己的滚动感到满意,那么您可以考虑扩展 Lock 并添加一个静态观察线程,该线程保留一个活动锁列表并定期检查过期时间。
-
我很想自己动手,但如果已经有解决方案可以做到这一点,我也不想重新发明轮子。
-
@flup,我明确要求提供一个提供过期锁的解决方案。所有其他 SO 问题都只是关于分布式锁,而不是分布式过期锁,这是我关心的关键特性。
标签: java concurrency locking semaphore distributed-lock