public interface CPSubsystem
HazelcastInstance.getCPSubsystem()
. Its data structures are CP with
respect to the CAP principle, i.e., they always maintain linearizability
and prefer consistency over availability during network partitions.
Currently, the CP subsystem contains only the implementations of Hazelcast's
concurrency APIs. These APIs do not maintain large states. For this reason,
all members of a Hazelcast cluster do not take part in the CP subsystem.
The number of members that takes part in the CP subsystem is specified with
CPSubsystemConfig.setCPMemberCount(int)
. Let's suppose the number of
CP members is configured as C. Then, when Hazelcast cluster starts,
the first C members form the CP subsystem. These members are called
CP members and they can also contain data for other regular Hazelcast data
structures, such as IMap
, ISet
, etc.
Data structures in the CP subsystem run in CPGroup
s. A CP group
consists of an odd number of CPMember
s between 3 and 7.
Each CP group independently runs the Raft consensus algorithm. Operations
are committed & executed only after they are successfully replicated to
the majority of the CP members in a CP group. For instance, in a CP group of
5 CP members, operations are committed when they are replicated to at least
3 CP members. The size of CP groups are specified via
CPSubsystemConfig.setGroupSize(int)
and each CP group contains
the same number of CP members.
Please note that the size of CP groups do not have to be same with
the CP member count. Namely, number of CP members in the CP subsystem can be
larger than the configured CP group size. In this case, CP groups will be
formed by selecting the CP members randomly. Please note that the current CP
subsystem implementation works only in memory without persisting any state
to disk. It means that a crashed CP member will not be able to recover by
reloading its previous state. Therefore, crashed CP members create a danger
for gradually losing majority of CP groups and eventually cause the total
loss of availability of the CP subsystem. To prevent such situations, failed
CP members can be removed from the CP subsystem and replaced in CP groups
with other available CP members. This flexibility provides a good degree of
fault-tolerance at run-time. Please see CPSubsystemConfig
and
CPSubsystemManagementService
for more details.
The CP subsystem runs 2 CP groups by default. The first one is
the Metadata group. It is an internal CP group which is responsible for
managing the CP members and CP groups. It is be initialized during the
cluster startup process if the CP subsystem is enabled via
CPSubsystemConfig.setCPMemberCount(int)
configuration.
The second group is the DEFAULT CP group, whose name is given in
CPGroup.DEFAULT_GROUP_NAME
. If a group name is not specified while
creating a proxy for a CP data structure, that data structure will be mapped
to the DEFAULT CP group. For instance, when a CP IAtomicLong
instance
is created by calling .getAtomicLong("myAtomicLong")
, it will be
initialized on the DEFAULT CP group. Besides these 2 pre-defined CP groups,
custom CP groups can be created at run-time. If a CP IAtomicLong
is
created by calling .getAtomicLong("myAtomicLong@myGroup")
, first
a new CP group will be created with the name "myGroup" and then
"myAtomicLong" will be initialized on this custom CP group.
The current set of CP data structures have quite low memory overheads.
Moreover, related to the Raft consensus algorithm, each CP group makes
uses of internal heartbeat RPCs to maintain authority of the leader member
and help lagging CP members to make progress. Last but not least, the new
CP lock and semaphore implementations rely on a brand new session mechanism.
In a nutshell, a Hazelcast server or a client starts a new session on the
corresponding CP group when it makes its very first lock or semaphore
acquire request, and then periodically commits session-heartbeats to this CP
group to indicate its liveliness. It means that if CP locks and semaphores
are distributed into multiple CP groups, there will be a session
management overhead. Please see CPSession
for more details.
For the aforementioned reasons, we recommend developers to use a minimal
number of CP groups. For most use cases, the DEFAULT CP group should be
sufficient to maintain all CP data structure instances. Custom CP groups
could be created when throughput of the CP subsystem is needed to be
improved.
The CP subsystem runs a discovery process in the background on cluster
startup. When it is enabled by setting a positive value to
CPSubsystemConfig.setCPMemberCount(int)
, say N, the first N members
in the cluster member list initiate the discovery process. Other Hazelcast
members skip this step. The CP subsystem discovery process runs out of the
box on top of Hazelcast's cluster member list without requiring any custom
configuration for different environments. It is completed when each one of
the first N Hazelcast members initializes its local CP member list and
commits it to the Metadata CP group. The Metadata CP group is initialized
among those CP members as well. A soon-to-be CP member terminates
itself if any of the following conditions occur before the discovery process
is completed:
When the CP subsystem is restarted via
CPSubsystemManagementService.restart()
, the CP subsystem discovery
process is triggered again. However, it does not terminate Hazelcast members
if the discovery fails for the aforementioned reasons, because Hazelcast
members are likely to contain data for AP data structures and termination
can cause data loss. Hence, you need to observe the cluster and check if
the discovery process completes successfully on CP subsystem restart.
See CPSubsystemManagementService.restart()
for more details.
The CP data structure proxies differ from the other Hazelcast data
structure proxies in one aspect, that is, if you call the
DistributedObject.destroy()
API on a CP data structure proxy,
that data structure is terminated on the underlying CP group and cannot be
reinitialized on the same CP group until the CP group is force-destroyed.
For this reason, please make sure that you are completely done with a CP
data structure before destroying its proxy.
CPSubsystemConfig
,
CPMember
,
CPSession
Modifier and Type | Method and Description |
---|---|
IAtomicLong |
getAtomicLong(String name)
Returns a proxy for an
IAtomicLong instance created on the CP
subsystem. |
<E> IAtomicReference<E> |
getAtomicReference(String name)
Returns a proxy for an
IAtomicReference instance created on
the CP subsystem. |
ICountDownLatch |
getCountDownLatch(String name)
Returns a proxy for an
ICountDownLatch instance created on
the CP subsystem. |
CPSessionManagementService |
getCPSessionManagementService()
Returns the
CPSessionManagementService of this Hazelcast
instance. |
CPSubsystemManagementService |
getCPSubsystemManagementService()
Returns the
CPSubsystemManagementService of this Hazelcast
instance. |
CPMember |
getLocalCPMember()
Returns the local CP member if this Hazelcast member is part of
the CP subsystem, returns null otherwise.
|
FencedLock |
getLock(String name)
Returns a proxy for an
FencedLock instance created on the CP
subsystem. |
ISemaphore |
getSemaphore(String name)
Returns a proxy for an
ISemaphore instance created on the CP
subsystem. |
IAtomicLong getAtomicLong(String name)
IAtomicLong
instance created on the CP
subsystem. Hazelcast's IAtomicLong
is a distributed version of
java.util.concurrent.atomic.AtomicLong. If no group name is
given within the "name" parameter, then the IAtomicLong
instance
will be created on the DEFAULT CP group. If a group name is given, like
.getAtomicLong("myLong@group1")
, the given group will be
initialized first, if not initialized already, and then the
IAtomicLong
instance will be created on this group. Returned
IAtomicLong
instance offers linearizability and behaves as a CP
register. When a network partition occurs, proxies that exist on the
minority side of its CP group lose availability.name
- name of the IAtomicLong
proxyIAtomicLong
proxy for the given name<E> IAtomicReference<E> getAtomicReference(String name)
IAtomicReference
instance created on
the CP subsystem. Hazelcast's IAtomicReference
is a distributed
version of java.util.concurrent.atomic.AtomicLong. If no group
name is given within the "name" parameter, then
the IAtomicReference
instance will be created on the DEFAULT CP
group. If a group name is given, like
.getAtomicReference("myRef@group1")
, the given group will be
initialized first, if not initialized already, and then the
IAtomicReference
instance will be created on this group.
Returned IAtomicReference
instance offers linearizability and
behaves as a CP register. When a network partition occurs, proxies that
exist on the minority side of its CP group lose availability.name
- name of the IAtomicReference
proxyIAtomicReference
proxy for the given nameICountDownLatch getCountDownLatch(String name)
ICountDownLatch
instance created on
the CP subsystem. Hazelcast's ICountDownLatch
is a distributed
version of java.util.concurrent.CountDownLatch. If no group
name is given within the "name" parameter, then
the ICountDownLatch
instance will be created on the DEFAULT CP
group. If a group name is given, like
.getCountDownLatch("myLatch@group1")
, the given group will be
initialized first, if not initialized already, and then the
ICountDownLatch
instance will be created on this group. Returned
ICountDownLatch
instance offers linearizability. When a network
partition occurs, proxies that exist on the minority side of its CP
group lose availability.name
- name of the ICountDownLatch
proxyICountDownLatch
proxy for the given nameFencedLock getLock(String name)
FencedLock
instance created on the CP
subsystem. Hazelcast's FencedLock
is a distributed version of
java.util.concurrent.locks.Lock. If no group name is given
within the "name" parameter, then the FencedLock
instance will
be created on the DEFAULT CP group. If a group name is given, like
.getLock("myLock@group1")
, the given group will be initialized
first, if not initialized already, and then the FencedLock
instance will be created on this group. Returned FencedLock
instance offers linearizability. When a network partition occurs,
proxies that exist on the minority side of its CP group lose
availability.name
- name of the FencedLock
proxyFencedLock
proxy for the given nameISemaphore getSemaphore(String name)
ISemaphore
instance created on the CP
subsystem. Hazelcast's ISemaphore
is a distributed version of
java.util.concurrent.Semaphore. If no group name is given
within the "name" parameter, then the ISemaphore
instance will
be created on the DEFAULT CP group. If a group name is given, like
.getSemaphore("mySemaphore@group1")
, the given group will be
initialized first, if not initialized already, and then the
ISemaphore
instance will be created on this group. Returned
ISemaphore
instance offers linearizability. When a network
partition occurs, proxies that exist on the minority side of its CP
group lose availability.name
- name of the ISemaphore
proxyISemaphore
proxy for the given nameCPSemaphoreConfig
CPMember getLocalCPMember()
This field is initialized when the local Hazelcast member is one of
the first CPSubsystemConfig.getCPMemberCount()
members
in the cluster and the CP subsystem discovery process is completed.
This method fails with HazelcastException
if the CP subsystem
is not enabled.
HazelcastException
- if the CP subsystem is not enabledCPSubsystemManagementService getCPSubsystemManagementService()
CPSubsystemManagementService
of this Hazelcast
instance. CPSubsystemManagementService
offers APIs for managing
CP members and CP groups.CPSubsystemManagementService
of this Hazelcast instanceCPSessionManagementService getCPSessionManagementService()
CPSessionManagementService
of this Hazelcast
instance. CPSessionManagementService
offers APIs for managing CP
sessions.CPSessionManagementService
of this Hazelcast instanceCopyright © 2019 Hazelcast, Inc.. All Rights Reserved.