Class PartitionRouter
Routing pipeline: hash(key) -> partition -> raftGroup -> leader node
Uses MurmurHash3 for consistent, well-distributed key hashing across 271 partitions (prime number for better distribution). Partitions are then mapped to Raft groups, each running an independent consensus instance.
Thread Safety: Partition assignments are updated atomically under a
write lock. All read operations use a read lock for concurrent access.
The volatile partitionToGroup array reference provides an additional
fast-path for snapshot reads.
Failure Handling: When a Raft group leader is unavailable, callers should retry after a leader election completes. The router itself does not block on leader availability.
- Since:
- 2.0
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intDefault number of partitions (271 -- prime for better distribution). -
Constructor Summary
ConstructorsConstructorDescriptionPartitionRouter(int numPartitions, RaftGroupManagerApi raftGroupManager) Creates a router with the specified partition count and a single Raft group.PartitionRouter(int numPartitions, RaftGroupManagerApi raftGroupManager, PartitioningStrategy<Object> partitioningStrategy) Creates a router with the specified partition count, Raft manager, and partitioning strategy.PartitionRouter(RaftGroupManagerApi raftGroupManager) Creates a router with the default partition count (271) and a single Raft group. -
Method Summary
Modifier and TypeMethodDescriptionvoidapplyMapping(int[] mapping) Applies a specific partition-to-group mapping.Returns an immutable snapshot of the current partition assignment.@Nullable StringgetLeaderForKey(Object key) Returns the leader node ID for the Raft group that owns the given key object.@Nullable StringgetLeaderForKey(String key) Returns the leader node ID for the Raft group that owns the given key.intgetPartition(Object key) Computes the partition ID for a key object, honoringPartitionAwarekeys.intgetPartition(String key) Computes the partition ID for a given key using MurmurHash3.intgetRaftGroup(Object key) Determines which Raft group owns the given key object.intgetRaftGroup(String key) Determines which Raft group owns the given key.intgetRaftGroupForPartition(int partitionId) Returns the Raft group ID that owns the specified partition.getRaftNodeForKey(Object key) Returns the RaftNode for the group that owns the given key object.getRaftNodeForKey(String key) Returns the RaftNode for the group that owns the given key.longMonotonic rebalance revision — increments on everyrebalance(int)andapplyMapping(int[]), and is preserved or advanced on snapshot restore.intgetWriteOwnerForPartition(int partitionId) Returns the group that should currently receive writes for the specified partition.voidrebalance(int numGroups) Rebalances partitions evenly across the specified number of Raft groups.voidrestoreFromSnapshot(HashMap<String, Object> snapshot) Restores the partition-to-group mapping from a Raft snapshot.Creates a serializable snapshot of the partition-to-group mapping.
-
Field Details
-
DEFAULT_NUM_PARTITIONS
public static final int DEFAULT_NUM_PARTITIONSDefault number of partitions (271 -- prime for better distribution).- See Also:
-
-
Constructor Details
-
PartitionRouter
Creates a router with the default partition count (271) and a single Raft group.- Parameters:
raftGroupManager- the Raft group manager for group lookups (must not be null)
-
PartitionRouter
Creates a router with the specified partition count and a single Raft group.All partitions are initially assigned to group 0. Call
rebalance(int)to redistribute across multiple groups.- Parameters:
numPartitions- the number of partitions (must be > 0)raftGroupManager- the Raft group manager (must not be null)
-
PartitionRouter
public PartitionRouter(int numPartitions, RaftGroupManagerApi raftGroupManager, PartitioningStrategy<Object> partitioningStrategy) Creates a router with the specified partition count, Raft manager, and partitioning strategy.- Parameters:
numPartitions- the number of partitions (must be > 0)raftGroupManager- the Raft group manager (must not be null)partitioningStrategy- fallback strategy for non-PartitionAware keys (must not be null)
-
-
Method Details
-
getPartition
Computes the partition ID for a given key using MurmurHash3.- Parameters:
key- the key to route (must not be null)- Returns:
- the partition ID (0 to numPartitions-1)
-
getPartition
Computes the partition ID for a key object, honoringPartitionAwarekeys.- Parameters:
key- the key to route (must not be null)- Returns:
- the partition ID (0 to numPartitions-1)
-
getRaftGroup
Determines which Raft group owns the given key.- Parameters:
key- the key to route (must not be null)- Returns:
- the Raft group ID that owns this key's partition
-
getRaftGroup
Determines which Raft group owns the given key object.- Parameters:
key- the key to route (must not be null)- Returns:
- the Raft group ID that owns this key's partition
-
getRaftGroupForPartition
public int getRaftGroupForPartition(int partitionId) Returns the Raft group ID that owns the specified partition.- Parameters:
partitionId- the partition ID (0 to numPartitions-1)- Returns:
- the Raft group ID owning this partition
-
getWriteOwnerForPartition
public int getWriteOwnerForPartition(int partitionId) Returns the group that should currently receive writes for the specified partition.During migration this may temporarily differ from the committed routing table while source-side writes are redirected before cleanup completes.
- Parameters:
partitionId- the partition ID (0 to numPartitions-1)- Returns:
- the write owner group for this partition
-
getRaftNodeForKey
Returns the RaftNode for the group that owns the given key.- Parameters:
key- the key to route (must not be null)- Returns:
- the RaftNode for the owning group (never null)
-
getRaftNodeForKey
Returns the RaftNode for the group that owns the given key object.- Parameters:
key- the key to route (must not be null)- Returns:
- the RaftNode for the owning group (never null)
-
getLeaderForKey
-
getLeaderForKey
-
rebalance
public void rebalance(int numGroups) Rebalances partitions evenly across the specified number of Raft groups.Uses round-robin assignment: partition
iis assigned to groupi % numGroups. This ensures even distribution with at most 1 partition difference between any two groups.- Parameters:
numGroups- the target number of Raft groups (must be > 0)
-
applyMapping
public void applyMapping(int[] mapping) Applies a specific partition-to-group mapping.Used during migration to set precise partition ownership rather than the default round-robin distribution.
- Parameters:
mapping- the new mapping array (length must equal numPartitions)
-
getRevision
public long getRevision()Monotonic rebalance revision — increments on everyrebalance(int)andapplyMapping(int[]), and is preserved or advanced on snapshot restore. Clients polling the partition table use this to reject stale out-of-order refresh responses.- Returns:
- the current revision (never decreases across the lifetime of this router)
- Since:
- 2.1
-
toSnapshot
Creates a serializable snapshot of the partition-to-group mapping.The mapping array is cloned under the read lock to capture a consistent point-in-time view. This allows the partition layout to survive node crashes via the Raft snapshot system.
- Returns:
- a HashMap containing the partition count and mapping array
-
restoreFromSnapshot
Restores the partition-to-group mapping from a Raft snapshot.If the mapping length matches the configured partition count, it is applied atomically with the persisted revision. Missing or malformed mappings fail closed so data structures are not restored under an unrelated/default routing layout.
- Parameters:
snapshot- the snapshot data previously produced bytoSnapshot()
-
getAssignment
Returns an immutable snapshot of the current partition assignment.- Returns:
- the current assignment (never null)
-