0
# Cluster Management
1
2
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.
3
4
## Cluster Interface
5
6
The main interface for cluster-wide operations and membership management.
7
8
```java { .api }
9
import com.hazelcast.cluster.Cluster;
10
import com.hazelcast.cluster.Member;
11
import com.hazelcast.cluster.MembershipListener;
12
import com.hazelcast.cluster.ClusterState;
13
import com.hazelcast.version.Version;
14
import java.util.Set;
15
import java.util.UUID;
16
17
public interface Cluster {
18
// Membership information
19
Set<Member> getMembers();
20
Member getLocalMember();
21
22
// Membership events
23
UUID addMembershipListener(MembershipListener listener);
24
boolean removeMembershipListener(UUID registrationId);
25
26
// Cluster time
27
long getClusterTime();
28
29
// Cluster state management
30
ClusterState getClusterState();
31
void changeClusterState(ClusterState newState);
32
void changeClusterState(ClusterState newState, TransactionOptions transactionOptions);
33
34
// Version management
35
Version getClusterVersion();
36
void changeClusterVersion(Version version);
37
38
// Cluster operations
39
void shutdown();
40
void shutdown(TransactionOptions transactionOptions);
41
42
// Lite member promotion
43
void promoteLocalLiteMember();
44
}
45
```
46
47
### Getting Cluster Interface
48
49
```java { .api }
50
HazelcastInstance hz = Hazelcast.newHazelcastInstance();
51
Cluster cluster = hz.getCluster();
52
```
53
54
## Member Management
55
56
### Member Interface
57
58
Represents information about a cluster member.
59
60
```java { .api }
61
import com.hazelcast.cluster.Member;
62
import com.hazelcast.cluster.Address;
63
import java.util.Map;
64
import java.util.UUID;
65
66
public interface Member extends Endpoint {
67
// Member identification
68
UUID getUuid();
69
Address getAddress();
70
Map<String, String> getAttributes();
71
String getAttribute(String key);
72
73
// Member properties
74
boolean isLiteMember();
75
Version getVersion();
76
77
// Address information
78
Address getSocketAddress();
79
80
// Lite member status
81
boolean isLocalMember();
82
}
83
```
84
85
### Address Class
86
87
Network address information for cluster members.
88
89
```java { .api }
90
import com.hazelcast.cluster.Address;
91
import java.net.InetAddress;
92
import java.net.InetSocketAddress;
93
94
public class Address {
95
// Constructors
96
public Address(String host, int port);
97
public Address(InetAddress inetAddress, int port);
98
public Address(InetSocketAddress inetSocketAddress);
99
100
// Address information
101
public String getHost();
102
public int getPort();
103
public InetAddress getInetAddress();
104
public InetSocketAddress getInetSocketAddress();
105
106
// Scope and type information
107
public String getScopeId();
108
public boolean isIPv4();
109
public boolean isIPv6();
110
}
111
```
112
113
### Member Information Examples
114
115
```java { .api }
116
Cluster cluster = hz.getCluster();
117
118
// Get all members
119
Set<Member> members = cluster.getMembers();
120
System.out.println("Cluster has " + members.size() + " members");
121
122
for (Member member : members) {
123
System.out.println("Member: " + member.getAddress());
124
System.out.println(" UUID: " + member.getUuid());
125
System.out.println(" Lite member: " + member.isLiteMember());
126
System.out.println(" Version: " + member.getVersion());
127
128
// Member attributes
129
Map<String, String> attributes = member.getAttributes();
130
for (Map.Entry<String, String> attr : attributes.entrySet()) {
131
System.out.println(" " + attr.getKey() + ": " + attr.getValue());
132
}
133
}
134
135
// Get local member
136
Member localMember = cluster.getLocalMember();
137
System.out.println("Local member: " + localMember.getAddress());
138
System.out.println("Is lite member: " + localMember.isLiteMember());
139
```
140
141
## Membership Events
142
143
### MembershipListener Interface
144
145
Listens for member join and leave events in the cluster.
146
147
```java { .api }
148
import com.hazelcast.cluster.MembershipListener;
149
import com.hazelcast.cluster.MembershipEvent;
150
151
public interface MembershipListener {
152
void memberAdded(MembershipEvent membershipEvent);
153
void memberRemoved(MembershipEvent membershipEvent);
154
}
155
```
156
157
### InitialMembershipListener Interface
158
159
Extended listener that also receives initial membership information.
160
161
```java { .api }
162
import com.hazelcast.cluster.InitialMembershipListener;
163
import com.hazelcast.cluster.InitialMembershipEvent;
164
165
public interface InitialMembershipListener extends MembershipListener {
166
void init(InitialMembershipEvent event);
167
}
168
```
169
170
### MembershipEvent Class
171
172
Contains information about membership change events.
173
174
```java { .api }
175
import com.hazelcast.cluster.MembershipEvent;
176
import com.hazelcast.cluster.Member;
177
import java.util.Set;
178
179
public class MembershipEvent {
180
public static final int MEMBER_ADDED = 1;
181
public static final int MEMBER_REMOVED = 2;
182
183
// Event information
184
public Cluster getCluster();
185
public Member getMember();
186
public int getEventType();
187
public Set<Member> getMembers();
188
}
189
```
190
191
### Membership Event Handling
192
193
```java { .api }
194
// Add membership listener
195
UUID listenerId = cluster.addMembershipListener(new MembershipListener() {
196
@Override
197
public void memberAdded(MembershipEvent membershipEvent) {
198
Member member = membershipEvent.getMember();
199
System.out.println("Member joined: " + member.getAddress());
200
System.out.println("Cluster size: " + membershipEvent.getMembers().size());
201
202
// Notify other systems about new member
203
notifyMemberAdded(member);
204
}
205
206
@Override
207
public void memberRemoved(MembershipEvent membershipEvent) {
208
Member member = membershipEvent.getMember();
209
System.out.println("Member left: " + member.getAddress());
210
System.out.println("Cluster size: " + membershipEvent.getMembers().size());
211
212
// Handle member departure
213
handleMemberDeparture(member);
214
}
215
});
216
217
// Initial membership listener
218
cluster.addMembershipListener(new InitialMembershipListener() {
219
@Override
220
public void init(InitialMembershipEvent event) {
221
System.out.println("Initial cluster members:");
222
for (Member member : event.getMembers()) {
223
System.out.println(" " + member.getAddress());
224
}
225
}
226
227
@Override
228
public void memberAdded(MembershipEvent event) {
229
System.out.println("New member joined: " + event.getMember().getAddress());
230
}
231
232
@Override
233
public void memberRemoved(MembershipEvent event) {
234
System.out.println("Member left: " + event.getMember().getAddress());
235
}
236
});
237
238
// Remove listener when no longer needed
239
cluster.removeMembershipListener(listenerId);
240
```
241
242
## Cluster State Management
243
244
### ClusterState Enum
245
246
Defines the operational states of the cluster.
247
248
```java { .api }
249
import com.hazelcast.cluster.ClusterState;
250
251
public enum ClusterState {
252
ACTIVE, // Normal operation mode
253
NO_MIGRATION, // Partition migrations are disabled
254
FROZEN, // No new members can join
255
PASSIVE, // All operations are disabled except reads
256
IN_TRANSITION // Cluster is changing state
257
}
258
```
259
260
### Cluster State Operations
261
262
```java { .api }
263
// Get current cluster state
264
ClusterState currentState = cluster.getClusterState();
265
System.out.println("Current cluster state: " + currentState);
266
267
// Change cluster state
268
switch (currentState) {
269
case ACTIVE:
270
// Temporarily disable migrations for maintenance
271
cluster.changeClusterState(ClusterState.NO_MIGRATION);
272
performMaintenance();
273
cluster.changeClusterState(ClusterState.ACTIVE);
274
break;
275
276
case NO_MIGRATION:
277
// Re-enable migrations
278
cluster.changeClusterState(ClusterState.ACTIVE);
279
break;
280
281
case FROZEN:
282
// Unfreeze cluster
283
cluster.changeClusterState(ClusterState.ACTIVE);
284
break;
285
}
286
287
// Emergency cluster freeze
288
public void emergencyFreeze() {
289
try {
290
cluster.changeClusterState(ClusterState.FROZEN);
291
System.out.println("Cluster frozen for emergency maintenance");
292
} catch (Exception e) {
293
System.err.println("Failed to freeze cluster: " + e.getMessage());
294
}
295
}
296
```
297
298
## Version Management
299
300
### Version Class
301
302
Represents version information for cluster members.
303
304
```java { .api }
305
import com.hazelcast.version.Version;
306
307
public class Version implements Comparable<Version> {
308
// Version components
309
public int getMajor();
310
public int getMinor();
311
public int getPatch();
312
313
// Version information
314
public boolean isUnknown();
315
316
// String representation
317
public String toString();
318
319
// Comparison
320
public int compareTo(Version other);
321
public boolean equals(Object obj);
322
}
323
```
324
325
### Cluster Version Management
326
327
```java { .api }
328
// Get cluster version
329
Version clusterVersion = cluster.getClusterVersion();
330
System.out.println("Cluster version: " + clusterVersion);
331
332
// Check if all members are compatible
333
Set<Member> members = cluster.getMembers();
334
boolean allCompatible = true;
335
336
for (Member member : members) {
337
Version memberVersion = member.getVersion();
338
if (memberVersion.compareTo(clusterVersion) != 0) {
339
System.out.println("Member " + member.getAddress() +
340
" has different version: " + memberVersion);
341
allCompatible = false;
342
}
343
}
344
345
if (allCompatible) {
346
System.out.println("All members have compatible versions");
347
}
348
349
// Upgrade cluster version (rolling upgrade scenario)
350
Version newVersion = Version.of(5, 3, 0);
351
try {
352
cluster.changeClusterVersion(newVersion);
353
System.out.println("Cluster upgraded to version: " + newVersion);
354
} catch (Exception e) {
355
System.err.println("Failed to upgrade cluster version: " + e.getMessage());
356
}
357
```
358
359
## Partition Management
360
361
### PartitionService Interface
362
363
Manages cluster data partitioning and distribution.
364
365
```java { .api }
366
import com.hazelcast.partition.PartitionService;
367
import com.hazelcast.partition.Partition;
368
import com.hazelcast.partition.PartitionLostListener;
369
import java.util.Set;
370
import java.util.UUID;
371
372
public interface PartitionService {
373
// Partition information
374
Set<Partition> getPartitions();
375
Partition getPartition(Object key);
376
377
// Random partition
378
Partition getRandomPartition();
379
380
// Migration and safety
381
boolean isClusterSafe();
382
boolean isMemberSafe(Member member);
383
boolean isLocalMemberSafe();
384
boolean forceLocalMemberToBeSafe(long timeout, TimeUnit unit);
385
386
// Partition loss events
387
UUID addPartitionLostListener(PartitionLostListener partitionLostListener);
388
boolean removePartitionLostListener(UUID registrationId);
389
390
// Migration listener
391
UUID addMigrationListener(MigrationListener migrationListener);
392
boolean removeMigrationListener(UUID registrationId);
393
}
394
```
395
396
### Partition Interface
397
398
Represents a single partition in the cluster.
399
400
```java { .api }
401
import com.hazelcast.partition.Partition;
402
import com.hazelcast.cluster.Member;
403
404
public interface Partition {
405
// Partition identification
406
int getPartitionId();
407
408
// Owner information
409
Member getOwner();
410
411
// Replica information
412
Member getReplicaAddress(int replicaIndex);
413
boolean isOwnerOrBackup(Member member);
414
}
415
```
416
417
### Partition Management Examples
418
419
```java { .api }
420
PartitionService partitionService = hz.getPartitionService();
421
422
// Check cluster safety
423
boolean clusterSafe = partitionService.isClusterSafe();
424
System.out.println("Cluster is safe: " + clusterSafe);
425
426
if (!clusterSafe) {
427
System.out.println("Waiting for cluster to become safe...");
428
boolean becameSafe = partitionService.forceLocalMemberToBeSafe(30, TimeUnit.SECONDS);
429
if (becameSafe) {
430
System.out.println("Cluster is now safe");
431
} else {
432
System.out.println("Timeout waiting for cluster safety");
433
}
434
}
435
436
// Get partition for a specific key
437
String key = "user:12345";
438
Partition partition = partitionService.getPartition(key);
439
System.out.println("Key '" + key + "' belongs to partition " + partition.getPartitionId());
440
System.out.println("Partition owner: " + partition.getOwner());
441
442
// Check all partitions
443
Set<Partition> partitions = partitionService.getPartitions();
444
System.out.println("Total partitions: " + partitions.size());
445
446
Map<Member, Integer> partitionCounts = new HashMap<>();
447
for (Partition p : partitions) {
448
Member owner = p.getOwner();
449
partitionCounts.put(owner, partitionCounts.getOrDefault(owner, 0) + 1);
450
}
451
452
System.out.println("Partition distribution:");
453
for (Map.Entry<Member, Integer> entry : partitionCounts.entrySet()) {
454
System.out.println(" " + entry.getKey().getAddress() + ": " + entry.getValue() + " partitions");
455
}
456
```
457
458
### Partition Loss Handling
459
460
```java { .api }
461
import com.hazelcast.partition.PartitionLostListener;
462
import com.hazelcast.partition.PartitionLostEvent;
463
464
// Add partition loss listener
465
UUID listenerId = partitionService.addPartitionLostListener(new PartitionLostListener() {
466
@Override
467
public void partitionLost(PartitionLostEvent event) {
468
int partitionId = event.getPartitionId();
469
int lostBackupCount = event.getLostBackupCount();
470
Member eventSource = event.getEventSource();
471
472
System.err.println("PARTITION LOST!");
473
System.err.println(" Partition ID: " + partitionId);
474
System.err.println(" Lost backups: " + lostBackupCount);
475
System.err.println(" Source: " + eventSource);
476
477
// Handle partition loss
478
handlePartitionLoss(partitionId);
479
480
// Alert monitoring systems
481
alertPartitionLoss(partitionId, lostBackupCount);
482
}
483
});
484
485
// Remove listener when done
486
partitionService.removePartitionLostListener(listenerId);
487
```
488
489
## Member Selection and Filtering
490
491
### MemberSelector Interface
492
493
Interface for selecting specific members based on criteria.
494
495
```java { .api }
496
import com.hazelcast.cluster.MemberSelector;
497
import com.hazelcast.cluster.Member;
498
499
public interface MemberSelector {
500
boolean select(Member member);
501
}
502
```
503
504
### Built-in Member Selectors
505
506
```java { .api }
507
import com.hazelcast.cluster.memberlist.MemberListJoinConfig;
508
509
// Select only data members (non-lite members)
510
MemberSelector dataMembers = member -> !member.isLiteMember();
511
512
// Select members by attribute
513
MemberSelector webServers = member -> "web-server".equals(member.getAttribute("server-type"));
514
515
// Select members by version
516
Version targetVersion = Version.of(5, 3, 0);
517
MemberSelector compatibleMembers = member -> member.getVersion().compareTo(targetVersion) >= 0;
518
519
// Use selectors
520
Set<Member> allMembers = cluster.getMembers();
521
Set<Member> selectedMembers = allMembers.stream()
522
.filter(dataMembers::select)
523
.collect(Collectors.toSet());
524
525
System.out.println("Data members: " + selectedMembers.size());
526
```
527
528
## Cluster Operations
529
530
### Safe Shutdown
531
532
```java { .api }
533
public void safeClusterShutdown() {
534
try {
535
// Wait for cluster to be in a safe state
536
PartitionService partitionService = hz.getPartitionService();
537
boolean safe = partitionService.forceLocalMemberToBeSafe(60, TimeUnit.SECONDS);
538
539
if (!safe) {
540
System.out.println("Warning: Cluster not in safe state, proceeding anyway");
541
}
542
543
// Gracefully shutdown the cluster
544
cluster.shutdown();
545
System.out.println("Cluster shutdown initiated");
546
547
} catch (Exception e) {
548
System.err.println("Error during cluster shutdown: " + e.getMessage());
549
}
550
}
551
```
552
553
### Lite Member Operations
554
555
```java { .api }
556
// Check if local member is lite member
557
Member localMember = cluster.getLocalMember();
558
if (localMember.isLiteMember()) {
559
System.out.println("This is a lite member (client-like, no data storage)");
560
561
// Promote lite member to full data member
562
try {
563
cluster.promoteLocalLiteMember();
564
System.out.println("Lite member promoted to data member");
565
} catch (Exception e) {
566
System.err.println("Failed to promote lite member: " + e.getMessage());
567
}
568
} else {
569
System.out.println("This is a data member");
570
}
571
572
// Count lite vs data members
573
Set<Member> members = cluster.getMembers();
574
long liteMemberCount = members.stream().filter(Member::isLiteMember).count();
575
long dataMemberCount = members.size() - liteMemberCount;
576
577
System.out.println("Cluster composition:");
578
System.out.println(" Data members: " + dataMemberCount);
579
System.out.println(" Lite members: " + liteMemberCount);
580
```
581
582
## Distributed Coordination
583
584
### Member Attributes Configuration
585
586
```java { .api }
587
// Configure member attributes in Config
588
Config config = new Config();
589
config.getMemberAttributeConfig()
590
.setAttribute("server-type", "application")
591
.setAttribute("region", "us-east-1")
592
.setAttribute("rack", "rack-1")
593
.setAttribute("zone", "zone-a");
594
595
HazelcastInstance hz = Hazelcast.newHazelcastInstance(config);
596
597
// Use attributes for member selection
598
Cluster cluster = hz.getCluster();
599
Member localMember = cluster.getLocalMember();
600
601
System.out.println("Local member attributes:");
602
Map<String, String> attributes = localMember.getAttributes();
603
for (Map.Entry<String, String> attr : attributes.entrySet()) {
604
System.out.println(" " + attr.getKey() + ": " + attr.getValue());
605
}
606
607
// Find members in same region
608
String localRegion = localMember.getAttribute("region");
609
Set<Member> sameRegionMembers = cluster.getMembers().stream()
610
.filter(member -> localRegion.equals(member.getAttribute("region")))
611
.collect(Collectors.toSet());
612
613
System.out.println("Members in same region (" + localRegion + "): " + sameRegionMembers.size());
614
```
615
616
### Cluster Time Synchronization
617
618
```java { .api }
619
// Get cluster-wide synchronized time
620
long clusterTime = cluster.getClusterTime();
621
long localTime = System.currentTimeMillis();
622
long timeDiff = clusterTime - localTime;
623
624
System.out.println("Cluster time: " + new Date(clusterTime));
625
System.out.println("Local time: " + new Date(localTime));
626
System.out.println("Time difference: " + timeDiff + "ms");
627
628
// Use cluster time for distributed timestamps
629
public class TimestampedEvent {
630
private final long timestamp;
631
private final String data;
632
633
public TimestampedEvent(String data, Cluster cluster) {
634
this.timestamp = cluster.getClusterTime();
635
this.data = data;
636
}
637
638
public long getTimestamp() { return timestamp; }
639
public String getData() { return data; }
640
}
641
```
642
643
## Monitoring and Health Checks
644
645
### Cluster Health Monitoring
646
647
```java { .api }
648
public class ClusterHealthMonitor {
649
private final Cluster cluster;
650
private final PartitionService partitionService;
651
652
public ClusterHealthMonitor(HazelcastInstance hz) {
653
this.cluster = hz.getCluster();
654
this.partitionService = hz.getPartitionService();
655
}
656
657
public ClusterHealth checkHealth() {
658
Set<Member> members = cluster.getMembers();
659
boolean clusterSafe = partitionService.isClusterSafe();
660
ClusterState state = cluster.getClusterState();
661
662
return new ClusterHealth(
663
members.size(),
664
state,
665
clusterSafe,
666
getPartitionDistribution(),
667
getVersionCompatibility()
668
);
669
}
670
671
private Map<Member, Integer> getPartitionDistribution() {
672
Map<Member, Integer> distribution = new HashMap<>();
673
for (Partition partition : partitionService.getPartitions()) {
674
Member owner = partition.getOwner();
675
if (owner != null) {
676
distribution.put(owner, distribution.getOrDefault(owner, 0) + 1);
677
}
678
}
679
return distribution;
680
}
681
682
private boolean getVersionCompatibility() {
683
Version clusterVersion = cluster.getClusterVersion();
684
return cluster.getMembers().stream()
685
.allMatch(member -> member.getVersion().equals(clusterVersion));
686
}
687
}
688
689
// Usage
690
ClusterHealthMonitor monitor = new ClusterHealthMonitor(hz);
691
ClusterHealth health = monitor.checkHealth();
692
693
if (health.isHealthy()) {
694
System.out.println("Cluster is healthy");
695
} else {
696
System.out.println("Cluster health issues detected:");
697
health.getIssues().forEach(System.out::println);
698
}
699
```