首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可以设置为过期Java的全局分布式锁

可以设置为过期Java的全局分布式锁
EN

Stack Overflow用户
提问于 2014-03-31 16:26:18
回答 4查看 5.7K关注 0票数 2

我有一个用例,我希望有一个全局分布的锁。我们一开始使用SELECT .. FOR UPDATE,但随着服务器数量的增加,这很快就出现了问题。此外,它也没有考虑到签出锁,然后死掉并返回锁的进程。

我们需要能够设置锁的过期(也就是说,如果签出锁的进程在2小时内没有返回它,那么锁就会自动返回到池中)。我意识到这带来了我们忽略锁的问题,但是我们相当肯定,如果没有在2小时内完成这个过程,那么这个过程已经死掉了。而且这项工作是幂等的,所以如果多做一次,那也不是什么大不了的事。

我查看了许多分布式锁定系统,并遇到了非常有用的这个问题。所有的解决方案都扩展到了Java的java.util.concurrency.locks.Lock,实际上这可能是我遇到的问题,因为该接口没有我所需要的过期特性。我们有一个与mongo java-分布式锁类似的策略,在那里我们使用MongoDB的findAndModify。我们正在考虑:

作为我们的分布式锁定机制(都碰巧实现了java.util.concurrency.locks.Lock)。

最大的问题是,因为java.util.concurrency.locks.Lock没有一个关闭锁的选项,所以这些并不适合所有的目标。这个回答可能与hazelcast最接近,但它依赖于整个服务器的失败,而不仅仅是一个需要太长时间的线程。另一种选择可能是像描述的这里那样,在hazelcast中使用Samaphore。我可以有一个收割机线,然后能够取消锁的其他人,如果他们是太长。使用Mongo和Redis,我可以利用它们的过期对象的能力,但这似乎不是库的一部分,因为它们最终只是实现了java.util.concurrency.locks.Lock

因此,这只是一种长篇大论的方式来问,是否有一个分布式锁定机制,我可以在N秒后自动过期?在这种情况下,我应该考虑一种与java.util.concurrency.locks.Lock不同的机制吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-07-15 18:12:55

您可以使用基于雷迪森服务器的Redis。它实现了熟悉的Java数据结构,包括具有分布式和可伸缩能力的java.util.Lock。包括设置锁定释放超时的能力。用法示例:

代码语言:javascript
复制
Config config = new Config();
// for single server
config.useSingleServer()
      .setAddress("127.0.0.1:6379");
// or 
// for master/slave servers
config.useSentinelConnection()
      .setMasterName("mymaster")
      .addSentinelAddress("127.0.0.1:26389", "127.0.0.1:26379");

Redisson redisson = Redisson.create(config);

Lock lock = redisson.getLock("anyLock");
try {
   // unlock automatically after 10 seconds of hold
   lock.lock(10, TimeUnit.SECONDS);

} finally {
   lock.unlock();
}

...

redisson.shutdown();
票数 3
EN

Stack Overflow用户

发布于 2014-04-16 08:42:49

您应该考虑使用动物园管理员。而且有一个易于使用的库,用于建立在动物园管理员之上的“分布式”东西:馆长框架。我想你要找的是共享重入锁。您还可以在菜谱中检查其他锁。

票数 3
EN

Stack Overflow用户

发布于 2014-04-16 21:20:19

这个怎么样?http://www.gemstone.com/docs/5.5.0/product/docs/japi/com/gemstone/gemfire/distributed/DistributedLockService.html

它的lock方法似乎满足了您的需要:

public abstract boolean lock(Object name, long waitTimeMillis, long leaseTimeMillis)

尝试获取名为“名称”的锁。获取锁后立即返回true。如果该锁当前由此系统中的另一个线程或分布式系统中的任何其他进程持有,或者系统中的另一个线程已锁定整个服务,则此方法在放弃并返回false之前一直试图获取该锁,直至waitTimeMillis。如果获得了锁,它将一直保持到被调用解锁(对象名称)为止,或者直到锁被授予后的leaseTimeMillis毫秒(以第一位为准)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22766988

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档