Class RaftGroupManager
- All Implemented Interfaces:
RaftGroupManagerApi
Architecture:
- Each Raft group is an independent RaftNode with its own election, log, and state machine.
- Keys are routed to groups using consistent hashing:
group = "raft-" + (hash(key) % numGroups) - The DEFAULT group ("raft-0") is always present for backward compatibility.
- Removes the single-Raft-group bottleneck for large-scale deployments.
Design Decisions:
- Consistent Hashing: Same key always routes to the same group, enabling sharding.
- Independent Elections: Each group elects its own leader, reducing contention.
- Backward Compatibility: Existing code continues to use the DEFAULT group if numGroups=1.
- Configurable Scale: numGroups default is 1 (no sharding); multi-group sharding remains fail-closed for production until independent durability and recovery evidence is complete.
Thread Safety: All operations are thread-safe using ConcurrentHashMap and atomic comparisons. Multiple threads can safely create and use groups concurrently.
This class manages local sharding of independent RaftNode instances. It does not
implement Raft cluster membership changes for a single group.
- Since:
- 2.0
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringThe default/primary group name (used when numGroups=1 or for compatibility). -
Constructor Summary
ConstructorsConstructorDescriptionRaftGroupManager(String localNodeId, int numGroups, int instanceNumber) Creates a new RaftGroupManager with the specified configuration.RaftGroupManager(String localNodeId, int numGroups, int instanceNumber, long compactionThreshold) -
Method Summary
Modifier and TypeMethodDescriptionintReturns the configured upper bound for Raft group IDs.protected RaftNodecreateRaftNode(String groupName) Creates a RaftNode instance for the given group.Gets all active RaftNode instances.Gets the default group (backward compatible accessor).getGroupForKey(String key) Routes a key to its Raft group using consistent hashing.@Nullable RaftNodegetGroupIfExists(String groupName) Gets a specific Raft group by name, or null if it hasn't been created yet.Gets a snapshot of current group state for monitoring/debugging.intGets the count of currently instantiated groups.getOrCreateGroup(String groupName) Gets or creates a Raft group by name using lazy initialization.booleanChecks if a group has been instantiated.Lists all active (created) Raft groups.voidShuts down all Raft groups gracefully.
-
Field Details
-
DEFAULT_GROUP
The default/primary group name (used when numGroups=1 or for compatibility).- See Also:
-
-
Constructor Details
-
RaftGroupManager
Creates a new RaftGroupManager with the specified configuration.- Parameters:
localNodeId- the ID of the local node for logging/identification (must not be null)numGroups- the number of Raft groups (1 = no sharding)instanceNumber- the instance number for logging (must be >= 0)- Throws:
NullPointerException- if localNodeId is nullIllegalArgumentException- if numGroups invalid input: '<' 1 or instanceNumber invalid input: '<' 0
-
RaftGroupManager
public RaftGroupManager(String localNodeId, int numGroups, int instanceNumber, long compactionThreshold)
-
-
Method Details
-
getOrCreateGroup
Gets or creates a Raft group by name using lazy initialization.Thread-safe: uses computeIfAbsent to ensure only one RaftNode is created per group name, even under concurrent access.
- Specified by:
getOrCreateGroupin interfaceRaftGroupManagerApi- Parameters:
groupName- the group name (typically "raft-N" where N is 0-based index, must not be null)- Returns:
- the RaftNode for this group, creating it on first access (never null)
- Throws:
NullPointerException- if groupName is null
-
getGroupForKey
Routes a key to its Raft group using consistent hashing.Algorithm:
groupIndex = Math.abs(key.hashCode()) % numGroupsGuarantees:
- The same key always routes to the same group (deterministic routing)
- Different keys distribute roughly evenly across groups (load balancing)
- Adding/removing groups causes minimal key remapping
- Specified by:
getGroupForKeyin interfaceRaftGroupManagerApi- Parameters:
key- the key to route (must not be null)- Returns:
- the RaftNode for this key's group (never null)
- Throws:
NullPointerException- if key is null
-
getDefaultGroup
Gets the default group (backward compatible accessor).Use this when you want the single primary group, without key-based routing. This is equivalent to the behavior when
numGroups=1.- Specified by:
getDefaultGroupin interfaceRaftGroupManagerApi- Returns:
- the DEFAULT RaftNode ("raft-0"), never null
-
listGroups
Lists all active (created) Raft groups.- Returns:
- an unmodifiable collection of group names that have been instantiated (never null)
-
getInstantiatedGroupCount
public int getInstantiatedGroupCount()Gets the count of currently instantiated groups.- Returns:
- the number of groups that have been created (0 to numGroups)
-
configuredGroupCount
public int configuredGroupCount()Description copied from interface:RaftGroupManagerApiReturns the configured upper bound for Raft group IDs.Implementations that do not expose a fixed group count may return
Integer.MAX_VALUE, which preserves permissive validation for tests and custom managers.- Specified by:
configuredGroupCountin interfaceRaftGroupManagerApi
-
getGroupIfExists
Gets a specific Raft group by name, or null if it hasn't been created yet.- Specified by:
getGroupIfExistsin interfaceRaftGroupManagerApi- Parameters:
groupName- the group name (must not be null)- Returns:
- the RaftNode if it exists, or
nullif not yet created - Throws:
NullPointerException- if groupName is null
-
hasGroup
Checks if a group has been instantiated.- Specified by:
hasGroupin interfaceRaftGroupManagerApi- Parameters:
groupName- the group name (must not be null)- Returns:
- true if the group has been created, false otherwise
- Throws:
NullPointerException- if groupName is null
-
shutdownAll
public void shutdownAll()Shuts down all Raft groups gracefully.Calls stop() on each RaftNode. After this, the manager is no longer usable and a new instance should be created to continue operations.
Errors stopping individual groups are logged but do not prevent shutdown of other groups.
-
getAllGroups
Gets all active RaftNode instances.- Returns:
- an unmodifiable collection of all instantiated RaftNodes (never null)
-
getGroupSnapshot
-
createRaftNode
-