mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-24 17:09:48 +00:00
Process more expensive allocation deciders last (#20724)
Today, the individual allocation deciders appear in random order when initialized in AllocationDeciders, which means potentially more performance intensive allocation deciders could run before less expensive deciders. This adds to the execution time when a less expensive decider could terminate the decision making process early with a NO decision. This commit orders the initialization of allocation deciders, based on a general assessment of the big O runtime of each decider, moving the likely more expensive deciders last. Closes #12815
This commit is contained in:
parent
3dcf1d5445
commit
dc166c5dc6
@ -19,12 +19,10 @@
|
||||
|
||||
package org.elasticsearch.cluster;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.elasticsearch.cluster.action.index.MappingUpdatedAction;
|
||||
import org.elasticsearch.cluster.action.index.NodeMappingRefreshAction;
|
||||
import org.elasticsearch.cluster.action.shard.ShardStateAction;
|
||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateFilter;
|
||||
import org.elasticsearch.cluster.metadata.MetaDataCreateIndexService;
|
||||
import org.elasticsearch.cluster.metadata.MetaDataDeleteIndexService;
|
||||
import org.elasticsearch.cluster.metadata.MetaDataIndexAliasesService;
|
||||
@ -55,18 +53,17 @@ import org.elasticsearch.cluster.routing.allocation.decider.SnapshotInProgressAl
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.ThrottlingAllocationDecider;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.inject.AbstractModule;
|
||||
import org.elasticsearch.common.logging.Loggers;
|
||||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.Setting;
|
||||
import org.elasticsearch.common.settings.Setting.Property;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.util.ExtensionPoint;
|
||||
import org.elasticsearch.gateway.GatewayAllocator;
|
||||
import org.elasticsearch.plugins.ClusterPlugin;
|
||||
import org.elasticsearch.tasks.TaskResultsService;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@ -109,21 +106,21 @@ public class ClusterModule extends AbstractModule {
|
||||
public static Collection<AllocationDecider> createAllocationDeciders(Settings settings, ClusterSettings clusterSettings,
|
||||
List<ClusterPlugin> clusterPlugins) {
|
||||
// collect deciders by class so that we can detect duplicates
|
||||
Map<Class, AllocationDecider> deciders = new HashMap<>();
|
||||
Map<Class, AllocationDecider> deciders = new LinkedHashMap<>();
|
||||
addAllocationDecider(deciders, new MaxRetryAllocationDecider(settings));
|
||||
addAllocationDecider(deciders, new SameShardAllocationDecider(settings));
|
||||
addAllocationDecider(deciders, new FilterAllocationDecider(settings, clusterSettings));
|
||||
addAllocationDecider(deciders, new ReplicaAfterPrimaryActiveAllocationDecider(settings));
|
||||
addAllocationDecider(deciders, new ThrottlingAllocationDecider(settings, clusterSettings));
|
||||
addAllocationDecider(deciders, new RebalanceOnlyWhenActiveAllocationDecider(settings));
|
||||
addAllocationDecider(deciders, new ClusterRebalanceAllocationDecider(settings, clusterSettings));
|
||||
addAllocationDecider(deciders, new ConcurrentRebalanceAllocationDecider(settings, clusterSettings));
|
||||
addAllocationDecider(deciders, new EnableAllocationDecider(settings, clusterSettings));
|
||||
addAllocationDecider(deciders, new AwarenessAllocationDecider(settings, clusterSettings));
|
||||
addAllocationDecider(deciders, new ShardsLimitAllocationDecider(settings, clusterSettings));
|
||||
addAllocationDecider(deciders, new NodeVersionAllocationDecider(settings));
|
||||
addAllocationDecider(deciders, new DiskThresholdDecider(settings, clusterSettings));
|
||||
addAllocationDecider(deciders, new SnapshotInProgressAllocationDecider(settings, clusterSettings));
|
||||
addAllocationDecider(deciders, new FilterAllocationDecider(settings, clusterSettings));
|
||||
addAllocationDecider(deciders, new SameShardAllocationDecider(settings));
|
||||
addAllocationDecider(deciders, new DiskThresholdDecider(settings, clusterSettings));
|
||||
addAllocationDecider(deciders, new ThrottlingAllocationDecider(settings, clusterSettings));
|
||||
addAllocationDecider(deciders, new ShardsLimitAllocationDecider(settings, clusterSettings));
|
||||
addAllocationDecider(deciders, new AwarenessAllocationDecider(settings, clusterSettings));
|
||||
|
||||
clusterPlugins.stream()
|
||||
.flatMap(p -> p.createAllocationDeciders(settings, clusterSettings).stream())
|
||||
|
@ -19,17 +19,25 @@
|
||||
|
||||
package org.elasticsearch.cluster;
|
||||
|
||||
import org.elasticsearch.action.admin.indices.create.CreateIndexClusterStateUpdateRequest;
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateFilter;
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.cluster.routing.ShardRouting;
|
||||
import org.elasticsearch.cluster.routing.allocation.RoutingAllocation;
|
||||
import org.elasticsearch.cluster.routing.allocation.allocator.BalancedShardsAllocator;
|
||||
import org.elasticsearch.cluster.routing.allocation.allocator.ShardsAllocator;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.AllocationDecider;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.AwarenessAllocationDecider;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.ClusterRebalanceAllocationDecider;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.ConcurrentRebalanceAllocationDecider;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.FilterAllocationDecider;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.MaxRetryAllocationDecider;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.NodeVersionAllocationDecider;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.RebalanceOnlyWhenActiveAllocationDecider;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.ReplicaAfterPrimaryActiveAllocationDecider;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.ShardsLimitAllocationDecider;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.SnapshotInProgressAllocationDecider;
|
||||
import org.elasticsearch.cluster.routing.allocation.decider.ThrottlingAllocationDecider;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.inject.ModuleTestCase;
|
||||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
@ -40,9 +48,12 @@ import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.SettingsModule;
|
||||
import org.elasticsearch.plugins.ClusterPlugin;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@ -156,4 +167,34 @@ public class ClusterModuleTests extends ModuleTestCase {
|
||||
NullPointerException e = expectThrows(NullPointerException.class, () ->
|
||||
newClusterModuleWithShardsAllocator(settings, "bad", () -> null));
|
||||
}
|
||||
|
||||
// makes sure that the allocation deciders are setup in the correct order, such that the
|
||||
// slower allocation deciders come last and we can exit early if there is a NO decision without
|
||||
// running them. If the order of the deciders is changed for a valid reason, the order should be
|
||||
// changed in the test too.
|
||||
public void testAllocationDeciderOrder() {
|
||||
List<Class<? extends AllocationDecider>> expectedDeciders = Arrays.asList(
|
||||
MaxRetryAllocationDecider.class,
|
||||
ReplicaAfterPrimaryActiveAllocationDecider.class,
|
||||
RebalanceOnlyWhenActiveAllocationDecider.class,
|
||||
ClusterRebalanceAllocationDecider.class,
|
||||
ConcurrentRebalanceAllocationDecider.class,
|
||||
EnableAllocationDecider.class,
|
||||
NodeVersionAllocationDecider.class,
|
||||
SnapshotInProgressAllocationDecider.class,
|
||||
FilterAllocationDecider.class,
|
||||
SameShardAllocationDecider.class,
|
||||
DiskThresholdDecider.class,
|
||||
ThrottlingAllocationDecider.class,
|
||||
ShardsLimitAllocationDecider.class,
|
||||
AwarenessAllocationDecider.class);
|
||||
Collection<AllocationDecider> deciders = ClusterModule.createAllocationDeciders(Settings.EMPTY,
|
||||
new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), Collections.emptyList());
|
||||
Iterator<AllocationDecider> iter = deciders.iterator();
|
||||
int idx = 0;
|
||||
while (iter.hasNext()) {
|
||||
AllocationDecider decider = iter.next();
|
||||
assertSame(decider.getClass(), expectedDeciders.get(idx++));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user