2

グローバルに分散されたロックが必要なユースケースがあります。を使い始めましたSELECT .. FOR UPDATEが、サーバーの数を増やしていくと、すぐに問題が発生し始めました。また、ロックをチェックアウトした後に終了し、ロックを返せなかったプロセスも考慮されていませんでした。

ロックに有効期限を設定できるようにする必要があります (つまり、ロックをチェックアウトしたプロセスが 2 時間以内にロックを返さない場合、ロックは自動的にプールに返されます)。これにより、ロックを無視するという問題が発生することは認識していますが、2 時間以内に完了しない場合、プロセスが終了したことはほぼ確実です。また、ジョブはべき等であるため、複数回実行されても大したことではありません。

私は多くの分散ロック システムを調べ、非常に役立つこの質問に出くわしました。すべてのソリューションはJavaのjava.util.concurrency.locks.Lock. MongoDB のfindAndModifyを使用するmongo-java-distributed-lockと同様の戦略があります。検討中:

私たちの分散ロックメカニズムとして (すべてがたまたま実装されています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この状況とは別のメカニズムを検討する必要がありますか?

4

4 に答える 4

2

Zookeeperの使用を検討する必要があります。そして、zookeeper : curator frameworkの上に構築された、この種の「分散型」のもののための使いやすいライブラリがあります。あなたが探しているのは shared reentrant lockだと思います。レシピで他のロックを確認することもできます。

于 2014-04-16T08:42:49.190 に答える
1

実際、私が知る限り、mongo-java-distributed-lockには以下を使用してロックを期限切れにする機能があります。DistributedLockOptions.setInactiveLockTimeout()

まだ試していませんが、そうなると思います...

編集:私も試してみましたが、うまくいきます...

String lockName = "com.yourcompany.yourapplication.somelock";
int lockTimeoutMilliSeconds = 500;

String dbURI = CWConfig.get().getMongoDBConfig().getDbURI();
DistributedLockSvcFactory lockSvcFactory = new DistributedLockSvcFactory(new DistributedLockSvcOptions(dbURI));
DistributedLockSvc lockSvc = lockSvcFactory.getLockSvc();

DistributedLock lock = lockSvc.create(lockName);
lock.getOptions().setInactiveLockTimeout(lockTimeoutMilliSeconds);
try {
    lock.lock();
    // Do work
} finally {
    lock.unlock();
}
于 2016-05-31T13:03:57.200 に答える