Skip to content

Commit

Permalink
Star tree mapping changes with feature flag
Browse files Browse the repository at this point in the history
Signed-off-by: Bharathwaj G <bharath78910@gmail.com>
  • Loading branch information
bharath-techie committed Jun 13, 2024
1 parent 2e13e9c commit 682ba9f
Show file tree
Hide file tree
Showing 32 changed files with 1,342 additions and 14 deletions.
4 changes: 4 additions & 0 deletions distribution/src/config/opensearch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,7 @@ ${path.logs}
# Gates the functionality of enabling Opensearch to use pluggable caches with respective store names via setting.
#
#opensearch.experimental.feature.pluggable.caching.enabled: false
#
# Gates the functionality of star tree index, which improves the performance of search aggregations.
#
#opensearch.experimental.feature.composite.star_tree.enabled: true
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
import org.opensearch.index.IndexNotFoundException;
import org.opensearch.index.IndexService;
import org.opensearch.index.IndexSettings;
import org.opensearch.index.compositeindex.CompositeIndexValidator;
import org.opensearch.index.mapper.DocumentMapper;
import org.opensearch.index.mapper.MapperService;
import org.opensearch.index.mapper.MapperService.MergeReason;
Expand Down Expand Up @@ -1318,6 +1319,10 @@ private static void updateIndexMappingsAndBuildSortOrder(
}
}

if (mapperService.isCompositeIndexPresent()) {
CompositeIndexValidator.validate(mapperService, indexService.getCompositeIndexSettings());
}

if (sourceMetadata == null) {
// now that the mapping is merged we can validate the index sort.
// we cannot validate for index shrinking since the mapping is empty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
import org.opensearch.index.ShardIndexingPressureMemoryManager;
import org.opensearch.index.ShardIndexingPressureSettings;
import org.opensearch.index.ShardIndexingPressureStore;
import org.opensearch.index.compositeindex.CompositeIndexSettings;
import org.opensearch.index.remote.RemoteStorePressureSettings;
import org.opensearch.index.remote.RemoteStoreStatsTrackerFactory;
import org.opensearch.index.store.remote.filecache.FileCacheSettings;
Expand Down Expand Up @@ -755,7 +756,10 @@ public void apply(Settings value, Settings current, Settings previous) {
RemoteStoreSettings.CLUSTER_REMOTE_STORE_PATH_HASH_ALGORITHM_SETTING,
RemoteStoreSettings.CLUSTER_REMOTE_MAX_TRANSLOG_READERS,
RemoteStoreSettings.CLUSTER_REMOTE_STORE_TRANSLOG_METADATA,
SearchService.CLUSTER_ALLOW_DERIVED_FIELD_SETTING
SearchService.CLUSTER_ALLOW_DERIVED_FIELD_SETTING,

// Composite index settings
CompositeIndexSettings.STAR_TREE_INDEX_ENABLED_SETTING
)
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ protected FeatureFlagSettings(
FeatureFlags.TIERED_REMOTE_INDEX_SETTING,
FeatureFlags.REMOTE_STORE_MIGRATION_EXPERIMENTAL_SETTING,
FeatureFlags.PLUGGABLE_CACHE_SETTING,
FeatureFlags.REMOTE_PUBLICATION_EXPERIMENTAL_SETTING
FeatureFlags.REMOTE_PUBLICATION_EXPERIMENTAL_SETTING,
FeatureFlags.STAR_TREE_INDEX_SETTING
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import org.opensearch.index.SearchSlowLog;
import org.opensearch.index.TieredMergePolicyProvider;
import org.opensearch.index.cache.bitset.BitsetFilterCache;
import org.opensearch.index.compositeindex.startree.StarTreeIndexSettings;
import org.opensearch.index.engine.EngineConfig;
import org.opensearch.index.fielddata.IndexFieldDataService;
import org.opensearch.index.mapper.FieldMapper;
Expand Down Expand Up @@ -238,6 +239,14 @@ public final class IndexScopedSettings extends AbstractScopedSettings {
// Settings for concurrent segment search
IndexSettings.INDEX_CONCURRENT_SEGMENT_SEARCH_SETTING,
IndexSettings.ALLOW_DERIVED_FIELDS,

// Settings for star tree index
StarTreeIndexSettings.STAR_TREE_DEFAULT_MAX_LEAF_DOCS,
StarTreeIndexSettings.STAR_TREE_MAX_DIMENSIONS_SETTING,
StarTreeIndexSettings.STAR_TREE_MAX_FIELDS_SETTING,
StarTreeIndexSettings.DEFAULT_METRICS_LIST,
StarTreeIndexSettings.DEFAULT_DATE_INTERVALS,

// validate that built-in similarities don't get redefined
Setting.groupSetting("index.similarity.", (s) -> {
Map<String, Settings> groups = s.getAsGroups();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ public class FeatureFlags {
Property.NodeScope
);

/**
* Gates the functionality of star tree index, which improves the performance of search
* aggregations.
*/
public static final String STAR_TREE_INDEX = "opensearch.experimental.feature.composite.star_tree.enabled";
public static final Setting<Boolean> STAR_TREE_INDEX_SETTING = Setting.boolSetting(STAR_TREE_INDEX, false, Property.NodeScope);

private static final List<Setting<Boolean>> ALL_FEATURE_FLAG_SETTINGS = List.of(
REMOTE_STORE_MIGRATION_EXPERIMENTAL_SETTING,
EXTENSIONS_SETTING,
Expand All @@ -108,7 +115,8 @@ public class FeatureFlags {
DATETIME_FORMATTER_CACHING_SETTING,
TIERED_REMOTE_INDEX_SETTING,
PLUGGABLE_CACHE_SETTING,
REMOTE_PUBLICATION_EXPERIMENTAL_SETTING
REMOTE_PUBLICATION_EXPERIMENTAL_SETTING,
STAR_TREE_INDEX_SETTING
);
/**
* Should store the settings from opensearch.yml.
Expand Down
7 changes: 5 additions & 2 deletions server/src/main/java/org/opensearch/index/IndexModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
import org.opensearch.index.cache.query.DisabledQueryCache;
import org.opensearch.index.cache.query.IndexQueryCache;
import org.opensearch.index.cache.query.QueryCache;
import org.opensearch.index.compositeindex.CompositeIndexSettings;
import org.opensearch.index.engine.Engine;
import org.opensearch.index.engine.EngineConfigFactory;
import org.opensearch.index.engine.EngineFactory;
Expand Down Expand Up @@ -606,7 +607,8 @@ public IndexService newIndexService(
BiFunction<IndexSettings, ShardRouting, TranslogFactory> translogFactorySupplier,
Supplier<TimeValue> clusterDefaultRefreshIntervalSupplier,
RecoverySettings recoverySettings,
RemoteStoreSettings remoteStoreSettings
RemoteStoreSettings remoteStoreSettings,
CompositeIndexSettings compositeIndexSettings
) throws IOException {
final IndexEventListener eventListener = freeze();
Function<IndexService, CheckedFunction<DirectoryReader, DirectoryReader, IOException>> readerWrapperFactory = indexReaderWrapper
Expand Down Expand Up @@ -665,7 +667,8 @@ public IndexService newIndexService(
translogFactorySupplier,
clusterDefaultRefreshIntervalSupplier,
recoverySettings,
remoteStoreSettings
remoteStoreSettings,
compositeIndexSettings
);
success = true;
return indexService;
Expand Down
10 changes: 9 additions & 1 deletion server/src/main/java/org/opensearch/index/IndexService.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
import org.opensearch.index.cache.IndexCache;
import org.opensearch.index.cache.bitset.BitsetFilterCache;
import org.opensearch.index.cache.query.QueryCache;
import org.opensearch.index.compositeindex.CompositeIndexSettings;
import org.opensearch.index.engine.Engine;
import org.opensearch.index.engine.EngineConfigFactory;
import org.opensearch.index.engine.EngineFactory;
Expand Down Expand Up @@ -188,6 +189,7 @@ public class IndexService extends AbstractIndexComponent implements IndicesClust
private final Supplier<TimeValue> clusterDefaultRefreshIntervalSupplier;
private final RecoverySettings recoverySettings;
private final RemoteStoreSettings remoteStoreSettings;
private final CompositeIndexSettings compositeIndexSettings;

public IndexService(
IndexSettings indexSettings,
Expand Down Expand Up @@ -223,7 +225,8 @@ public IndexService(
BiFunction<IndexSettings, ShardRouting, TranslogFactory> translogFactorySupplier,
Supplier<TimeValue> clusterDefaultRefreshIntervalSupplier,
RecoverySettings recoverySettings,
RemoteStoreSettings remoteStoreSettings
RemoteStoreSettings remoteStoreSettings,
CompositeIndexSettings compositeIndexSettings
) {
super(indexSettings);
this.allowExpensiveQueries = allowExpensiveQueries;
Expand Down Expand Up @@ -301,6 +304,7 @@ public IndexService(
this.translogFactorySupplier = translogFactorySupplier;
this.recoverySettings = recoverySettings;
this.remoteStoreSettings = remoteStoreSettings;
this.compositeIndexSettings = compositeIndexSettings;
updateFsyncTaskIfNecessary();
}

Expand Down Expand Up @@ -1020,6 +1024,10 @@ private void rescheduleRefreshTasks() {
}
}

public CompositeIndexSettings getCompositeIndexSettings() {
return compositeIndexSettings;
}

/**
* Shard Store Deleter Interface
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.index.compositeindex;

import org.opensearch.common.annotation.ExperimentalApi;
import org.opensearch.common.settings.ClusterSettings;
import org.opensearch.common.settings.Setting;
import org.opensearch.common.settings.Settings;
import org.opensearch.common.util.FeatureFlags;

/**
* Cluster level settings for composite indices
*
* @opensearch.experimental
*/
@ExperimentalApi
public class CompositeIndexSettings {
public static final Setting<Boolean> STAR_TREE_INDEX_ENABLED_SETTING = Setting.boolSetting(
"indices.composite.star_tree.enabled",
false,
value -> {
if (FeatureFlags.isEnabled(FeatureFlags.STAR_TREE_INDEX_SETTING) == false && value == true) {
throw new IllegalArgumentException(
"star tree index is under an experimental feature and can be activated only by enabling "
+ FeatureFlags.STAR_TREE_INDEX_SETTING.getKey()
+ " feature flag in the JVM options"
);
}
},
Setting.Property.NodeScope,
Setting.Property.Dynamic
);

private volatile boolean starTreeIndexCreationEnabled;

public CompositeIndexSettings(Settings settings, ClusterSettings clusterSettings) {
this.starTreeIndexCreationEnabled = STAR_TREE_INDEX_ENABLED_SETTING.get(settings);
clusterSettings.addSettingsUpdateConsumer(STAR_TREE_INDEX_ENABLED_SETTING, this::starTreeIndexCreationEnabled);

}

private void starTreeIndexCreationEnabled(boolean value) {
this.starTreeIndexCreationEnabled = value;
}

public boolean isStarTreeIndexCreationEnabled() {
return starTreeIndexCreationEnabled;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.index.compositeindex;

import org.opensearch.common.annotation.ExperimentalApi;
import org.opensearch.index.mapper.CompositeDataCubeFieldType;
import org.opensearch.index.mapper.CompositeMappedFieldType;
import org.opensearch.index.mapper.MappedFieldType;
import org.opensearch.index.mapper.MapperService;
import org.opensearch.index.mapper.StarTreeMapper;

import java.util.Locale;
import java.util.Set;

/**
* Validation for composite indices
*
* @opensearch.experimental
*/
@ExperimentalApi
public class CompositeIndexValidator {

public static void validate(MapperService mapperService, CompositeIndexSettings compositeIndexSettings) {
validateStarTreeMappings(mapperService, compositeIndexSettings);
}

private static void validateStarTreeMappings(MapperService mapperService, CompositeIndexSettings compositeIndexSettings) {
Set<CompositeMappedFieldType> compositeFieldTypes = mapperService.getCompositeFieldTypes();
for (CompositeMappedFieldType compositeFieldType : compositeFieldTypes) {
if (!(compositeFieldType instanceof StarTreeMapper.StarTreeFieldType)) {
return;
}
if (!compositeIndexSettings.isStarTreeIndexCreationEnabled()) {
throw new IllegalArgumentException(
String.format(
Locale.ROOT,
"star tree index cannot be created, enable it using [%s] setting",
CompositeIndexSettings.STAR_TREE_INDEX_ENABLED_SETTING.getKey()
)
);
}
CompositeDataCubeFieldType dataCubeFieldType = (CompositeDataCubeFieldType) compositeFieldType;
for (Dimension dim : dataCubeFieldType.getDimensions()) {
MappedFieldType ft = mapperService.fieldType(dim.getField());
if (!ft.isAggregatable()) {
throw new IllegalArgumentException(
String.format(
Locale.ROOT,
"Aggregations not supported for the dimension field [%s] with field type [%s] as part of star tree field",
dim.getField(),
ft.typeName()
)
);
}
}
for (Metric metric : dataCubeFieldType.getMetrics()) {
MappedFieldType ft = mapperService.fieldType(metric.getField());
if (!ft.isAggregatable()) {
throw new IllegalArgumentException(
String.format(
Locale.ROOT,
"Aggregations not supported for the metrics field [%s] with field type [%s] as part of star tree field",
metric.getField(),
ft.typeName()
)
);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.index.compositeindex;

import org.opensearch.common.Rounding;
import org.opensearch.common.annotation.ExperimentalApi;
import org.opensearch.common.xcontent.support.XContentMapValues;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.index.compositeindex.startree.StarTreeIndexSettings;
import org.opensearch.index.mapper.Mapper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* Date dimension class
*
* @opensearch.experimental
*/
@ExperimentalApi
public class DateDimension extends Dimension {
private final List<Rounding.DateTimeUnit> calendarIntervals;

public DateDimension(String name, List<Rounding.DateTimeUnit> intervals) {
super(name);
this.calendarIntervals = intervals;
}

@SuppressWarnings("unchecked")
public DateDimension(Map.Entry<String, Object> dimension, Mapper.TypeParser.ParserContext c) {
super(dimension.getKey());
List<String> intervalStrings = XContentMapValues.extractRawValues("calendar_interval", (Map<String, Object>) dimension.getValue())
.stream()
.map(Object::toString)
.collect(Collectors.toList());
if (intervalStrings == null || intervalStrings.isEmpty()) {
this.calendarIntervals = StarTreeIndexSettings.DEFAULT_DATE_INTERVALS.get(c.getSettings());
} else {
this.calendarIntervals = new ArrayList<>();
for (String interval : intervalStrings) {
this.calendarIntervals.add(StarTreeIndexSettings.getTimeUnit(interval));
}
}
}

public List<Rounding.DateTimeUnit> getIntervals() {
return calendarIntervals;
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(this.getField());
builder.field("type", "date");
builder.startArray("calendar_interval");
for (Rounding.DateTimeUnit interval : calendarIntervals) {
builder.value(interval.shortName());
}
builder.endArray();
builder.endObject();
return builder;
}
}
Loading

0 comments on commit 682ba9f

Please sign in to comment.