In-memory distributed computing platform for real-time stream processing and data storage with SQL capabilities
—
Hazelcast provides comprehensive cluster management capabilities including membership management, cluster state control, partition management, and distributed coordination. This allows you to monitor and control cluster behavior programmatically.
The main interface for cluster-wide operations and membership management.
import com.hazelcast.cluster.Cluster;
import com.hazelcast.cluster.Member;
import com.hazelcast.cluster.MembershipListener;
import com.hazelcast.cluster.ClusterState;
import com.hazelcast.version.Version;
import java.util.Set;
import java.util.UUID;
public interface Cluster {
// Membership information
Set<Member> getMembers();
Member getLocalMember();
// Membership events
UUID addMembershipListener(MembershipListener listener);
boolean removeMembershipListener(UUID registrationId);
// Cluster time
long getClusterTime();
// Cluster state management
ClusterState getClusterState();
void changeClusterState(ClusterState newState);
void changeClusterState(ClusterState newState, TransactionOptions transactionOptions);
// Version management
Version getClusterVersion();
void changeClusterVersion(Version version);
// Cluster operations
void shutdown();
void shutdown(TransactionOptions transactionOptions);
// Lite member promotion
void promoteLocalLiteMember();
}HazelcastInstance hz = Hazelcast.newHazelcastInstance();
Cluster cluster = hz.getCluster();Represents information about a cluster member.
import com.hazelcast.cluster.Member;
import com.hazelcast.cluster.Address;
import java.util.Map;
import java.util.UUID;
public interface Member extends Endpoint {
// Member identification
UUID getUuid();
Address getAddress();
Map<String, String> getAttributes();
String getAttribute(String key);
// Member properties
boolean isLiteMember();
Version getVersion();
// Address information
Address getSocketAddress();
// Lite member status
boolean isLocalMember();
}Network address information for cluster members.
import com.hazelcast.cluster.Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
public class Address {
// Constructors
public Address(String host, int port);
public Address(InetAddress inetAddress, int port);
public Address(InetSocketAddress inetSocketAddress);
// Address information
public String getHost();
public int getPort();
public InetAddress getInetAddress();
public InetSocketAddress getInetSocketAddress();
// Scope and type information
public String getScopeId();
public boolean isIPv4();
public boolean isIPv6();
}Cluster cluster = hz.getCluster();
// Get all members
Set<Member> members = cluster.getMembers();
System.out.println("Cluster has " + members.size() + " members");
for (Member member : members) {
System.out.println("Member: " + member.getAddress());
System.out.println(" UUID: " + member.getUuid());
System.out.println(" Lite member: " + member.isLiteMember());
System.out.println(" Version: " + member.getVersion());
// Member attributes
Map<String, String> attributes = member.getAttributes();
for (Map.Entry<String, String> attr : attributes.entrySet()) {
System.out.println(" " + attr.getKey() + ": " + attr.getValue());
}
}
// Get local member
Member localMember = cluster.getLocalMember();
System.out.println("Local member: " + localMember.getAddress());
System.out.println("Is lite member: " + localMember.isLiteMember());Listens for member join and leave events in the cluster.
import com.hazelcast.cluster.MembershipListener;
import com.hazelcast.cluster.MembershipEvent;
public interface MembershipListener {
void memberAdded(MembershipEvent membershipEvent);
void memberRemoved(MembershipEvent membershipEvent);
}Extended listener that also receives initial membership information.
import com.hazelcast.cluster.InitialMembershipListener;
import com.hazelcast.cluster.InitialMembershipEvent;
public interface InitialMembershipListener extends MembershipListener {
void init(InitialMembershipEvent event);
}Contains information about membership change events.
import com.hazelcast.cluster.MembershipEvent;
import com.hazelcast.cluster.Member;
import java.util.Set;
public class MembershipEvent {
public static final int MEMBER_ADDED = 1;
public static final int MEMBER_REMOVED = 2;
// Event information
public Cluster getCluster();
public Member getMember();
public int getEventType();
public Set<Member> getMembers();
}// Add membership listener
UUID listenerId = cluster.addMembershipListener(new MembershipListener() {
@Override
public void memberAdded(MembershipEvent membershipEvent) {
Member member = membershipEvent.getMember();
System.out.println("Member joined: " + member.getAddress());
System.out.println("Cluster size: " + membershipEvent.getMembers().size());
// Notify other systems about new member
notifyMemberAdded(member);
}
@Override
public void memberRemoved(MembershipEvent membershipEvent) {
Member member = membershipEvent.getMember();
System.out.println("Member left: " + member.getAddress());
System.out.println("Cluster size: " + membershipEvent.getMembers().size());
// Handle member departure
handleMemberDeparture(member);
}
});
// Initial membership listener
cluster.addMembershipListener(new InitialMembershipListener() {
@Override
public void init(InitialMembershipEvent event) {
System.out.println("Initial cluster members:");
for (Member member : event.getMembers()) {
System.out.println(" " + member.getAddress());
}
}
@Override
public void memberAdded(MembershipEvent event) {
System.out.println("New member joined: " + event.getMember().getAddress());
}
@Override
public void memberRemoved(MembershipEvent event) {
System.out.println("Member left: " + event.getMember().getAddress());
}
});
// Remove listener when no longer needed
cluster.removeMembershipListener(listenerId);Defines the operational states of the cluster.
import com.hazelcast.cluster.ClusterState;
public enum ClusterState {
ACTIVE, // Normal operation mode
NO_MIGRATION, // Partition migrations are disabled
FROZEN, // No new members can join
PASSIVE, // All operations are disabled except reads
IN_TRANSITION // Cluster is changing state
}// Get current cluster state
ClusterState currentState = cluster.getClusterState();
System.out.println("Current cluster state: " + currentState);
// Change cluster state
switch (currentState) {
case ACTIVE:
// Temporarily disable migrations for maintenance
cluster.changeClusterState(ClusterState.NO_MIGRATION);
performMaintenance();
cluster.changeClusterState(ClusterState.ACTIVE);
break;
case NO_MIGRATION:
// Re-enable migrations
cluster.changeClusterState(ClusterState.ACTIVE);
break;
case FROZEN:
// Unfreeze cluster
cluster.changeClusterState(ClusterState.ACTIVE);
break;
}
// Emergency cluster freeze
public void emergencyFreeze() {
try {
cluster.changeClusterState(ClusterState.FROZEN);
System.out.println("Cluster frozen for emergency maintenance");
} catch (Exception e) {
System.err.println("Failed to freeze cluster: " + e.getMessage());
}
}Represents version information for cluster members.
import com.hazelcast.version.Version;
public class Version implements Comparable<Version> {
// Version components
public int getMajor();
public int getMinor();
public int getPatch();
// Version information
public boolean isUnknown();
// String representation
public String toString();
// Comparison
public int compareTo(Version other);
public boolean equals(Object obj);
}// Get cluster version
Version clusterVersion = cluster.getClusterVersion();
System.out.println("Cluster version: " + clusterVersion);
// Check if all members are compatible
Set<Member> members = cluster.getMembers();
boolean allCompatible = true;
for (Member member : members) {
Version memberVersion = member.getVersion();
if (memberVersion.compareTo(clusterVersion) != 0) {
System.out.println("Member " + member.getAddress() +
" has different version: " + memberVersion);
allCompatible = false;
}
}
if (allCompatible) {
System.out.println("All members have compatible versions");
}
// Upgrade cluster version (rolling upgrade scenario)
Version newVersion = Version.of(5, 3, 0);
try {
cluster.changeClusterVersion(newVersion);
System.out.println("Cluster upgraded to version: " + newVersion);
} catch (Exception e) {
System.err.println("Failed to upgrade cluster version: " + e.getMessage());
}Manages cluster data partitioning and distribution.
import com.hazelcast.partition.PartitionService;
import com.hazelcast.partition.Partition;
import com.hazelcast.partition.PartitionLostListener;
import java.util.Set;
import java.util.UUID;
public interface PartitionService {
// Partition information
Set<Partition> getPartitions();
Partition getPartition(Object key);
// Random partition
Partition getRandomPartition();
// Migration and safety
boolean isClusterSafe();
boolean isMemberSafe(Member member);
boolean isLocalMemberSafe();
boolean forceLocalMemberToBeSafe(long timeout, TimeUnit unit);
// Partition loss events
UUID addPartitionLostListener(PartitionLostListener partitionLostListener);
boolean removePartitionLostListener(UUID registrationId);
// Migration listener
UUID addMigrationListener(MigrationListener migrationListener);
boolean removeMigrationListener(UUID registrationId);
}Represents a single partition in the cluster.
import com.hazelcast.partition.Partition;
import com.hazelcast.cluster.Member;
public interface Partition {
// Partition identification
int getPartitionId();
// Owner information
Member getOwner();
// Replica information
Member getReplicaAddress(int replicaIndex);
boolean isOwnerOrBackup(Member member);
}PartitionService partitionService = hz.getPartitionService();
// Check cluster safety
boolean clusterSafe = partitionService.isClusterSafe();
System.out.println("Cluster is safe: " + clusterSafe);
if (!clusterSafe) {
System.out.println("Waiting for cluster to become safe...");
boolean becameSafe = partitionService.forceLocalMemberToBeSafe(30, TimeUnit.SECONDS);
if (becameSafe) {
System.out.println("Cluster is now safe");
} else {
System.out.println("Timeout waiting for cluster safety");
}
}
// Get partition for a specific key
String key = "user:12345";
Partition partition = partitionService.getPartition(key);
System.out.println("Key '" + key + "' belongs to partition " + partition.getPartitionId());
System.out.println("Partition owner: " + partition.getOwner());
// Check all partitions
Set<Partition> partitions = partitionService.getPartitions();
System.out.println("Total partitions: " + partitions.size());
Map<Member, Integer> partitionCounts = new HashMap<>();
for (Partition p : partitions) {
Member owner = p.getOwner();
partitionCounts.put(owner, partitionCounts.getOrDefault(owner, 0) + 1);
}
System.out.println("Partition distribution:");
for (Map.Entry<Member, Integer> entry : partitionCounts.entrySet()) {
System.out.println(" " + entry.getKey().getAddress() + ": " + entry.getValue() + " partitions");
}import com.hazelcast.partition.PartitionLostListener;
import com.hazelcast.partition.PartitionLostEvent;
// Add partition loss listener
UUID listenerId = partitionService.addPartitionLostListener(new PartitionLostListener() {
@Override
public void partitionLost(PartitionLostEvent event) {
int partitionId = event.getPartitionId();
int lostBackupCount = event.getLostBackupCount();
Member eventSource = event.getEventSource();
System.err.println("PARTITION LOST!");
System.err.println(" Partition ID: " + partitionId);
System.err.println(" Lost backups: " + lostBackupCount);
System.err.println(" Source: " + eventSource);
// Handle partition loss
handlePartitionLoss(partitionId);
// Alert monitoring systems
alertPartitionLoss(partitionId, lostBackupCount);
}
});
// Remove listener when done
partitionService.removePartitionLostListener(listenerId);Interface for selecting specific members based on criteria.
import com.hazelcast.cluster.MemberSelector;
import com.hazelcast.cluster.Member;
public interface MemberSelector {
boolean select(Member member);
}import com.hazelcast.cluster.memberlist.MemberListJoinConfig;
// Select only data members (non-lite members)
MemberSelector dataMembers = member -> !member.isLiteMember();
// Select members by attribute
MemberSelector webServers = member -> "web-server".equals(member.getAttribute("server-type"));
// Select members by version
Version targetVersion = Version.of(5, 3, 0);
MemberSelector compatibleMembers = member -> member.getVersion().compareTo(targetVersion) >= 0;
// Use selectors
Set<Member> allMembers = cluster.getMembers();
Set<Member> selectedMembers = allMembers.stream()
.filter(dataMembers::select)
.collect(Collectors.toSet());
System.out.println("Data members: " + selectedMembers.size());public void safeClusterShutdown() {
try {
// Wait for cluster to be in a safe state
PartitionService partitionService = hz.getPartitionService();
boolean safe = partitionService.forceLocalMemberToBeSafe(60, TimeUnit.SECONDS);
if (!safe) {
System.out.println("Warning: Cluster not in safe state, proceeding anyway");
}
// Gracefully shutdown the cluster
cluster.shutdown();
System.out.println("Cluster shutdown initiated");
} catch (Exception e) {
System.err.println("Error during cluster shutdown: " + e.getMessage());
}
}// Check if local member is lite member
Member localMember = cluster.getLocalMember();
if (localMember.isLiteMember()) {
System.out.println("This is a lite member (client-like, no data storage)");
// Promote lite member to full data member
try {
cluster.promoteLocalLiteMember();
System.out.println("Lite member promoted to data member");
} catch (Exception e) {
System.err.println("Failed to promote lite member: " + e.getMessage());
}
} else {
System.out.println("This is a data member");
}
// Count lite vs data members
Set<Member> members = cluster.getMembers();
long liteMemberCount = members.stream().filter(Member::isLiteMember).count();
long dataMemberCount = members.size() - liteMemberCount;
System.out.println("Cluster composition:");
System.out.println(" Data members: " + dataMemberCount);
System.out.println(" Lite members: " + liteMemberCount);// Configure member attributes in Config
Config config = new Config();
config.getMemberAttributeConfig()
.setAttribute("server-type", "application")
.setAttribute("region", "us-east-1")
.setAttribute("rack", "rack-1")
.setAttribute("zone", "zone-a");
HazelcastInstance hz = Hazelcast.newHazelcastInstance(config);
// Use attributes for member selection
Cluster cluster = hz.getCluster();
Member localMember = cluster.getLocalMember();
System.out.println("Local member attributes:");
Map<String, String> attributes = localMember.getAttributes();
for (Map.Entry<String, String> attr : attributes.entrySet()) {
System.out.println(" " + attr.getKey() + ": " + attr.getValue());
}
// Find members in same region
String localRegion = localMember.getAttribute("region");
Set<Member> sameRegionMembers = cluster.getMembers().stream()
.filter(member -> localRegion.equals(member.getAttribute("region")))
.collect(Collectors.toSet());
System.out.println("Members in same region (" + localRegion + "): " + sameRegionMembers.size());// Get cluster-wide synchronized time
long clusterTime = cluster.getClusterTime();
long localTime = System.currentTimeMillis();
long timeDiff = clusterTime - localTime;
System.out.println("Cluster time: " + new Date(clusterTime));
System.out.println("Local time: " + new Date(localTime));
System.out.println("Time difference: " + timeDiff + "ms");
// Use cluster time for distributed timestamps
public class TimestampedEvent {
private final long timestamp;
private final String data;
public TimestampedEvent(String data, Cluster cluster) {
this.timestamp = cluster.getClusterTime();
this.data = data;
}
public long getTimestamp() { return timestamp; }
public String getData() { return data; }
}public class ClusterHealthMonitor {
private final Cluster cluster;
private final PartitionService partitionService;
public ClusterHealthMonitor(HazelcastInstance hz) {
this.cluster = hz.getCluster();
this.partitionService = hz.getPartitionService();
}
public ClusterHealth checkHealth() {
Set<Member> members = cluster.getMembers();
boolean clusterSafe = partitionService.isClusterSafe();
ClusterState state = cluster.getClusterState();
return new ClusterHealth(
members.size(),
state,
clusterSafe,
getPartitionDistribution(),
getVersionCompatibility()
);
}
private Map<Member, Integer> getPartitionDistribution() {
Map<Member, Integer> distribution = new HashMap<>();
for (Partition partition : partitionService.getPartitions()) {
Member owner = partition.getOwner();
if (owner != null) {
distribution.put(owner, distribution.getOrDefault(owner, 0) + 1);
}
}
return distribution;
}
private boolean getVersionCompatibility() {
Version clusterVersion = cluster.getClusterVersion();
return cluster.getMembers().stream()
.allMatch(member -> member.getVersion().equals(clusterVersion));
}
}
// Usage
ClusterHealthMonitor monitor = new ClusterHealthMonitor(hz);
ClusterHealth health = monitor.checkHealth();
if (health.isHealthy()) {
System.out.println("Cluster is healthy");
} else {
System.out.println("Cluster health issues detected:");
health.getIssues().forEach(System.out::println);
}Install with Tessl CLI
npx tessl i tessl/maven-com-hazelcast--hazelcast