Skip to content

Commit

Permalink
Add support for CPU ranges in desired nodes (#86434)
Browse files Browse the repository at this point in the history
This commit adds support for CPU ranges in the desired nodes API. 

This aligns better with environments where administrators/orchestrators
can define lower and upper bounds for the amount of CPUs that the
desired node would get once deployed. 

This allows to provide information about the expected CPU and possible
allowed overcommit that the desired node will run on.

This was the previous expected body for the desired nodes API (we still support it):
```
PUT /_internal/desired_nodes/history/1
{
    "nodes" : [
        {
            "settings" : {
                 "node.name" : "instance-000187",
                 "node.external_id": "instance-000187",
                 "node.roles" : ["data_hot", "master"],
                 "node.attr.data" : "hot",
                 "node.attr.logical_availability_zone" : "zone-0"
            },
            "processors" : 8, 
            "memory" : "58gb",
            "storage" : "1700gb",
            "node_version" : "8.3.0"
        }
    ]
}
```

Now it's possible to define `processors` or `processors_range` as in:
```
PUT /_internal/desired_nodes/history/1
{
    "nodes" : [
        {
            "settings" : {
                 "node.name" : "instance-000187",
                 "node.external_id": "instance-000187",
                 "node.roles" : ["data_hot", "master"],
                 "node.attr.data" : "hot",
                 "node.attr.logical_availability_zone" : "zone-0"
            },
            "processors_range" : {"min": 8.0, "max": 16.0},
            "memory" : "58gb",
            "storage" : "1700gb",
            "node_version" : "8.3.0"
        }
    ]
}
```
Note that `max` in `processors_range` is optional.

This commit also moves from representing CPUs as integers to
accept floating point numbers.

Note: I disabled the bwc yamlRestTests for versions < 8.3 since we introduced
a few "breaking changes" but since this is an internal API it should be fine.
  • Loading branch information
fcofdez committed May 20, 2022
1 parent 9e8703a commit e91e7e6
Show file tree
Hide file tree
Showing 17 changed files with 1,042 additions and 124 deletions.
5 changes: 5 additions & 0 deletions docs/changelog/86434.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 86434
summary: Add support for CPU ranges in desired nodes
area: Autoscaling
type: enhancement
issues: []
4 changes: 2 additions & 2 deletions docs/reference/cluster/delete-desired-nodes.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ PUT /_internal/desired_nodes/history/1
"node.attr.data" : "hot",
"node.attr.logical_availability_zone" : "zone-0"
},
"processors" : 8,
"processors" : 8.0,
"memory" : "58gb",
"storage" : "1700gb",
"storage" : "2tb",
"node_version" : "{version}"
}
]
Expand Down
4 changes: 2 additions & 2 deletions docs/reference/cluster/get-desired-nodes.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ PUT /_internal/desired_nodes/my_history/1
"node.attr.data" : "hot",
"node.attr.logical_availability_zone" : "zone-0"
},
"processors" : 8,
"processors" : 8.0,
"memory" : "59gb",
"storage" : "1700gb",
"storage" : "2tb",
"node_version" : "{version}"
}
]
Expand Down
36 changes: 32 additions & 4 deletions docs/reference/cluster/update-desired-nodes.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ PUT /_internal/desired_nodes/<history_id>/<version>
"node.attr.data" : "hot",
"node.attr.logical_availability_zone" : "zone-0"
},
"processors" : 8,
"processors" : 8.0,
"memory" : "58gb",
"storage" : "1700gb",
"storage" : "2tb",
"node_version" : "{version}"
}
]
Expand Down Expand Up @@ -77,9 +77,9 @@ PUT /_internal/desired_nodes/Ywkh3INLQcuPT49f6kcppA/100
"node.attr.data" : "hot",
"node.attr.logical_availability_zone" : "zone-0"
},
"processors" : 8,
"processors" : 8.0,
"memory" : "58gb",
"storage" : "1700gb",
"storage" : "2tb",
"node_version" : "{version}"
}
]
Expand All @@ -96,6 +96,34 @@ The API returns the following result:
}
--------------------------------------------------

Additionally, it is possible to specify a processors range.
This is helpful in environments where Elasticsearch nodes can
be deployed in hosts where the number of processors that the
Elasticsearch process can use is guaranteed to be at least the
lower range and up to the upper range. This is a common scenario
in Linux deployments where cgroups is used.
[source,console]
--------------------------------------------------
PUT /_internal/desired_nodes/Ywkh3INLQcuPT49f6kcppA/101
{
"nodes" : [
{
"settings" : {
"node.name" : "instance-000187",
"node.external_id": "instance-000187",
"node.roles" : ["data_hot", "master"],
"node.attr.data" : "hot",
"node.attr.logical_availability_zone" : "zone-0"
},
"processors_range" : {"min": 8.0, "max": 10.0},
"memory" : "58gb",
"storage" : "2tb",
"node_version" : "{version}"
}
]
}
--------------------------------------------------

//////////////////////////
[source,console]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ public enum ValueType {
OBJECT_ARRAY_OR_NULL(START_OBJECT, START_ARRAY, VALUE_NULL),
OBJECT_OR_BOOLEAN(START_OBJECT, VALUE_BOOLEAN),
OBJECT_OR_STRING(START_OBJECT, VALUE_STRING),
OBJECT_OR_LONG(START_OBJECT, VALUE_NUMBER),
OBJECT_OR_NUMBER(START_OBJECT, VALUE_NUMBER),
OBJECT_ARRAY_BOOLEAN_OR_STRING(START_OBJECT, START_ARRAY, VALUE_BOOLEAN, VALUE_STRING),
OBJECT_ARRAY_OR_STRING(START_OBJECT, START_ARRAY, VALUE_STRING),
OBJECT_ARRAY_STRING_OR_NUMBER(START_OBJECT, START_ARRAY, VALUE_STRING, VALUE_NUMBER),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class Fields {
// For BWC with nodes pre 7.0
return p.longValue();
}
}, new ParseField("total"), ValueType.OBJECT_OR_LONG);
}, new ParseField("total"), ValueType.OBJECT_OR_NUMBER);
HITS_PARSER.declareObjectArray(constructorArg(), HIT_PARSER, new ParseField("hits"));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

package org.elasticsearch.upgrades;

import org.elasticsearch.Version;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.cluster.metadata.DesiredNode;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;

public class DesiredNodesUpgradeIT extends AbstractRollingTestCase {
public void testUpgradeDesiredNodes() throws Exception {
// Desired nodes was introduced in 8.1
if (UPGRADE_FROM_VERSION.before(Version.V_8_1_0)) {
return;
}

switch (CLUSTER_TYPE) {
case OLD -> {
var response = updateDesiredNodes(1, desiredNodesWithIntegerProcessor());
var statusCode = response.getStatusLine().getStatusCode();
assertThat(statusCode, equalTo(200));
}
case MIXED -> {
final var historyVersion = FIRST_MIXED_ROUND ? 2 : 3;
if (UPGRADE_FROM_VERSION.onOrAfter(DesiredNode.RANGE_FLOAT_PROCESSORS_SUPPORT_VERSION)) {
var response = updateDesiredNodes(historyVersion, desiredNodesWithRangeOrFloatProcessors());
var statusCode = response.getStatusLine().getStatusCode();
assertThat(statusCode, equalTo(200));
} else {
// Processor ranges or float processors are forbidden during upgrades: 8.2 -> 8.3 clusters
final var responseException = expectThrows(
ResponseException.class,
() -> updateDesiredNodes(historyVersion, desiredNodesWithRangeOrFloatProcessors())
);
var statusCode = responseException.getResponse().getStatusLine().getStatusCode();
assertThat(statusCode, is(equalTo(400)));
}
}
case UPGRADED -> {
var response = updateDesiredNodes(4, desiredNodesWithRangeOrFloatProcessors());
var statusCode = response.getStatusLine().getStatusCode();
assertThat(statusCode, equalTo(200));
}
}

final var getDesiredNodesRequest = new Request("GET", "/_internal/desired_nodes/_latest");
Response response = client().performRequest(getDesiredNodesRequest);
assertThat(response.getStatusLine().getStatusCode(), is(equalTo(200)));
}

private Response updateDesiredNodes(int version, String body) throws Exception {
final var updateDesiredNodesRequest = new Request("PUT", "/_internal/desired_nodes/history/" + version);
updateDesiredNodesRequest.setJsonEntity(body);
return client().performRequest(updateDesiredNodesRequest);
}

private String desiredNodesWithRangeOrFloatProcessors() {
if (randomBoolean()) {
return """
{
"nodes" : [
{
"settings" : {
"node.name" : "instance-000187"
},
"processors_range" : {"min": 9.0, "max": 10.0},
"memory" : "58gb",
"storage" : "1tb",
"node_version" : "99.1.0"
}
]
}""";
} else {
return """
{
"nodes" : [
{
"settings" : {
"node.name" : "instance-000187"
},
"processors" : 9.5,
"memory" : "58gb",
"storage" : "1tb",
"node_version" : "99.1.0"
}
]
}""";
}
}

private String desiredNodesWithIntegerProcessor() {
return """
{
"nodes" : [
{
"settings" : {
"node.name" : "instance-000187"
},
"processors" : 9,
"memory" : "58gb",
"storage" : "1tb",
"node_version" : "99.1.0"
}
]
}""";
}
}

0 comments on commit e91e7e6

Please sign in to comment.