Skip to content

Commit d25c01a

Browse files
authored
Scripting: Increase ingest script cache defaults (#53906)
* 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 Backport of: 1b37d4b Refs: #50152
1 parent 10cabbb commit d25c01a

File tree

5 files changed

+181
-36
lines changed

5 files changed

+181
-36
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: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import java.nio.charset.StandardCharsets;
4848
import java.util.ArrayList;
4949
import java.util.Arrays;
50+
import java.util.Collection;
5051
import java.util.Collections;
5152
import java.util.Comparator;
5253
import java.util.HashMap;
@@ -242,7 +243,7 @@ public ScriptService(Settings settings, Map<String, ScriptEngine> engines, Map<S
242243

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

248249
/**
@@ -256,12 +257,12 @@ void registerClusterSettingsListeners(ClusterSettings clusterSettings) {
256257
clusterSettings.addSettingsUpdateConsumer(SCRIPT_MAX_SIZE_IN_BYTES, this::setMaxSizeInBytes);
257258

258259
// Handle all updatable per-context settings at once for each context.
259-
for (String context: contexts.keySet()) {
260+
for (ScriptContext<?> context: contexts.values()) {
260261
clusterSettings.addSettingsUpdateConsumer(
261262
(settings) -> cacheHolder.get().updateContextSettings(settings, context),
262-
Arrays.asList(SCRIPT_CACHE_SIZE_SETTING.getConcreteSettingForNamespace(context),
263-
SCRIPT_CACHE_EXPIRE_SETTING.getConcreteSettingForNamespace(context),
264-
SCRIPT_MAX_COMPILATIONS_RATE_SETTING.getConcreteSettingForNamespace(context),
263+
Arrays.asList(SCRIPT_CACHE_SIZE_SETTING.getConcreteSettingForNamespace(context.name),
264+
SCRIPT_CACHE_EXPIRE_SETTING.getConcreteSettingForNamespace(context.name),
265+
SCRIPT_MAX_COMPILATIONS_RATE_SETTING.getConcreteSettingForNamespace(context.name),
265266
SCRIPT_GENERAL_CACHE_EXPIRE_SETTING,
266267
// general settings used for fallbacks
267268
SCRIPT_GENERAL_CACHE_SIZE_SETTING)
@@ -581,17 +582,18 @@ static class CacheHolder {
581582
final ScriptCache general;
582583
final Map<String, AtomicReference<ScriptCache>> contextCache;
583584

584-
final Set<String> contexts;
585+
final Set<ScriptContext<?>> contexts;
585586
final boolean compilationLimitsEnabled;
586587

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

619633
/**
@@ -667,16 +681,16 @@ ScriptStats stats() {
667681
/**
668682
* Update settings for the context cache, if we're in the context cache mode otherwise no-op.
669683
*/
670-
void updateContextSettings(Settings settings, String context) {
684+
void updateContextSettings(Settings settings, ScriptContext<?> context) {
671685
if (general != null) {
672686
return;
673687
}
674-
AtomicReference<ScriptCache> ref = contextCache.get(context);
675-
assert ref != null : "expected script cache to exist for context [" + context + "]";
688+
AtomicReference<ScriptCache> ref = contextCache.get(context.name);
689+
assert ref != null : "expected script cache to exist for context [" + context.name + "]";
676690
ScriptCache cache = ref.get();
677-
assert cache != null : "expected script cache to be non-null for context [" + context + "]";
691+
assert cache != null : "expected script cache to be non-null for context [" + context.name + "]";
678692
ref.set(contextFromSettings(settings, context, compilationLimitsEnabled));
679-
logger.debug("Replaced context [" + context + "] with new settings");
693+
logger.debug("Replaced context [" + context.name + "] with new settings");
680694
}
681695
}
682696
}

0 commit comments

Comments
 (0)