5

I see that Hazelcast 3.12 has introduced the CPSubsystem() for systems with 3-7 nodes. I understand the reasoning. However, if I am trying to design a solution that can run with anywhere between 1-n nodes, do I need to use different logic to validate if the CPSubsystem is enabled? How do I even check that?

I would have thought/hoped that simply calling

hazelcastInstance.getCPSubsystem().getLock()

would work no matter the number of nodes, but if there are fewer than 3 nodes, it throws an exception. And I can't find any method that allows me to check if the CPSubsystem is enabled or not.

My current implementation uses the deprecated method getLock() to get a distributed lock:

   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();
    }

How can I get a lock with Hazelcast without knowing this? The hazelcastInstance.getLock() is marked as deprecated and targeted for removal in HC4.

Eric B.
  • 23,425
  • 50
  • 169
  • 316

2 Answers2

6

As you already know, CPSubsystem is a CP system in terms of CAP theorem. It has to be enabled explicitly to use, because it has some limitations and prerequisites. One of them is, at least 3 Hazelcast members should exist in the cluster. Actually, 2 members is sufficient but Hazelcast's CPSubsystem rejects to work with 2 members because majority of 2 members is 2 again, and it's prone to be unavailable once one of the members crashes.

HazelcastInstance.getLock() uses async replication of Hazelcast and cannot provide CP guarantees under failures. This is fine for some systems/applications but not for all. That's why choosing between a best-effort locking mechanism vs CP based locking mechanism should be explicit and applications relying on the lock should be designed depending on this choice. See Daniel Abadi's The dangers of conditional consistency guarantees post related to this choice. That's why, CPSubsystem().getLock() does not fallback to best-effort/unsafe locking mechanism when cluster size is below 3.

HazelcastInstance.getLock() is deprecated in 3.12 and will be removed in 4.0. But Hazelcast will provide an unsafe (development) mode for CP data structures, which will work with any number of members and will be based on async replication similar to Hazelcast AP data structures.

mdogan
  • 1,929
  • 14
  • 15
  • Thanks for linking the that PR. That's precisely what I was looking for and was concerned about it's availability. I guess for the moment, the safest path is to continue using the deprecated methods until the unsafe mode is released. I've also edited my question to indicate Hazelcast 3.12 instead. – Eric B. Jul 29 '19 at 18:11
  • Currently I am facing the same issue regarding the use of `CPSubsystem`, working with just few instances and have at least one working all the time seems to be not possible. I also raised this [question](https://stackoverflow.com/questions/57526281/configure-hazelcast-cpsubsystem-retries-timeout) mentioning the issue around it. Probably I will be avoiding the `CPSubsystem` for now until the unsafe mode is released. – nortontgueno Aug 16 '19 at 18:24
0
    HazelcastInstance hz1 = Hazelcast.newHazelcastInstance(config);
    HazelcastInstance hz2 = Hazelcast.newHazelcastInstance(config);
    HazelcastInstance hz3 = Hazelcast.newHazelcastInstance(config);

You can add 3 members on the same JVM/node/instance.You should be able to run CPSubsystem without three physical nodes, instances or JVM.

Yukti Kaura
  • 55
  • 1
  • 11