use of org.apache.cassandra.dht.Token in project cassandra by apache.
the class ReplicationAwareTokenAllocator method evaluateImprovement.
/**
* Evaluates the improvement in variance for both units and individual tokens when candidate is inserted into the
* ring.
*/
private double evaluateImprovement(CandidateInfo<Unit> candidate, double optTokenOwnership, double newUnitMult) {
double tokenChange = 0;
UnitInfo<Unit> candidateUnit = candidate.owningUnit;
Token candidateEnd = candidate.token;
// Form a chain of units affected by the insertion to be able to qualify change of unit ownership.
// A unit may be affected more than once.
UnitAdjustmentTracker<Unit> unitTracker = new UnitAdjustmentTracker<>(candidateUnit);
// Reflect change in ownership of the splitting token (candidate).
tokenChange += applyOwnershipAdjustment(candidate, candidateUnit, candidate.replicationStart, candidateEnd, optTokenOwnership, unitTracker);
// Loop through all vnodes that replicate candidate or split and update their ownership.
ReplicationVisitor replicationVisitor = new ReplicationVisitor();
for (TokenInfo<Unit> curr = candidate.split; !replicationVisitor.visitedAll(); curr = curr.next) {
UnitInfo<Unit> currUnit = curr.owningUnit;
if (!replicationVisitor.add(currUnit.group))
// If this group is already seen, the token cannot be affected.
continue;
Token replicationEnd = curr.token;
Token replicationStart = findUpdatedReplicationStart(curr, candidate);
tokenChange += applyOwnershipAdjustment(curr, currUnit, replicationStart, replicationEnd, optTokenOwnership, unitTracker);
}
replicationVisitor.clean();
double nodeChange = unitTracker.calculateUnitChange(newUnitMult, optTokenOwnership);
return -(tokenChange + nodeChange);
}
use of org.apache.cassandra.dht.Token in project cassandra by apache.
the class ReplicationAwareTokenAllocator method confirmCandidate.
/**
* Incorporates the selected candidate into the ring, adjusting ownership information and calculated token
* information.
*/
private void confirmCandidate(CandidateInfo<Unit> candidate) {
// This process is less efficient than it could be (loops through each vnode's replication span instead
// of recalculating replicationStart, replicationThreshold from existing data + new token data in an O(1)
// case analysis similar to evaluateImprovement). This is fine as the method does not dominate processing
// time.
// Put the accepted candidate in the token list.
UnitInfo<Unit> newUnit = candidate.owningUnit;
Token newToken = candidate.token;
sortedTokens.put(newToken, newUnit.unit);
unitToTokens.put(newUnit.unit, newToken);
TokenInfo<Unit> prev = candidate.prevInRing();
TokenInfo<Unit> newTokenInfo = new TokenInfo<>(newToken, newUnit);
newTokenInfo.replicatedOwnership = candidate.replicatedOwnership;
// List is not empty so this won't need to change head of list.
newTokenInfo.insertAfter(prev, prev);
// Update data for candidate.
populateTokenInfoAndAdjustUnit(newTokenInfo, newUnit.group);
ReplicationVisitor replicationVisitor = new ReplicationVisitor();
assert newTokenInfo.next == candidate.split;
for (TokenInfo<Unit> curr = newTokenInfo.next; !replicationVisitor.visitedAll(); curr = curr.next) {
// update the candidate between curr and next
candidate = candidate.next;
populateCandidate(candidate);
if (!replicationVisitor.add(curr.owningUnit.group))
// If we've already seen this group, the token cannot be affected.
continue;
populateTokenInfoAndAdjustUnit(curr, newUnit.group);
}
replicationVisitor.clean();
}
use of org.apache.cassandra.dht.Token in project cassandra by apache.
the class TokenAllocation method evaluateReplicatedOwnership.
// return the ratio of ownership for each endpoint
public static Map<InetAddress, Double> evaluateReplicatedOwnership(TokenMetadata tokenMetadata, AbstractReplicationStrategy rs) {
Map<InetAddress, Double> ownership = Maps.newHashMap();
List<Token> sortedTokens = tokenMetadata.sortedTokens();
Iterator<Token> it = sortedTokens.iterator();
Token current = it.next();
while (it.hasNext()) {
Token next = it.next();
addOwnership(tokenMetadata, rs, current, next, ownership);
current = next;
}
addOwnership(tokenMetadata, rs, current, sortedTokens.get(0), ownership);
return ownership;
}
use of org.apache.cassandra.dht.Token in project cassandra by apache.
the class TokenAllocation method allocateTokens.
public static Collection<Token> allocateTokens(final TokenMetadata tokenMetadata, final AbstractReplicationStrategy rs, final InetAddress endpoint, int numTokens) {
TokenMetadata tokenMetadataCopy = tokenMetadata.cloneOnlyTokenMap();
StrategyAdapter strategy = getStrategy(tokenMetadataCopy, rs, endpoint);
Collection<Token> tokens = create(tokenMetadata, strategy).addUnit(endpoint, numTokens);
tokens = adjustForCrossDatacenterClashes(tokenMetadata, strategy, tokens);
if (logger.isWarnEnabled()) {
logger.warn("Selected tokens {}", tokens);
SummaryStatistics os = replicatedOwnershipStats(tokenMetadataCopy, rs, endpoint);
tokenMetadataCopy.updateNormalTokens(tokens, endpoint);
SummaryStatistics ns = replicatedOwnershipStats(tokenMetadataCopy, rs, endpoint);
logger.warn("Replicated node load in datacentre before allocation {}", statToString(os));
logger.warn("Replicated node load in datacentre after allocation {}", statToString(ns));
// TODO: Is it worth doing the replicated ownership calculation always to be able to raise this alarm?
if (ns.getStandardDeviation() > os.getStandardDeviation())
logger.warn("Unexpected growth in standard deviation after allocation.");
}
return tokens;
}
use of org.apache.cassandra.dht.Token in project cassandra by apache.
the class TokenAllocation method adjustForCrossDatacenterClashes.
private static Collection<Token> adjustForCrossDatacenterClashes(final TokenMetadata tokenMetadata, StrategyAdapter strategy, Collection<Token> tokens) {
List<Token> filtered = Lists.newArrayListWithCapacity(tokens.size());
for (Token t : tokens) {
while (tokenMetadata.getEndpoint(t) != null) {
InetAddress other = tokenMetadata.getEndpoint(t);
if (strategy.inAllocationRing(other))
throw new ConfigurationException(String.format("Allocated token %s already assigned to node %s. Is another node also allocating tokens?", t, other));
t = t.increaseSlightly();
}
filtered.add(t);
}
return filtered;
}
Aggregations