All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.cp.CPSubsystem Maven / Gradle / Ivy

There is a newer version: 62
Show newest version
/*
 * Copyright (c) 2008-2019, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hazelcast.cp;

import com.hazelcast.config.cp.CPSemaphoreConfig;
import com.hazelcast.config.cp.CPSubsystemConfig;
import com.hazelcast.config.cp.FencedLockConfig;
import com.hazelcast.core.DistributedObject;
import com.hazelcast.core.HazelcastException;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IAtomicLong;
import com.hazelcast.core.IAtomicReference;
import com.hazelcast.core.ICountDownLatch;
import com.hazelcast.core.IMap;
import com.hazelcast.core.ISemaphore;
import com.hazelcast.core.ISet;
import com.hazelcast.cp.lock.FencedLock;
import com.hazelcast.cp.session.CPSession;
import com.hazelcast.cp.session.CPSessionManagementService;

/**
 * The CP subsystem is a component of a Hazelcast cluster that builds
 * an in-memory strongly consistent layer. It is accessed via
 * {@link 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 * {@link 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 {@link IMap}, {@link ISet}, etc. *

* Data structures in the CP subsystem run in {@link CPGroup}s. A CP group * consists of an odd number of {@link 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 * {@link 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 {@link CPSubsystemConfig} and * {@link 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 * {@link CPSubsystemConfig#setCPMemberCount(int)} configuration. * The second group is the DEFAULT CP group, whose name is given in * {@link 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 {@link IAtomicLong} instance * is created by calling {@code .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 {@link IAtomicLong} is * created by calling {@code .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 {@link 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 * {@link 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: *

    *
  • Any Hazelcast member leaves the cluster,
  • *
  • The local Hazelcast member commits a CP member list which is different * from other members' committed CP member lists,
  • *
  • The local Hazelcast member list fails to commit its discovered CP member * list for any reason.
  • *
*

* When the CP subsystem is restarted via * {@link 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 {@link CPSubsystemManagementService#restart()} for more details. *

* The CP data structure proxies differ from the other Hazelcast data * structure proxies in two aspects. First, each time you fetch a proxy via * one of the methods in this interface, internally a commit is performed * on the Metadata CP group. Hence, callers should cache returned proxies. * Second, if you call {@link DistributedObject#destroy()} on a CP data * structure proxy, that data structure is terminated on the underlying * CP group and cannot be reinitialized 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. * * @see CPSubsystemConfig * @see CPMember * @see CPSession */ public interface CPSubsystem { /** * Returns a proxy for an {@link IAtomicLong} instance created on the CP * subsystem. Hazelcast's {@link IAtomicLong} is a distributed version of * java.util.concurrent.atomic.AtomicLong. If no group name is * given within the "name" parameter, then the {@link IAtomicLong} instance * will be created on the DEFAULT CP group. If a group name is given, like * {@code .getAtomicLong("myLong@group1")}, the given group will be * initialized first, if not initialized already, and then the * {@link IAtomicLong} instance will be created on this group. Returned * {@link 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. *

* Each call of this method performs a commit to the Metadata CP * group. Hence, callers should cache the returned proxy. * * @param name name of the {@link IAtomicLong} proxy * @return {@link IAtomicLong} proxy for the given name * @throws HazelcastException if the CP subsystem is not enabled */ IAtomicLong getAtomicLong(String name); /** * Returns a proxy for an {@link IAtomicReference} instance created on * the CP subsystem. Hazelcast's {@link IAtomicReference} is a distributed * version of java.util.concurrent.atomic.AtomicLong. If no group * name is given within the "name" parameter, then * the {@link IAtomicReference} instance will be created on the DEFAULT CP * group. If a group name is given, like * {@code .getAtomicReference("myRef@group1")}, the given group will be * initialized first, if not initialized already, and then the * {@link IAtomicReference} instance will be created on this group. * Returned {@link 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. *

* Each call of this method performs a commit to the Metadata CP * group. Hence, callers should cache the returned proxy. * * @param name name of the {@link IAtomicReference} proxy * @return {@link IAtomicReference} proxy for the given name * @throws HazelcastException if the CP subsystem is not enabled */ IAtomicReference getAtomicReference(String name); /** * Returns a proxy for an {@link ICountDownLatch} instance created on * the CP subsystem. Hazelcast's {@link ICountDownLatch} is a distributed * version of java.util.concurrent.CountDownLatch. If no group * name is given within the "name" parameter, then * the {@link ICountDownLatch} instance will be created on the DEFAULT CP * group. If a group name is given, like * {@code .getCountDownLatch("myLatch@group1")}, the given group will be * initialized first, if not initialized already, and then the * {@link ICountDownLatch} instance will be created on this group. Returned * {@link ICountDownLatch} instance offers linearizability. When a network * partition occurs, proxies that exist on the minority side of its CP * group lose availability. *

* Each call of this method performs a commit to the Metadata CP * group. Hence, callers should cache the returned proxy. * * @param name name of the {@link ICountDownLatch} proxy * @return {@link ICountDownLatch} proxy for the given name * @throws HazelcastException if the CP subsystem is not enabled */ ICountDownLatch getCountDownLatch(String name); /** * Returns a proxy for an {@link FencedLock} instance created on the CP * subsystem. Hazelcast's {@link FencedLock} is a distributed version of * java.util.concurrent.locks.Lock. If no group name is given * within the "name" parameter, then the {@link FencedLock} instance will * be created on the DEFAULT CP group. If a group name is given, like * {@code .getLock("myLock@group1")}, the given group will be initialized * first, if not initialized already, and then the {@link FencedLock} * instance will be created on this group. Returned {@link FencedLock} * instance offers linearizability. When a network partition occurs, * proxies that exist on the minority side of its CP group lose * availability. *

* Each call of this method performs a commit to the Metadata CP * group. Hence, callers should cache the returned proxy. * * @see FencedLockConfig * * @param name name of the {@link FencedLock} proxy * @return {@link FencedLock} proxy for the given name * @throws HazelcastException if the CP subsystem is not enabled */ FencedLock getLock(String name); /** * Returns a proxy for an {@link ISemaphore} instance created on the CP * subsystem. Hazelcast's {@link ISemaphore} is a distributed version of * java.util.concurrent.Semaphore. If no group name is given * within the "name" parameter, then the {@link ISemaphore} instance will * be created on the DEFAULT CP group. If a group name is given, like * {@code .getSemaphore("mySemaphore@group1")}, the given group will be * initialized first, if not initialized already, and then the * {@link ISemaphore} instance will be created on this group. Returned * {@link ISemaphore} instance offers linearizability. When a network * partition occurs, proxies that exist on the minority side of its CP * group lose availability. *

* Each call of this method performs a commit to the Metadata CP * group. Hence, callers should cache the returned proxy. * * @see CPSemaphoreConfig * * @param name name of the {@link ISemaphore} proxy * @return {@link ISemaphore} proxy for the given name * @throws HazelcastException if the CP subsystem is not enabled */ ISemaphore getSemaphore(String name); /** * Returns the local CP member if this Hazelcast member is part of * the CP subsystem, returns null otherwise. *

* This method is a shortcut for {@link CPSubsystemManagementService#getLocalCPMember()} * method. Calling this method is equivalent to calling * getCPSubsystemManagementService().getLocalCPMember(). * * @return local CP member if available, null otherwise * @throws HazelcastException if the CP subsystem is not enabled * @see CPSubsystemManagementService#getLocalCPMember() */ CPMember getLocalCPMember(); /** * Returns the {@link CPSubsystemManagementService} of this Hazelcast * instance. {@link CPSubsystemManagementService} offers APIs for managing * CP members and CP groups. * * @return the {@link CPSubsystemManagementService} of this Hazelcast instance */ CPSubsystemManagementService getCPSubsystemManagementService(); /** * Returns the {@link CPSessionManagementService} of this Hazelcast * instance. {@link CPSessionManagementService} offers APIs for managing CP * sessions. * * @return the {@link CPSessionManagementService} of this Hazelcast instance */ CPSessionManagementService getCPSessionManagementService(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy