use of org.apache.ignite.internal.processors.cluster.BaselineTopology in project ignite by apache.
the class GridAffinityAssignmentCache method calculate.
/**
* Calculates ideal assignment for given topology version and events happened since last calculation.
*
* @param topVer Topology version to calculate affinity cache for.
* @param events Discovery events that caused this topology version change.
* @param discoCache Discovery cache.
* @return Ideal affinity assignment.
*/
public IdealAffinityAssignment calculate(AffinityTopologyVersion topVer, @Nullable ExchangeDiscoveryEvents events, @Nullable DiscoCache discoCache) {
if (log.isDebugEnabled())
log.debug("Calculating ideal affinity [topVer=" + topVer + ", locNodeId=" + ctx.localNodeId() + ", discoEvts=" + events + ']');
IdealAffinityAssignment prevAssignment = idealAssignment;
// Already calculated.
if (prevAssignment != null && prevAssignment.topologyVersion().equals(topVer))
return prevAssignment;
// Resolve nodes snapshot for specified topology version.
List<ClusterNode> sorted;
if (!locCache) {
sorted = new ArrayList<>(discoCache.cacheGroupAffinityNodes(groupId()));
sorted.sort(NodeOrderComparator.getInstance());
} else
sorted = Collections.singletonList(ctx.discovery().localNode());
boolean hasBaseline = false;
boolean changedBaseline = false;
BaselineTopology blt = null;
if (discoCache != null) {
blt = discoCache.state().baselineTopology();
hasBaseline = blt != null;
changedBaseline = !hasBaseline ? baselineTopology != null : !blt.equals(baselineTopology);
}
IdealAffinityAssignment assignment;
if (prevAssignment != null && events != null) {
/* Skip affinity calculation only when all nodes triggered exchange
don't belong to affinity for current group (client node or filtered by nodeFilter). */
boolean skipCalculation = true;
for (DiscoveryEvent event : events.events()) {
boolean affinityNode = CU.affinityNode(event.eventNode(), nodeFilter);
if (affinityNode || event.type() == EVT_DISCOVERY_CUSTOM_EVT) {
skipCalculation = false;
break;
}
}
if (hasBaseline && changedBaseline) {
recalculateBaselineAssignment(topVer, events, prevAssignment, sorted, blt);
assignment = IdealAffinityAssignment.create(topVer, sorted, baselineAssignmentWithoutOfflineNodes(discoCache));
} else if (skipCalculation)
assignment = prevAssignment;
else if (hasBaseline) {
if (baselineAssignment == null)
recalculateBaselineAssignment(topVer, events, prevAssignment, sorted, blt);
assignment = IdealAffinityAssignment.create(topVer, sorted, baselineAssignmentWithoutOfflineNodes(discoCache));
} else {
List<List<ClusterNode>> calculated = aff.assignPartitions(new GridAffinityFunctionContextImpl(sorted, prevAssignment.assignment(), events.lastEvent(), topVer, backups));
assignment = IdealAffinityAssignment.create(topVer, sorted, calculated);
}
} else {
if (hasBaseline) {
recalculateBaselineAssignment(topVer, events, prevAssignment, sorted, blt);
assignment = IdealAffinityAssignment.createWithPreservedPrimaries(topVer, baselineAssignmentWithoutOfflineNodes(discoCache), baselineAssignment);
} else {
List<List<ClusterNode>> calculated = aff.assignPartitions(new GridAffinityFunctionContextImpl(sorted, prevAssignment != null ? prevAssignment.assignment() : null, events != null ? events.lastEvent() : null, topVer, backups));
assignment = IdealAffinityAssignment.create(topVer, sorted, calculated);
}
}
assert assignment != null;
idealAssignment = assignment;
if (ctx.cache().cacheMode(cacheOrGrpName) == PARTITIONED && !ctx.clientNode())
printDistributionIfThresholdExceeded(assignment.assignment(), sorted.size());
if (hasBaseline) {
baselineTopology = blt;
assert baselineAssignment != null;
} else {
baselineTopology = null;
baselineAssignment = null;
}
if (locCache)
initialize(topVer, assignment.assignment());
return assignment;
}
use of org.apache.ignite.internal.processors.cluster.BaselineTopology in project ignite by apache.
the class IgniteClusterImpl method validateBeforeBaselineChange.
/**
* Executes validation checks of cluster state and BaselineTopology before changing BaselineTopology to new one.
*/
private void validateBeforeBaselineChange(Collection<? extends BaselineNode> baselineTop) {
verifyBaselineTopologySupport(ctx.discovery().discoCache());
if (!ctx.state().clusterState().active())
throw new IgniteException("Changing BaselineTopology on inactive cluster is not allowed.");
if (baselineTop != null) {
if (baselineTop.isEmpty())
throw new IgniteException("BaselineTopology must contain at least one node.");
List<BaselineNode> currBlT = Optional.ofNullable(ctx.state().clusterState().baselineTopology()).map(BaselineTopology::currentBaseline).orElse(Collections.emptyList());
Collection<ClusterNode> srvrs = ctx.cluster().get().forServers().nodes();
for (BaselineNode node : baselineTop) {
Object consistentId = node.consistentId();
if (currBlT.stream().noneMatch(currBlTNode -> Objects.equals(currBlTNode.consistentId(), consistentId)) && srvrs.stream().noneMatch(currServersNode -> Objects.equals(currServersNode.consistentId(), consistentId)))
throw new IgniteException("Check arguments. Node with consistent ID [" + consistentId + "] not found in server nodes.");
}
Collection<Object> onlineNodes = onlineBaselineNodesRequestedForRemoval(baselineTop);
if (onlineNodes != null) {
if (!onlineNodes.isEmpty())
throw new IgniteException("Removing online nodes from BaselineTopology is not supported: " + onlineNodes);
}
}
}
use of org.apache.ignite.internal.processors.cluster.BaselineTopology in project ignite by apache.
the class IgniteBaselineAffinityTopologyActivationTest method testNodeWithBltIsProhibitedToJoinNewCluster.
/**
*/
@Test
public void testNodeWithBltIsProhibitedToJoinNewCluster() throws Exception {
BaselineTopologyVerifier nullVerifier = new BaselineTopologyVerifier() {
@Override
public void verify(BaselineTopology blt) {
assertNull(blt);
}
};
Ignite nodeC = startGridWithConsistentId("C");
nodeC.cluster().active(true);
stopGrid("C", false);
Ignite nodeA = startGridWithConsistentId("A");
Ignite nodeB = startGridWithConsistentId("B");
verifyBaselineTopologyOnNodes(nullVerifier, new Ignite[] { nodeA, nodeB });
boolean expectedExceptionThrown = false;
try {
startGridWithConsistentId("C");
} catch (IgniteCheckedException e) {
expectedExceptionThrown = true;
if (e.getCause() != null && e.getCause().getCause() != null) {
Throwable rootCause = e.getCause().getCause();
if (!(rootCause instanceof IgniteSpiException) || !rootCause.getMessage().contains("Node with set up BaselineTopology"))
Assert.fail("Unexpected ignite exception was thrown: " + e);
} else
throw e;
}
assertTrue("Expected exception wasn't thrown.", expectedExceptionThrown);
}
use of org.apache.ignite.internal.processors.cluster.BaselineTopology in project ignite by apache.
the class IgniteBaselineAffinityTopologyActivationTest method testRemoveBaselineTopology.
/**
* Verifies that baseline topology is removed successfully through baseline changing API.
*/
@Test
public void testRemoveBaselineTopology() throws Exception {
BaselineTopologyVerifier verifier = new BaselineTopologyVerifier() {
@Override
public void verify(BaselineTopology blt) {
assertNull(blt);
}
};
Ignite nodeA = startGridWithConsistentId("A");
Ignite nodeB = startGridWithConsistentId("B");
Ignite nodeC = startGridWithConsistentId("C");
nodeA.cluster().baselineAutoAdjustEnabled(false);
nodeA.cluster().active(true);
nodeA.cluster().setBaselineTopology(null);
verifyBaselineTopologyOnNodes(verifier, new Ignite[] { nodeA, nodeB, nodeC });
}
use of org.apache.ignite.internal.processors.cluster.BaselineTopology in project ignite by apache.
the class IgniteBaselineAffinityTopologyActivationTest method testAddNodeToBaselineTopology.
/**
*/
@Test
public void testAddNodeToBaselineTopology() throws Exception {
final long expectedActivationHash = (long) "A".hashCode() + "B".hashCode() + "C".hashCode() + "D".hashCode();
BaselineTopologyVerifier verifier = new BaselineTopologyVerifier() {
@Override
public void verify(BaselineTopology blt) {
assertNotNull(blt);
assertEquals(4, blt.consistentIds().size());
long activationHash = U.field(blt, "branchingPntHash");
assertEquals(expectedActivationHash, activationHash);
}
};
Ignite nodeA = startGridWithConsistentId("A");
Ignite nodeB = startGridWithConsistentId("B");
Ignite nodeC = startGridWithConsistentId("C");
nodeA.cluster().baselineAutoAdjustEnabled(false);
nodeC.cluster().active(true);
IgniteEx nodeD = (IgniteEx) startGridWithConsistentId("D");
nodeD.cluster().setBaselineTopology(baselineNodes(nodeA.cluster().forServers().nodes()));
verifyBaselineTopologyOnNodes(verifier, new Ignite[] { nodeA, nodeB, nodeC, nodeD });
}
Aggregations