Cluster Groups

Easily create logical groups of cluster nodes within your cluster.

❗️

This is a legacy Apache Ignite documentation

The new documentation is hosted here: https://ignite.apache.org/docs/latest/

ClusterGroup

ClusterGroup represents a logical grouping of cluster nodes.

In Ignite all nodes are equal by design, so you don't have to start any node in a specific order, or assign any specific roles to them. However, Ignite allows users to logically group cluster nodes for any application-specific purpose. For example, you may wish to deploy a service only on remote nodes or assign a role of "worker" to some worker nodes for job execution.

👍

Note that IgniteCluster interface is also a cluster group which includes all the nodes in the cluster.

You can limit job execution, service deployment, messaging, events, and other tasks to run only within some cluster group. For example, here is how to broadcast a job only to remote nodes (excluding the local node).

final Ignite ignite = Ignition.ignite();

IgniteCluster cluster = ignite.cluster();

// Get compute instance which will only execute
// over remote nodes, i.e. not this node.
IgniteCompute compute = ignite.compute(cluster.forRemotes());

// Broadcast to all remote nodes and print the ID of the node 
// on which this closure is executing.
compute.broadcast(() -> System.out.println("Hello Node: " + ignite.cluster().localNode().id());
final Ignite ignite = Ignition.ignite();

IgniteCluster cluster = ignite.cluster();

// Get compute instance which will only execute
// over remote nodes, i.e. not this node.
IgniteCompute compute = ignite.compute(cluster.forRemotes());

// Broadcast closure only to remote nodes.
compute.broadcast(new IgniteRunnable() {
    @Override public void run() {
        // Print ID of the node on which this runnable is executing.
        System.out.println(">>> Hello Node: " + ignite.cluster().localNode().id());
    }
});

Predefined Cluster Groups

You can create cluster groups based on any predicate. For convenience, Ignite comes with some predefined cluster groups.

Here are some examples of cluster groups available in the ClusterGroup interface.

IgniteCluster cluster = ignite.cluster();

// Cluster group with remote nodes, i.e. other than this node.
ClusterGroup remoteGroup = cluster.forRemotes();
IgniteCluster cluster = ignite.cluster();

// All nodes on which cache with name "myCache" is deployed,
// either in client or server mode.
ClusterGroup cacheGroup = cluster.forCacheNodes("myCache");

// All data nodes responsible for caching data for "myCache".
ClusterGroup dataGroup = cluster.forDataNodes("myCache");

// All client nodes that access "myCache".
ClusterGroup clientGroup = cluster.forClientNodes("myCache");
IgniteCluster cluster = ignite.cluster();

// All nodes with attribute "ROLE" equal to "worker".
ClusterGroup attrGroup = cluster.forAttribute("ROLE", "worker");
IgniteCluster cluster = ignite.cluster();

// Cluster group containing one random node.
ClusterGroup randomGroup = cluster.forRandom();

// First (and only) node in the random group.
ClusterNode randomNode = randomGroup.node();
IgniteCluster cluster = ignite.cluster();

// Pick random node.
ClusterGroup randomNode = cluster.forRandom();

// All nodes on the same physical host as the random node.
ClusterGroup cacheNodes = cluster.forHost(randomNode);
IgniteCluster cluster = ignite.cluster();

// Dynamic cluster group representing the oldest cluster node.
// Will automatically shift to the next oldest, if the oldest
// node crashes.
ClusterGroup oldestNode = cluster.forOldest();
IgniteCluster cluster = ignite.cluster();

// Cluster group with only this (local) node in it.
ClusterGroup localGroup = cluster.forLocal();

// Local node.
ClusterNode localNode = localGroup.node();
IgniteCluster cluster = ignite.cluster();

// All client nodes.
ClusterGroup clientGroup = cluster.forClients();

// All server nodes.
ClusterGroup serverGroup = cluster.forServers();

Cluster Groups with Node Attributes

The unique characteristic of Ignite is that all grid nodes are equal. There are no master or server nodes, and there are no worker or client nodes either. All nodes are equal from Ignite’s point of view — however, users can configure nodes to be masters and workers, or clients and data nodes.

All cluster nodes, on start-up, automatically register all the environment and system properties as node attributes. However, users can choose to assign their own node attributes through the Ignite configuration:

<bean class="org.apache.ignite.IgniteConfiguration">
    ...
    <property name="userAttributes">
        <map>
            <entry key="ROLE" value="worker"/>
        </map>
    </property>
    ...
</bean>
IgniteConfiguration cfg = new IgniteConfiguration();

Map<String, String> attrs = Collections.singletonMap("ROLE", "worker");

cfg.setUserAttributes(attrs);

// Start Ignite node.
Ignite ignite = Ignition.start(cfg);

👍

All environment variables and system properties are automatically registered as node attributes on initialization.

👍

Node attributes are available via the ClusterNode.attribute("propertyName") method.

The following example shows how to get the nodes where "worker" attribute has been set.

IgniteCluster cluster = ignite.cluster();

ClusterGroup workerGroup = cluster.forAttribute("ROLE", "worker");

Collection<GridNode> workerNodes = workerGroup.nodes();

Custom Cluster Groups

You can define dynamic cluster groups based on some predicate. Such cluster groups will always only include the nodes that pass the predicate.

Here is an example of a cluster group over nodes that have less than 50% CPU utilization. Note that the nodes in this group will change over time based on their CPU load.

IgniteCluster cluster = ignite.cluster();

// Nodes with less than 50% CPU load.
ClusterGroup readyNodes = cluster.forPredicate((node) -> node.metrics().getCurrentCpuLoad() < 0.5);
IgniteCluster cluster = ignite.cluster();

// Nodes with less than 50% CPU load.
ClusterGroup readyNodes = cluster.forPredicate(
    new IgnitePredicate<ClusterNode>() {
        @Override public boolean apply(ClusterNode node) {
            return node.metrics().getCurrentCpuLoad() < 0.5;
        }
    }
));

Combining Cluster Groups

You can combine cluster groups by nesting them within each other. For example, the following code snippet shows how to get a random remote node by combing remote group with random group.

// Group containing oldest node out of remote nodes.
ClusterGroup oldestGroup = cluster.forRemotes().forOldest();

ClusterNode oldestNode = oldestGroup.node();

Getting Nodes from Cluster Groups

You can get to various cluster group nodes as follows:

ClusterGroup remoteGroup = cluster.forRemotes();

// All cluster nodes in the group.
Collection<ClusterNode> grpNodes = remoteGroup.nodes();

// First node in the group (useful for groups with one node).
ClusterNode node = remoteGroup.node();

// And if you know a node ID, get node by ID.
UUID myID = ...;

node = remoteGroup.node(myId);

Cluster Group Metrics

Ignite automatically collects metrics about all the cluster nodes. The cool thing about cluster groups is that it automatically aggregates the metrics across all the nodes in the group and provides proper averages, mins, and maxes within the group.

Group metrics are available via the ClusterMetrics interface which contains over 50 various metrics (note that the same metrics are available for individual cluster nodes as well).

Here is an example of getting some metrics, including average CPU load and used heap, across all remote nodes:

// Cluster group with remote nodes, i.e. other than this node.
ClusterGroup remoteGroup = ignite.cluster().forRemotes();

// Cluster group metrics.
ClusterMetrics metrics = remoteGroup.metrics();

// Get some metric values.
double cpuLoad = metrics.getCurrentCpuLoad();
long usedHeap = metrics.getHeapMemoryUsed();
int numberOfCores = metrics.getTotalCpus();
int activeJobs = metrics.getCurrentActiveJobs();

X