Apache zookeeper 为什么我需要使用curator而不是zookeeper本机API作为分布式锁?
我们的项目严重依赖分布式锁。我知道馆长提供了几种锁。我的问题是,我可以将创建节点用作互斥对象吗Apache zookeeper 为什么我需要使用curator而不是zookeeper本机API作为分布式锁?,apache-zookeeper,apache-curator,Apache Zookeeper,Apache Curator,我们的项目严重依赖分布式锁。我知道馆长提供了几种锁。我的问题是,我可以将创建节点用作互斥对象吗 CuratorFramework zkClient = zookeeperConnectionProvider.getZkClientForJobDistributeLock(); try { zkClient.create() .creatingParentsIfNeeded()
CuratorFramework zkClient = zookeeperConnectionProvider.getZkClientForJobDistributeLock();
try {
zkClient.create()
.creatingParentsIfNeeded()
.withMode(CreateMode.EPHEMERAL)
.forPath("/" + job.getIdentifier().jobNodeString());
LOGGER.info(String.format("create node in zookeeper [%s]", job.getIdentifier().jobNodeString()));
} catch (Exception e) {
LOGGER.info(String.format("create job instance node in zookeeper failed [%s], reason [%s]",
job.getIdentifier().jobNodeString(),
e.getClass().getCanonicalName()));
return NO_WORK;
}
当第一个进程成功创建时,第二个进程将获得
NodeExistsException
异常。如果这样不行,我想知道原因 我认为反对按您的建议执行的第一个反对意见是,很难阅读/理解代码,请将其与以下内容进行比较:
InterProcessSemaphoreMutex lock = new InterProcessSemaphoreMutex(client, path);
lock.acquire();
另一个原因是您通常使用锁来阻止线程,直到另一个线程释放锁,这样您就可以编写如下所示的代码:
//do normal work
...
lock.acquire();
//do critical single threaded work
...
lock.release();
//back to normal work
...
这在您的代码中是完全可能的,但在这里它是为您创建的
使用已经实现的锁而不是编写自己的锁还有很多原因,但这主要归结为:“为什么要重新发明轮子?”我认为反对按您的建议执行的第一个原因是,很难阅读/理解代码,请将其与:
InterProcessSemaphoreMutex lock = new InterProcessSemaphoreMutex(client, path);
lock.acquire();
另一个原因是您通常使用锁来阻止线程,直到另一个线程释放锁,这样您就可以编写如下所示的代码:
//do normal work
...
lock.acquire();
//do critical single threaded work
...
lock.release();
//back to normal work
...
这在您的代码中是完全可能的,但在这里它是为您创建的
使用已经实现的锁而不是编写自己的锁还有很多原因,但这主要归结为:“为什么要重新发明轮子?”谢谢Petter。我需要的是类似互斥的东西,但是失败的进程不需要等到成功发布。我原以为zookeeper中的命名节点可以,但我发现它根本不起作用。最后我转向进程间互斥。一开始不使用它的原因是,我读了一些文档,知道它在zookeeper中创建了几个节点,并且最小索引将获得锁。所以我认为一个节点可能更有效。之后我做了一些实验:进程A在zookeeper中创建一个节点并保持连接,然后进程B删除该节点,我得到一个非节点异常。如果进程A与zookeeper服务器断开连接,则进程B可以正确删除它(ps:节点类型为CreateMode.Persistent)。不同连接之间是否存在某种“隔离”机制?如果不想等待锁定,可以使用:Boolean hasLock=lock.acquire(1,TimeUnit.millists);我不确定您是否可以使用0,但这只会等待1毫秒的锁定,因此它不会使您的代码慢很多。哦,如果“hasLock”是假的,你就没有得到锁。谢谢你,皮特。我需要的是类似互斥的东西,但是失败的进程不需要等到成功发布。我原以为zookeeper中的命名节点可以,但我发现它根本不起作用。最后我转向进程间互斥。一开始不使用它的原因是,我读了一些文档,知道它在zookeeper中创建了几个节点,并且最小索引将获得锁。所以我认为一个节点可能更有效。之后我做了一些实验:进程A在zookeeper中创建一个节点并保持连接,然后进程B删除该节点,我得到一个非节点异常。如果进程A与zookeeper服务器断开连接,则进程B可以正确删除它(ps:节点类型为CreateMode.Persistent)。不同连接之间是否存在某种“隔离”机制?如果不想等待锁定,可以使用:Boolean hasLock=lock.acquire(1,TimeUnit.millists);我不确定您是否可以使用0,但这只会等待1毫秒的锁定,因此它不会使您的代码慢很多。哦,如果“hasLock”是假的,你就没有得到锁。