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:
parent
00a26b9dd2
commit
efffb3d5b7
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue