如何在少于 3 个节点的情况下使用 Hazelcast 的 CPSubsystem?

How to use Hazelcast's CPSubsystem with fewer than 3 nodes?

我看到 Hazelcast 3.12 为具有 3-7 个节点的系统引入了 CPSubsystem()。我明白其中的道理。但是,如果我尝试设计一个可以 运行 与 1-n 节点之间的任何位置的解决方案,我是否需要使用不同的逻辑来验证是否启用了 CPSubsystem?我该如何检查?

我会 thought/hoped 只需调用

hazelcastInstance.getCPSubsystem().getLock()

无论节点数多少都可以,但如果少于3个节点,就会抛出异常。而且我找不到任何允许我检查 CPSubsystem 是否启用的方法。

我当前的实现使用已弃用的方法getLock()来获取分布式锁:

   LOG.debug("Creating a distributed lock on username for a maximum of 5 minutes {}", username);
    ILock usernameLock = hazelcastInstance.getLock(this.getClass().getName() + ":" + username);
    try {
        if (usernameLock.tryLock (5, TimeUnit.MINUTES)) {
            clearUserData(cacheEntryEvent);
        }
    } catch (InterruptedException e) {
        LOG.warn("Exception locking on : {} ", username, e);
        LOG.warn("Invoking clearUserData without synchronization : {}", username);
        clearUserData(cacheEntryEvent);
    } finally {
        usernameLock.unlock();
    }

如何在不知道这一点的情况下使用 Hazelcast 获得锁定? hazelcastInstance.getLock() 在 HC4 中被标记为已弃用和删除。

如您所知,根据 CAP 定理,CPSubsystem 是一个 CP 系统。它必须明确启用才能使用,因为它有一些限制和先决条件。其中之一是,集群中至少应存在 3 个 Hazelcast 成员。实际上,2 个成员就足够了,但是 Hazelcast 的 CPSubsystem 拒绝使用 2 个成员,因为 2 个成员中的大多数又是 2 个,一旦其中一个成员崩溃,它就很容易不可用。

HazelcastInstance.getLock() 使用 async replication of Hazelcast 并且在失败时无法提供 CP 保证。这对某些人 systems/applications 没问题,但对所有人而言并非如此。这就是为什么在尽力而为锁定机制与基于 CP 的锁定机制之间进行选择应该是明确的,并且应该根据此选择来设计依赖于锁定的应用程序。请参阅 Daniel Abadi 的 条件一致性保证的危险 post 与此选择相关。这就是为什么当簇大小低于 3 时 CPSubsystem().getLock() 不会回退到 best-effort/unsafe 锁定机制。

HazelcastInstance.getLock() 在 3.12 中已弃用,将在 4.0 中删除。但是 Hazelcast 将提供一个 unsafe (development) mode for CP data structures,它将与任意数量的成员一起工作,并且将基于类似于 Hazelcast AP 数据结构的异步复制。

    HazelcastInstance hz1 = Hazelcast.newHazelcastInstance(config);
    HazelcastInstance hz2 = Hazelcast.newHazelcastInstance(config);
    HazelcastInstance hz3 = Hazelcast.newHazelcastInstance(config);

您可以在同一个 JVM/node/instance 上添加 3 个成员。您应该能够 运行 没有三个物理节点、实例或 JVM 的 CPSubsystem。