use of org.infinispan.distribution.ch.impl.DefaultConsistentHash in project infinispan by infinispan.
the class TopologyAwareOwnershipStatistics method testConsistencyWhenNodeLeaves.
public void testConsistencyWhenNodeLeaves() {
addNode(testAddresses[0], "m2", "r0", "s1");
addNode(testAddresses[1], "m1", "r0", "s0");
addNode(testAddresses[2], "m1", "r0", "s1");
addNode(testAddresses[3], "m1", "r1", "s0");
addNode(testAddresses[4], "m0", "r0", "s1");
addNode(testAddresses[5], "m0", "r1", "s1");
addNode(testAddresses[6], "m0", "r1", "s0");
addNode(testAddresses[7], "m0", "r0", "s3");
addNode(testAddresses[8], "m0", "r0", "s2");
addNode(testAddresses[9], "m0", "r0", "s0");
int numOwners = 3;
updateConsistentHash(numOwners);
assertAllLocations(chMembers, numOwners);
assertDistribution(chMembers, numOwners);
for (Address addr : chMembers) {
log.debugf("Removing node %s", addr);
List<Address> addressCopy = new ArrayList<>(chMembers);
addressCopy.remove(addr);
DefaultConsistentHash newCH = chf.updateMembers(ch, addressCopy, null);
newCH = chf.rebalance(newCH);
// Allow a small number of segment moves, even though this is a leave, because the CH factory
// generates extra moves trying to balance the CH.
AtomicInteger movedSegmentsCount = new AtomicInteger(0);
for (int segment = 0; segment < numSegments; segment++) {
checkConsistency(segment, numOwners, addr, newCH, movedSegmentsCount);
}
assert movedSegmentsCount.get() <= numSegments * numOwners * 0.1 : String.format("Too many moved segments after leave: %d. CH after leave is: %s\nPrevious: %s", movedSegmentsCount.get(), newCH, ch);
}
}
use of org.infinispan.distribution.ch.impl.DefaultConsistentHash in project infinispan by infinispan.
the class StateProviderTest method test1.
public void test1() {
// create list of 6 members
List<Address> members1 = Arrays.asList(A, B, C, D, E, F);
List<Address> members2 = new ArrayList<>(members1);
members2.remove(A);
members2.remove(F);
members2.add(G);
// create CHes
KeyPartitioner keyPartitioner = new HashFunctionPartitioner(StateProviderTest.NUM_SEGMENTS);
DefaultConsistentHashFactory chf = new DefaultConsistentHashFactory();
DefaultConsistentHash ch1 = chf.create(2, StateProviderTest.NUM_SEGMENTS, members1, null);
DefaultConsistentHash ch2 = chf.updateMembers(ch1, members2, null);
// create dependencies
when(rpcManager.getAddress()).thenReturn(A);
when(rpcManager.invokeCommand(any(Address.class), any(), any(), any())).thenReturn(new CompletableFuture<>());
// create state provider
StateProviderImpl stateProvider = new StateProviderImpl();
TestingUtil.inject(stateProvider, configuration, rpcManager, commandsFactory, cacheNotifier, persistenceManager, dataContainer, transactionTable, stateTransferLock, distributionManager, ef, keyPartitioner, TransactionOriginatorChecker.LOCAL);
stateProvider.start();
final List<InternalCacheEntry> cacheEntries = new ArrayList<>();
Object key1 = new TestKey("key1", 0, keyPartitioner);
Object key2 = new TestKey("key2", 0, keyPartitioner);
cacheEntries.add(new ImmortalCacheEntry(key1, "value1"));
cacheEntries.add(new ImmortalCacheEntry(key2, "value2"));
when(dataContainer.iterator()).thenAnswer(invocation -> cacheEntries.iterator());
when(transactionTable.getLocalTransactions()).thenReturn(Collections.emptyList());
when(transactionTable.getRemoteTransactions()).thenReturn(Collections.emptyList());
CacheTopology simpleTopology = new CacheTopology(1, 1, ch1, ch1, ch1, CacheTopology.Phase.READ_OLD_WRITE_ALL, ch1.getMembers(), persistentUUIDManager.mapAddresses(ch1.getMembers()));
this.cacheTopology = new LocalizedCacheTopology(CacheMode.DIST_SYNC, simpleTopology, keyPartitioner, A, true);
stateProvider.onTopologyUpdate(this.cacheTopology, false);
log.debug("ch1: " + ch1);
IntSet segmentsToRequest = IntSets.from(ch1.getSegmentsForOwner(members1.get(0)));
CompletionStage<List<TransactionInfo>> transactionsStage = stateProvider.getTransactionsForSegments(members1.get(0), 1, segmentsToRequest);
List<TransactionInfo> transactions = CompletionStages.join(transactionsStage);
assertEquals(0, transactions.size());
CompletionStage<List<TransactionInfo>> transactionsStage2 = stateProvider.getTransactionsForSegments(members1.get(0), 1, SmallIntSet.of(2, StateProviderTest.NUM_SEGMENTS));
Exceptions.expectExecutionException(IllegalArgumentException.class, transactionsStage2.toCompletableFuture());
verifyNoMoreInteractions(stateTransferLock);
when(dataContainer.iterator(any())).thenReturn(cacheEntries.iterator());
when(persistenceManager.publishEntries(any(IntSet.class), any(), anyBoolean(), anyBoolean(), any())).thenReturn(Flowable.empty());
stateProvider.startOutboundTransfer(F, 1, IntSets.immutableSet(0), true);
assertTrue(stateProvider.isStateTransferInProgress());
log.debug("ch2: " + ch2);
simpleTopology = new CacheTopology(2, 1, ch2, ch2, ch2, CacheTopology.Phase.READ_OLD_WRITE_ALL, ch2.getMembers(), persistentUUIDManager.mapAddresses(ch2.getMembers()));
this.cacheTopology = new LocalizedCacheTopology(CacheMode.DIST_SYNC, simpleTopology, keyPartitioner, A, true);
stateProvider.onTopologyUpdate(this.cacheTopology, true);
assertFalse(stateProvider.isStateTransferInProgress());
stateProvider.startOutboundTransfer(D, 1, IntSets.immutableSet(0), true);
assertTrue(stateProvider.isStateTransferInProgress());
stateProvider.stop();
assertFalse(stateProvider.isStateTransferInProgress());
}
use of org.infinispan.distribution.ch.impl.DefaultConsistentHash in project infinispan by infinispan.
the class IndexedJGroupsAddress method computeMetricsAfterRebalance.
protected Map<String, String> computeMetricsAfterRebalance(int numSegments, int numOwners, int numNodes) {
List<Address> members = createAddresses(numNodes);
Map<String, String> metrics = new HashMap<>();
long[] distribution = new long[LOOPS * numNodes];
long[] distributionPrimary = new long[LOOPS * numNodes];
double[] largestRatio = new double[LOOPS];
int distIndex = 0;
ConsistentHashFactory<DefaultConsistentHash> chf = createFactory();
DefaultConsistentHash ch = chf.create(numOwners, numSegments, members, null);
// loop leave/join and rebalance
for (int i = 0; i < LOOPS; i++) {
// leave
members.remove(0);
DefaultConsistentHash rebalancedCH = chf.updateMembers(ch, members, null);
ch = chf.rebalance(rebalancedCH);
// join
Address joiner = createSingleAddress(numNodes + i);
members.add(joiner);
rebalancedCH = chf.updateMembers(ch, members, null);
ch = chf.rebalance(rebalancedCH);
// stats after rebalance
OwnershipStatistics stats = new OwnershipStatistics(ch, ch.getMembers());
assertEquals(numSegments * numOwners, stats.sumOwned());
for (Address node : ch.getMembers()) {
distribution[distIndex] = stats.getOwned(node);
distributionPrimary[distIndex] = stats.getPrimaryOwned(node);
distIndex++;
}
largestRatio[i] = getSegmentsPerNodesMinMaxRatio(ch);
}
Arrays.sort(distribution);
Arrays.sort(distributionPrimary);
Arrays.sort(largestRatio);
addMetrics(metrics, "Any owner:", numSegments, numOwners, numNodes, distribution, INTERVALS);
addMetrics(metrics, "Primary:", numSegments, 1, numNodes, distributionPrimary, INTERVALS_PRIMARY);
addDoubleMetric(metrics, "Segments per node - max/min ratio", largestRatio[largestRatio.length - 1]);
return metrics;
}
use of org.infinispan.distribution.ch.impl.DefaultConsistentHash in project infinispan by infinispan.
the class IndexedJGroupsAddress method computeMetrics.
protected Map<String, String> computeMetrics(int numSegments, int numOwners, int numNodes) {
List<Address> members = createAddresses(numNodes);
Map<String, String> metrics = new HashMap<>();
long[] distribution = new long[LOOPS * numNodes];
long[] distributionPrimary = new long[LOOPS * numNodes];
double[] largestRatio = new double[LOOPS];
int distIndex = 0;
ConsistentHashFactory<DefaultConsistentHash> chf = createFactory();
for (int i = 0; i < LOOPS; i++) {
DefaultConsistentHash ch = chf.create(numOwners, numSegments, members, null);
OwnershipStatistics stats = new OwnershipStatistics(ch, ch.getMembers());
assertEquals(numSegments * numOwners, stats.sumOwned());
for (Address node : ch.getMembers()) {
distribution[distIndex] = stats.getOwned(node);
distributionPrimary[distIndex] = stats.getPrimaryOwned(node);
distIndex++;
}
largestRatio[i] = getSegmentsPerNodesMinMaxRatio(ch);
}
Arrays.sort(distribution);
Arrays.sort(distributionPrimary);
Arrays.sort(largestRatio);
addMetrics(metrics, "Any owner:", numSegments, numOwners, numNodes, distribution, INTERVALS);
addMetrics(metrics, "Primary:", numSegments, 1, numNodes, distributionPrimary, INTERVALS_PRIMARY);
addDoubleMetric(metrics, "Segments per node - max/min ratio", largestRatio[largestRatio.length - 1]);
return metrics;
}
use of org.infinispan.distribution.ch.impl.DefaultConsistentHash in project infinispan by infinispan.
the class WorkDuringJoinTest method testJoinAndGet.
public void testJoinAndGet() {
List<MagicKey> keys = init();
KeyPartitioner keyPartitioner = TestingUtil.extractComponent(c1, KeyPartitioner.class);
ConsistentHash chOld = getCacheTopology(c1).getWriteConsistentHash();
Address joinerAddress = startNewMember();
List<Address> newMembers = new ArrayList<>(chOld.getMembers());
newMembers.add(joinerAddress);
DefaultConsistentHashFactory chf = new DefaultConsistentHashFactory();
ConsistentHash chNew = chf.rebalance(chf.updateMembers((DefaultConsistentHash) chOld, newMembers, null));
// which key should me mapped to the joiner?
MagicKey keyToTest = null;
for (MagicKey k : keys) {
int segment = keyPartitioner.getSegment(k);
if (chNew.isSegmentLocalToNode(joinerAddress, segment)) {
keyToTest = k;
break;
}
}
if (keyToTest == null)
throw new NullPointerException("Couldn't find a key mapped to J!");
assert joiner.get(keyToTest) != null;
}
Aggregations