Partitioning & Sharding
LoomCache uses PartitionRouter, PartitionTable, and a consistent hash ring (ConsistentHashRing) for routing and
ownership planning. Today the default data model is full replication — every node in the single Raft group holds
every partition, so partitioning is primarily an affinity/routing hint rather than a sharded placement strategy. The
ingredients for per-partition Raft groups ship in the sharding/ package and are exercised by tests; production
activation is unsupported/fail-closed until per-group WAL, Raft metadata, snapshot, install-snapshot, and restart
recovery are proven.
Consistent Hash Ring
Keys are hashed to 271 partitions mapped cleanly across virtual nodes, decoupling data from physical servers.
Slot Management
Section titled “Slot Management”Rather than hashing keys directly to nodes, LoomCache hashes sharded-Raft keys to one of 271 routing partitions by default. That count matches Hazelcast’s default partition count and is intentionally small enough for compact client routing-table refreshes.
[!NOTE] Because LoomCache maps through routing partitions and server-side ownership slots instead of hashing directly to nodes, adding or removing a node only requires moving specific slices of the keyspace. That minimizes network impact compared to a traditional mod-N hash ring.
How Keys Map to Partitions
Section titled “How Keys Map to Partitions”partition = MurmurHash3(key) % 271The server publishes PartitionRouter snapshots to clients. The client SDK uses the same hash function for smart
routing — sending requests directly to the owning group without an extra redirect hop — while PartitionTable and
ConsistentHashRing handle server-side ownership planning during membership changes.
Slot Count Tradeoff
Section titled “Slot Count Tradeoff”LoomCache separates three counts that older comparisons sometimes collapsed into “1024 vs 271”:
PartitionRouter.DEFAULT_NUM_PARTITIONS = 271controls smart-client and multi-Raft-group routing.PartitionTable.TOTAL_SLOTS = 16_384controls membership-migration ownership planning.ConsistentHashRing.VNODES_PER_NODE = 256controls how many virtual positions each physical member contributes to the ring; a four-member cluster therefore has 1,024 ring positions.
More slots or virtual nodes make rebalancing smoother because ownership can move in smaller chunks and hot keys are less
likely to cluster on one member. The cost is larger metadata: every owner table, migration preview, and membership
broadcast grows linearly with the slot count. As a rule of thumb, an int routing table is about 1 KiB at 271 entries,
about 4 KiB at 1,024 entries, and about 64 KiB at 16,384 entries before protocol and JVM object overhead. LoomCache keeps
the client-facing routing table at 271 entries and uses the larger slot table only for server-side migration planning.
Partition Distribution
Section titled “Partition Distribution”| Cluster Size | Partitions per Node | Quorum |
|---|---|---|
| 3 nodes | ~90 each | 2 |
| 5 nodes | ~54 each | 3 |
| 7 nodes | ~38 each | 4 |
Partition Migration
Section titled “Partition Migration”Partition Migration (Dynamic Scaling)
Non-blocking state transfer when topologies change
When a development sharded cluster scales out, the PartitionMigrationManager negotiates a new layout via Raft and
streams slot data in the background. This is not a production sharding claim; production must stay on the single-group
model until the recovery gaps above are closed.
Migration Sequence
Section titled “Migration Sequence”- New node joins and announces itself via discovery
PartitionTablecomputes the optimal slot redistribution- Migration plan is committed through Raft consensus (all nodes agree)
- Data streams in the background — source node sends slot data to target
- Individual slots are briefly paused during the ownership handoff
- Client routing tables are updated — subsequent requests go to the new owner
Per-Slot Metrics
Section titled “Per-Slot Metrics”LoomCache tracks fine-grained metrics for each hash slot via SlotMetrics:
- Access count — requests hitting this slot
- Key count — number of keys stored in this slot
- Memory usage — bytes consumed by this slot’s data
Use SlotMetrics.getTopSlots(n) to identify hot partitions and rebalance proactively.
Client-Side Smart Routing
Section titled “Client-Side Smart Routing”The RequestRouter in the client SDK uses the same MurmurHash3 function and partition table to route requests to the
best known owner or leader:
// Client internally computes:int partition = MurmurHash3.hash(key) % 271;NodeInfo owner = partitionTable.getOwner(partition);// Sends request directly to owner — zero redirectsRedirects remain part of the correctness path when leadership or ownership information is stale.