Skip to content

Commit 16a4aa5

Browse files
authored
Deprecate setting processors to more than available (#44889)
Today the processors setting is permitted to be set to more than the number of processors available to the JVM. The processors setting directly sizes the number of threads in the various thread pools, with most of these sizes being a linear function in the number of processors. It doesn't make any sense to set processors very high as the overhead from context switching amongst all the threads will overwhelm, and changing the setting does not control how many physical CPU resources there are on which to schedule the additional threads. We have to draw a line somewhere and this commit deprecates setting processors to more than the number of available processors. This is the right place to draw the line given the linear growth as a function of processors in most of the thread pools, and that some are capped at the number of available processors already.
1 parent 321c2b8 commit 16a4aa5

File tree

4 files changed

+41
-26
lines changed

4 files changed

+41
-26
lines changed

server/src/main/java/org/elasticsearch/common/util/concurrent/EsExecutors.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919

2020
package org.elasticsearch.common.util.concurrent;
2121

22+
import org.apache.logging.log4j.LogManager;
2223
import org.elasticsearch.ExceptionsHelper;
2324
import org.elasticsearch.common.SuppressForbidden;
25+
import org.elasticsearch.common.logging.DeprecationLogger;
2426
import org.elasticsearch.common.settings.Setting;
2527
import org.elasticsearch.common.settings.Setting.Property;
2628
import org.elasticsearch.common.settings.Settings;
@@ -46,12 +48,27 @@
4648

4749
public class EsExecutors {
4850

51+
private static final DeprecationLogger deprecationLogger = new DeprecationLogger(LogManager.getLogger(EsExecutors.class));
52+
4953
/**
50-
* Settings key to manually set the number of available processors.
51-
* This is used to adjust thread pools sizes etc. per node.
54+
* Setting to manually set the number of available processors. This setting is used to adjust thread pool sizes per node.
5255
*/
53-
public static final Setting<Integer> PROCESSORS_SETTING =
54-
Setting.intSetting("processors", Runtime.getRuntime().availableProcessors(), 1, Property.NodeScope);
56+
public static final Setting<Integer> PROCESSORS_SETTING = new Setting<>(
57+
"processors",
58+
s -> Integer.toString(Runtime.getRuntime().availableProcessors()),
59+
s -> {
60+
final int value = Setting.parseInt(s, 1, "processors");
61+
final int availableProcessors = Runtime.getRuntime().availableProcessors();
62+
if (value > availableProcessors) {
63+
deprecationLogger.deprecatedAndMaybeLog(
64+
"processors",
65+
"setting processors to value [{}] which is more than available processors [{}] is deprecated",
66+
value,
67+
availableProcessors);
68+
}
69+
return value;
70+
},
71+
Property.NodeScope);
5572

5673
/**
5774
* Returns the number of available processors. Defaults to

test/framework/src/main/java/org/elasticsearch/test/InternalTestCluster.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ private static Settings getRandomNodeSettings(long seed) {
450450
builder.put(SearchService.DEFAULT_KEEPALIVE_SETTING.getKey(), timeValueSeconds(100 + random.nextInt(5 * 60)).getStringRep());
451451
}
452452

453-
builder.put(EsExecutors.PROCESSORS_SETTING.getKey(), 1 + random.nextInt(3));
453+
builder.put(EsExecutors.PROCESSORS_SETTING.getKey(), 1 + random.nextInt(Math.min(4, Runtime.getRuntime().availableProcessors())));
454454
if (random.nextBoolean()) {
455455
if (random.nextBoolean()) {
456456
builder.put("indices.fielddata.cache.size", 1 + random.nextInt(1000), ByteSizeUnit.MB);

x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -515,11 +515,13 @@ public List<ExecutorBuilder<?>> getExecutorBuilders(final Settings settings) {
515515
* @param settings The current settings
516516
* @return A number between 5 and the number of processors
517517
*/
518-
static int getWatcherThreadPoolSize(Settings settings) {
519-
boolean isDataNode = Node.NODE_DATA_SETTING.get(settings);
518+
static int getWatcherThreadPoolSize(final Settings settings) {
519+
return getWatcherThreadPoolSize(Node.NODE_DATA_SETTING.get(settings), EsExecutors.numberOfProcessors(settings));
520+
}
521+
522+
static int getWatcherThreadPoolSize(final boolean isDataNode, final int numberOfProcessors) {
520523
if (isDataNode) {
521-
int numberOfProcessors = EsExecutors.numberOfProcessors(settings);
522-
long size = Math.max(Math.min(5 * numberOfProcessors, 50), numberOfProcessors);
524+
final long size = Math.max(Math.min(5 * numberOfProcessors, 50), numberOfProcessors);
523525
return Math.toIntExact(size);
524526
} else {
525527
return 1;

x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherPluginTests.java

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -86,23 +86,19 @@ public void testWatcherDisabledTests() throws Exception {
8686

8787
public void testThreadPoolSize() {
8888
// old calculation was 5 * number of processors
89-
assertThat(Watcher.getWatcherThreadPoolSize(Settings.builder().put("processors", 1).build()), is(5));
90-
assertThat(Watcher.getWatcherThreadPoolSize(Settings.builder().put("processors", 2).build()), is(10));
91-
assertThat(Watcher.getWatcherThreadPoolSize(Settings.builder().put("processors", 4).build()), is(20));
92-
assertThat(Watcher.getWatcherThreadPoolSize(Settings.builder().put("processors", 8).build()), is(40));
93-
assertThat(Watcher.getWatcherThreadPoolSize(Settings.builder().put("processors", 9).build()), is(45));
94-
assertThat(Watcher.getWatcherThreadPoolSize(Settings.builder().put("processors", 10).build()), is(50));
95-
assertThat(Watcher.getWatcherThreadPoolSize(Settings.builder().put("processors", 16).build()), is(50));
96-
assertThat(Watcher.getWatcherThreadPoolSize(Settings.builder().put("processors", 24).build()), is(50));
97-
assertThat(Watcher.getWatcherThreadPoolSize(Settings.builder().put("processors", 50).build()), is(50));
98-
assertThat(Watcher.getWatcherThreadPoolSize(Settings.builder().put("processors", 51).build()), is(51));
99-
assertThat(Watcher.getWatcherThreadPoolSize(Settings.builder().put("processors", 96).build()), is(96));
100-
101-
Settings noDataNodeSettings = Settings.builder()
102-
.put("processors", scaledRandomIntBetween(1, 100))
103-
.put("node.data", false)
104-
.build();
105-
assertThat(Watcher.getWatcherThreadPoolSize(noDataNodeSettings), is(1));
89+
assertThat(Watcher.getWatcherThreadPoolSize(true, 1), is(5));
90+
assertThat(Watcher.getWatcherThreadPoolSize(true, 2), is(10));
91+
assertThat(Watcher.getWatcherThreadPoolSize(true, 4), is(20));
92+
assertThat(Watcher.getWatcherThreadPoolSize(true, 8), is(40));
93+
assertThat(Watcher.getWatcherThreadPoolSize(true, 9), is(45));
94+
assertThat(Watcher.getWatcherThreadPoolSize(true, 10), is(50));
95+
assertThat(Watcher.getWatcherThreadPoolSize(true, 16), is(50));
96+
assertThat(Watcher.getWatcherThreadPoolSize(true, 24), is(50));
97+
assertThat(Watcher.getWatcherThreadPoolSize(true, 50), is(50));
98+
assertThat(Watcher.getWatcherThreadPoolSize(true, 51), is(51));
99+
assertThat(Watcher.getWatcherThreadPoolSize(true, 96), is(96));
100+
101+
assertThat(Watcher.getWatcherThreadPoolSize(false, scaledRandomIntBetween(1, 100)), is(1));
106102
}
107103

108104
public void testReload() {

0 commit comments

Comments
 (0)