Skip to content

Commit 1b37d4b

Browse files
authored
Scripting: Increase ingest script cache defaults (#53765)
* Adds ability for contexts to specify their own defaults. * Context defaults are applied if no context-specific or general setting exists. * See 070ea7e for settings keys. * Increases the per-context default for the `ingest` context. * Cache size is doubled, 200 compared to default of 100 * Cache expiration is unchanged at no expiration * Cache max compilation is quintupled, 375/5m instead of 75/5m Refs: #50152
1 parent 984670b commit 1b37d4b

File tree

5 files changed

+180
-34
lines changed

5 files changed

+180
-34
lines changed

server/src/main/java/org/elasticsearch/script/IngestConditionalScript.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919

2020
package org.elasticsearch.script;
2121

22+
import org.elasticsearch.common.collect.Tuple;
23+
import org.elasticsearch.common.unit.TimeValue;
24+
2225
import java.util.Map;
2326

2427
/**
@@ -29,7 +32,8 @@ public abstract class IngestConditionalScript {
2932
public static final String[] PARAMETERS = { "ctx" };
3033

3134
/** The context used to compile {@link IngestConditionalScript} factories. */
32-
public static final ScriptContext<Factory> CONTEXT = new ScriptContext<>("processor_conditional", Factory.class);
35+
public static final ScriptContext<Factory> CONTEXT = new ScriptContext<>("processor_conditional", Factory.class,
36+
200, TimeValue.timeValueMillis(0), new Tuple<>(375, TimeValue.timeValueMinutes(5)));
3337

3438
/** The generic runtime parameters for the script. */
3539
private final Map<String, Object> params;

server/src/main/java/org/elasticsearch/script/IngestScript.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020

2121
package org.elasticsearch.script;
2222

23+
import org.elasticsearch.common.collect.Tuple;
24+
import org.elasticsearch.common.unit.TimeValue;
25+
2326
import java.util.Map;
2427

2528
/**
@@ -30,7 +33,8 @@ public abstract class IngestScript {
3033
public static final String[] PARAMETERS = { "ctx" };
3134

3235
/** The context used to compile {@link IngestScript} factories. */
33-
public static final ScriptContext<Factory> CONTEXT = new ScriptContext<>("ingest", Factory.class);
36+
public static final ScriptContext<Factory> CONTEXT = new ScriptContext<>("ingest", Factory.class,
37+
200, TimeValue.timeValueMillis(0), new Tuple<>(375, TimeValue.timeValueMinutes(5)));
3438

3539
/** The generic runtime parameters for the script. */
3640
private final Map<String, Object> params;

server/src/main/java/org/elasticsearch/script/ScriptContext.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919

2020
package org.elasticsearch.script;
2121

22+
import org.elasticsearch.common.collect.Tuple;
23+
import org.elasticsearch.common.unit.TimeValue;
24+
2225
import java.lang.reflect.Method;
2326

2427
/**
@@ -68,8 +71,18 @@ public final class ScriptContext<FactoryType> {
6871
/** A class that is an instance of a script. */
6972
public final Class<?> instanceClazz;
7073

71-
/** Construct a context with the related instance and compiled classes. */
72-
public ScriptContext(String name, Class<FactoryType> factoryClazz) {
74+
/** The default size of the cache for the context if not overridden */
75+
public final int cacheSizeDefault;
76+
77+
/** The default expiration of a script in the cache for the context, if not overridden */
78+
public final TimeValue cacheExpireDefault;
79+
80+
/** The default max compilation rate for scripts in this context. Script compilation is throttled if this is exceeded */
81+
public final Tuple<Integer, TimeValue> maxCompilationRateDefault;
82+
83+
/** Construct a context with the related instance and compiled classes with caller provided cache defaults */
84+
public ScriptContext(String name, Class<FactoryType> factoryClazz, int cacheSizeDefault, TimeValue cacheExpireDefault,
85+
Tuple<Integer, TimeValue> maxCompilationRateDefault) {
7386
this.name = name;
7487
this.factoryClazz = factoryClazz;
7588
Method newInstanceMethod = findMethod("FactoryType", factoryClazz, "newInstance");
@@ -90,6 +103,17 @@ public ScriptContext(String name, Class<FactoryType> factoryClazz) {
90103
+ factoryClazz.getName() + "] for script context [" + name + "]");
91104
}
92105
instanceClazz = newInstanceMethod.getReturnType();
106+
107+
this.cacheSizeDefault = cacheSizeDefault;
108+
this.cacheExpireDefault = cacheExpireDefault;
109+
this.maxCompilationRateDefault = maxCompilationRateDefault;
110+
}
111+
112+
/** Construct a context with the related instance and compiled classes with defaults for cacheSizeDefault, cacheExpireDefault and
113+
* maxCompilationRateDefault */
114+
public ScriptContext(String name, Class<FactoryType> factoryClazz) {
115+
// cache size default, cache expire default, max compilation rate are defaults from ScriptService.
116+
this(name, factoryClazz, 100, TimeValue.timeValueMillis(0), new Tuple<>(75, TimeValue.timeValueMinutes(5)));
93117
}
94118

95119
/** Returns a method with the given name, or throws an exception if multiple are found. */

server/src/main/java/org/elasticsearch/script/ScriptService.java

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import java.io.IOException;
4747
import java.nio.charset.StandardCharsets;
4848
import java.util.ArrayList;
49+
import java.util.Collection;
4950
import java.util.Collections;
5051
import java.util.Comparator;
5152
import java.util.HashMap;
@@ -241,7 +242,7 @@ public ScriptService(Settings settings, Map<String, ScriptEngine> engines, Map<S
241242

242243
// Validation requires knowing which contexts exist.
243244
this.validateCacheSettings(settings);
244-
cacheHolder = new AtomicReference<>(new CacheHolder(settings, contexts.keySet(), compilationLimitsEnabled()));
245+
cacheHolder = new AtomicReference<>(new CacheHolder(settings, contexts.values(), compilationLimitsEnabled()));
245246
}
246247

247248
/**
@@ -255,12 +256,12 @@ void registerClusterSettingsListeners(ClusterSettings clusterSettings) {
255256
clusterSettings.addSettingsUpdateConsumer(SCRIPT_MAX_SIZE_IN_BYTES, this::setMaxSizeInBytes);
256257

257258
// Handle all updatable per-context settings at once for each context.
258-
for (String context: contexts.keySet()) {
259+
for (ScriptContext<?> context: contexts.values()) {
259260
clusterSettings.addSettingsUpdateConsumer(
260261
(settings) -> cacheHolder.get().updateContextSettings(settings, context),
261-
List.of(SCRIPT_CACHE_SIZE_SETTING.getConcreteSettingForNamespace(context),
262-
SCRIPT_CACHE_EXPIRE_SETTING.getConcreteSettingForNamespace(context),
263-
SCRIPT_MAX_COMPILATIONS_RATE_SETTING.getConcreteSettingForNamespace(context),
262+
List.of(SCRIPT_CACHE_SIZE_SETTING.getConcreteSettingForNamespace(context.name),
263+
SCRIPT_CACHE_EXPIRE_SETTING.getConcreteSettingForNamespace(context.name),
264+
SCRIPT_MAX_COMPILATIONS_RATE_SETTING.getConcreteSettingForNamespace(context.name),
264265
SCRIPT_GENERAL_CACHE_EXPIRE_SETTING, // general settings used for fallbacks
265266
SCRIPT_GENERAL_CACHE_SIZE_SETTING
266267
)
@@ -580,17 +581,18 @@ static class CacheHolder {
580581
final ScriptCache general;
581582
final Map<String, AtomicReference<ScriptCache>> contextCache;
582583

583-
final Set<String> contexts;
584+
final Set<ScriptContext<?>> contexts;
584585
final boolean compilationLimitsEnabled;
585586

586-
CacheHolder(Settings settings, Set<String> contexts, boolean compilationLimitsEnabled) {
587+
CacheHolder(Settings settings, Collection<ScriptContext<?>> contexts, boolean compilationLimitsEnabled) {
587588
this.compilationLimitsEnabled = compilationLimitsEnabled;
588589
this.contexts = Set.copyOf(contexts);
589590
if (SCRIPT_GENERAL_MAX_COMPILATIONS_RATE_SETTING.get(settings).equals(USE_CONTEXT_RATE_VALUE)) {
590591
this.general = null;
591592
Map<String, AtomicReference<ScriptCache>> contextCache = new HashMap<>(this.contexts.size());
592-
for (String context : this.contexts) {
593-
contextCache.put(context, new AtomicReference<>(contextFromSettings(settings, context, this.compilationLimitsEnabled)));
593+
for (ScriptContext<?> context : this.contexts) {
594+
contextCache.put(context.name,
595+
new AtomicReference<>(contextFromSettings(settings, context, this.compilationLimitsEnabled)));
594596
}
595597
this.contextCache = Collections.unmodifiableMap(contextCache);
596598
} else {
@@ -607,12 +609,24 @@ static class CacheHolder {
607609
/**
608610
* Create a ScriptCache for the given context.
609611
*/
610-
private static ScriptCache contextFromSettings(Settings settings, String context, boolean compilationLimitsEnabled) {
611-
return new ScriptCache(SCRIPT_CACHE_SIZE_SETTING.getConcreteSettingForNamespace(context).get(settings),
612-
SCRIPT_CACHE_EXPIRE_SETTING.getConcreteSettingForNamespace(context).get(settings),
613-
compilationLimitsEnabled ?
614-
SCRIPT_MAX_COMPILATIONS_RATE_SETTING.getConcreteSettingForNamespace(context).get(settings) :
615-
SCRIPT_COMPILATION_RATE_ZERO);
612+
private static ScriptCache contextFromSettings(Settings settings, ScriptContext<?> context, boolean compilationLimitsEnabled) {
613+
String name = context.name;
614+
Tuple<Integer, TimeValue> compileRate;
615+
Setting<Tuple<Integer, TimeValue>> rateSetting = SCRIPT_MAX_COMPILATIONS_RATE_SETTING.getConcreteSettingForNamespace(name);
616+
if (compilationLimitsEnabled == false) {
617+
compileRate = SCRIPT_COMPILATION_RATE_ZERO;
618+
} else if (rateSetting.existsOrFallbackExists(settings)) {
619+
compileRate = rateSetting.get(settings);
620+
} else {
621+
compileRate = context.maxCompilationRateDefault;
622+
}
623+
624+
Setting<TimeValue> cacheExpire = SCRIPT_CACHE_EXPIRE_SETTING.getConcreteSettingForNamespace(name);
625+
Setting<Integer> cacheSize = SCRIPT_CACHE_SIZE_SETTING.getConcreteSettingForNamespace(name);
626+
627+
return new ScriptCache(cacheSize.existsOrFallbackExists(settings) ? cacheSize.get(settings) : context.cacheSizeDefault,
628+
cacheExpire.existsOrFallbackExists(settings) ? cacheExpire.get(settings) : context.cacheExpireDefault,
629+
compileRate);
616630
}
617631

618632
/**
@@ -666,16 +680,16 @@ ScriptStats stats() {
666680
/**
667681
* Update settings for the context cache, if we're in the context cache mode otherwise no-op.
668682
*/
669-
void updateContextSettings(Settings settings, String context) {
683+
void updateContextSettings(Settings settings, ScriptContext<?> context) {
670684
if (general != null) {
671685
return;
672686
}
673-
AtomicReference<ScriptCache> ref = contextCache.get(context);
674-
assert ref != null : "expected script cache to exist for context [" + context + "]";
687+
AtomicReference<ScriptCache> ref = contextCache.get(context.name);
688+
assert ref != null : "expected script cache to exist for context [" + context.name + "]";
675689
ScriptCache cache = ref.get();
676-
assert cache != null : "expected script cache to be non-null for context [" + context + "]";
690+
assert cache != null : "expected script cache to be non-null for context [" + context.name + "]";
677691
ref.set(contextFromSettings(settings, context, compilationLimitsEnabled));
678-
logger.debug("Replaced context [" + context + "] with new settings");
692+
logger.debug("Replaced context [" + context.name + "] with new settings");
679693
}
680694
}
681695
}

0 commit comments

Comments
 (0)