Skip to content

Commit 460ce87

Browse files
authored
Optimize loading mappings in logsdb index settings provider (elastic#120221)
Optimize mapping service usages in when determining synthetic source usage and assessing whether host.name field can be used for index sorting. This is done by excluding the part of the mapping we're not interested in. This replaces elastic#119935 and addresses the problem differently, by just loading the parts of the mapping LogsdbIndexModeSettingsProvider is interested in and by this lowering the overhead of parsing/merging mappings that has been reported via elastic#119552.
1 parent 36e8af7 commit 460ce87

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed

docs/changelog/120055.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 120055
2+
summary: Optimize loading mappings when determining synthetic source usage and whether host.name can be sorted on.
3+
area: Logs
4+
type: enhancement
5+
issues: []

x-pack/plugin/logsdb/src/main/java/org/elasticsearch/xpack/logsdb/LogsdbIndexModeSettingsProvider.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.elasticsearch.common.compress.CompressedXContent;
1717
import org.elasticsearch.common.regex.Regex;
1818
import org.elasticsearch.common.settings.Settings;
19+
import org.elasticsearch.common.xcontent.XContentHelper;
1920
import org.elasticsearch.core.CheckedFunction;
2021
import org.elasticsearch.core.Strings;
2122
import org.elasticsearch.index.IndexMode;
@@ -30,12 +31,14 @@
3031
import org.elasticsearch.index.mapper.NumberFieldMapper;
3132
import org.elasticsearch.index.mapper.ObjectMapper;
3233
import org.elasticsearch.index.mapper.SourceFieldMapper;
34+
import org.elasticsearch.xcontent.XContentType;
3335

3436
import java.io.IOException;
3537
import java.time.Instant;
3638
import java.util.ArrayList;
3739
import java.util.List;
3840
import java.util.Locale;
41+
import java.util.Set;
3942
import java.util.function.Supplier;
4043

4144
import static org.elasticsearch.cluster.metadata.IndexMetadata.INDEX_ROUTING_PATH;
@@ -44,6 +47,7 @@
4447
final class LogsdbIndexModeSettingsProvider implements IndexSettingProvider {
4548
private static final Logger LOGGER = LogManager.getLogger(LogsdbIndexModeSettingsProvider.class);
4649
private static final String LOGS_PATTERN = "logs-*-*";
50+
private static final Set<String> MAPPING_INCLUDES = Set.of("_doc._source.*", "_doc.properties.host**", "_doc.subobjects");
4751

4852
private final SyntheticSourceLicenseService syntheticSourceLicenseService;
4953
private final SetOnce<CheckedFunction<IndexMetadata, MapperService, IOException>> mapperServiceFactory = new SetOnce<>();
@@ -232,6 +236,19 @@ MappingHints getMappingHints(
232236
// combinedTemplateMappings can be empty when creating a normal index that doesn't match any template and without mapping.
233237
if (combinedTemplateMappings == null || combinedTemplateMappings.isEmpty()) {
234238
combinedTemplateMappings = List.of(new CompressedXContent("{}"));
239+
} else {
240+
// Filter the mapping to contain only the part this index settings provider is interested in.
241+
// This reduces the overhead of loading mappings, since mappings can be very large.
242+
// The _doc._source.mode is needed to determine synthetic source usage.
243+
// The _doc.properties.host* is needed to determine whether host.name field can be injected.
244+
// The _doc.subobjects is needed to determine whether subobjects is enabled.
245+
List<CompressedXContent> filteredMappings = new ArrayList<>(combinedTemplateMappings.size());
246+
for (CompressedXContent mappingSource : combinedTemplateMappings) {
247+
var ref = mappingSource.compressedReference();
248+
var map = XContentHelper.convertToMap(ref, true, XContentType.JSON, MAPPING_INCLUDES, Set.of()).v2();
249+
filteredMappings.add(new CompressedXContent(map));
250+
}
251+
combinedTemplateMappings = filteredMappings;
235252
}
236253
mapperService.merge(MapperService.SINGLE_MAPPING_NAME, combinedTemplateMappings, MapperService.MergeReason.INDEX_TEMPLATE);
237254
Mapper hostName = mapperService.mappingLookup().getMapper("host.name");

x-pack/plugin/logsdb/src/yamlRestTest/resources/rest-api-spec/test/30_logsdb_default_mapping.yml

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,116 @@ create logsdb data stream with host.name as integer and timestamp as date:
107107
- do:
108108
indices.create_data_stream:
109109
name: "logsdb"
110+
- is_true: acknowledged
111+
112+
- do:
113+
indices.get_data_stream:
114+
name: "logsdb"
115+
expand_wildcards: hidden
116+
- length: { data_streams: 1 }
117+
- set: { data_streams.0.indices.0.index_name: backing_index }
118+
119+
- do:
120+
indices.get_settings:
121+
index: $backing_index
122+
- match: { .$backing_index.settings.index.mode: logsdb }
123+
- is_false: .$backing_index.settings.index.logsdb.add_host_name_field
124+
- match: { .$backing_index.settings.index.logsdb.sort_on_host_name: "true" }
125+
126+
---
127+
create logsdb data stream with no host.name and timestamp as date:
128+
- requires:
129+
test_runner_features: [ "allowed_warnings" ]
130+
131+
- do:
132+
cluster.put_component_template:
133+
name: "logsdb-mappings"
134+
body:
135+
template:
136+
settings:
137+
mode: "logsdb"
138+
mappings:
139+
properties:
140+
"@timestamp":
141+
type: "date"
142+
143+
- do:
144+
indices.put_index_template:
145+
name: "logsdb-index-template"
146+
body:
147+
index_patterns: ["logsdb"]
148+
data_stream: {}
149+
composed_of: ["logsdb-mappings"]
150+
allowed_warnings:
151+
- "index template [logsdb-index-template] has index patterns [logsdb] matching patterns from existing older templates [global] with patterns (global => [*]); this template [logsdb-index-template] will take precedence during new index creation"
110152

153+
- do:
154+
indices.create_data_stream:
155+
name: "logsdb"
111156
- is_true: acknowledged
112157

158+
- do:
159+
indices.get_data_stream:
160+
name: "logsdb"
161+
expand_wildcards: hidden
162+
- length: { data_streams: 1 }
163+
- set: { data_streams.0.indices.0.index_name: backing_index }
164+
165+
- do:
166+
indices.get_settings:
167+
index: $backing_index
168+
- match: { .$backing_index.settings.index.mode: logsdb }
169+
- match: { .$backing_index.settings.index.logsdb.add_host_name_field: "true" }
170+
- match: { .$backing_index.settings.index.logsdb.sort_on_host_name: "true" }
171+
172+
---
173+
create logsdb data stream with host as keyword and timestamp as date:
174+
- requires:
175+
test_runner_features: [ "allowed_warnings" ]
176+
177+
- do:
178+
cluster.put_component_template:
179+
name: "logsdb-mappings"
180+
body:
181+
template:
182+
settings:
183+
mode: "logsdb"
184+
mappings:
185+
properties:
186+
host:
187+
type: "keyword"
188+
"@timestamp":
189+
type: "date"
190+
191+
- do:
192+
indices.put_index_template:
193+
name: "logsdb-index-template"
194+
body:
195+
index_patterns: ["logsdb"]
196+
data_stream: {}
197+
composed_of: ["logsdb-mappings"]
198+
allowed_warnings:
199+
- "index template [logsdb-index-template] has index patterns [logsdb] matching patterns from existing older templates [global] with patterns (global => [*]); this template [logsdb-index-template] will take precedence during new index creation"
200+
201+
- do:
202+
indices.create_data_stream:
203+
name: "logsdb"
204+
- is_true: acknowledged
205+
206+
- do:
207+
indices.get_data_stream:
208+
name: "logsdb"
209+
expand_wildcards: hidden
210+
- length: { data_streams: 1 }
211+
- set: { data_streams.0.indices.0.index_name: backing_index }
212+
213+
- do:
214+
indices.get_settings:
215+
index: $backing_index
216+
- match: { .$backing_index.settings.index.mode: logsdb }
217+
- is_false: .$backing_index.settings.index.logsdb.add_host_name_field
218+
- is_false: .$backing_index.settings.index.logsdb.sort_on_host_name
219+
113220
---
114221
create logsdb data stream with host as keyword:
115222
- requires:

0 commit comments

Comments
 (0)