Simplify calculation in AwarenessAllocationDecider (#38091)

Today's calculation of the maximum number of shards per attribute is rather
convoluted. This commit clarifies that it returns
ceil(shardCount/numberOfAttributes).
This commit is contained in:
David Turner 2019-02-20 08:55:04 +00:00
parent 00a26b9dd2
commit efffb3d5b7
1 changed files with 7 additions and 19 deletions

View File

@ -136,7 +136,7 @@ public class AwarenessAllocationDecider extends AllocationDecider {
int shardCount = indexMetaData.getNumberOfReplicas() + 1; // 1 for primary int shardCount = indexMetaData.getNumberOfReplicas() + 1; // 1 for primary
for (String awarenessAttribute : awarenessAttributes) { for (String awarenessAttribute : awarenessAttributes) {
// the node the shard exists on must be associated with an awareness attribute // the node the shard exists on must be associated with an awareness attribute
if (!node.node().getAttributes().containsKey(awarenessAttribute)) { if (node.node().getAttributes().containsKey(awarenessAttribute) == false) {
return allocation.decision(Decision.NO, NAME, return allocation.decision(Decision.NO, NAME,
"node does not contain the awareness attribute [%s]; required attributes cluster setting [%s=%s]", "node does not contain the awareness attribute [%s]; required attributes cluster setting [%s=%s]",
awarenessAttribute, CLUSTER_ROUTING_ALLOCATION_AWARENESS_ATTRIBUTE_SETTING.getKey(), awarenessAttribute, CLUSTER_ROUTING_ALLOCATION_AWARENESS_ATTRIBUTE_SETTING.getKey(),
@ -160,7 +160,7 @@ public class AwarenessAllocationDecider extends AllocationDecider {
if (moveToNode) { if (moveToNode) {
if (shardRouting.assignedToNode()) { if (shardRouting.assignedToNode()) {
String nodeId = shardRouting.relocating() ? shardRouting.relocatingNodeId() : shardRouting.currentNodeId(); String nodeId = shardRouting.relocating() ? shardRouting.relocatingNodeId() : shardRouting.currentNodeId();
if (!node.nodeId().equals(nodeId)) { if (node.nodeId().equals(nodeId) == false) {
// we work on different nodes, move counts around // we work on different nodes, move counts around
shardPerAttribute.putOrAdd(allocation.routingNodes().node(nodeId).node().getAttributes().get(awarenessAttribute), shardPerAttribute.putOrAdd(allocation.routingNodes().node(nodeId).node().getAttributes().get(awarenessAttribute),
0, -1); 0, -1);
@ -175,28 +175,16 @@ public class AwarenessAllocationDecider extends AllocationDecider {
List<String> fullValues = forcedAwarenessAttributes.get(awarenessAttribute); List<String> fullValues = forcedAwarenessAttributes.get(awarenessAttribute);
if (fullValues != null) { if (fullValues != null) {
for (String fullValue : fullValues) { for (String fullValue : fullValues) {
if (!shardPerAttribute.containsKey(fullValue)) { if (shardPerAttribute.containsKey(fullValue) == false) {
numberOfAttributes++; numberOfAttributes++;
} }
} }
} }
// TODO should we remove ones that are not part of full list? // TODO should we remove ones that are not part of full list?
int averagePerAttribute = shardCount / numberOfAttributes; final int currentNodeCount = shardPerAttribute.get(node.node().getAttributes().get(awarenessAttribute));
int totalLeftover = shardCount % numberOfAttributes; final int maximumNodeCount = (shardCount + numberOfAttributes - 1) / numberOfAttributes; // ceil(shardCount/numberOfAttributes)
int requiredCountPerAttribute; if (currentNodeCount > maximumNodeCount) {
if (averagePerAttribute == 0) {
// if we have more attributes values than shard count, no leftover
totalLeftover = 0;
requiredCountPerAttribute = 1;
} else {
requiredCountPerAttribute = averagePerAttribute;
}
int leftoverPerAttribute = totalLeftover == 0 ? 0 : 1;
int currentNodeCount = shardPerAttribute.get(node.node().getAttributes().get(awarenessAttribute));
// if we are above with leftover, then we know we are not good, even with mod
if (currentNodeCount > (requiredCountPerAttribute + leftoverPerAttribute)) {
return allocation.decision(Decision.NO, NAME, return allocation.decision(Decision.NO, NAME,
"there are too many copies of the shard allocated to nodes with attribute [%s], there are [%d] total configured " + "there are too many copies of the shard allocated to nodes with attribute [%s], there are [%d] total configured " +
"shard copies for this shard id and [%d] total attribute values, expected the allocated shard count per " + "shard copies for this shard id and [%d] total attribute values, expected the allocated shard count per " +
@ -205,7 +193,7 @@ public class AwarenessAllocationDecider extends AllocationDecider {
shardCount, shardCount,
numberOfAttributes, numberOfAttributes,
currentNodeCount, currentNodeCount,
requiredCountPerAttribute + leftoverPerAttribute); maximumNodeCount);
} }
} }