Skip to content

Commit 0c5c04b

Browse files
committed
Skip rebalancing if disabled and explicitly disabled on some indices too
1 parent 7491b9b commit 0c5c04b

File tree

2 files changed

+111
-14
lines changed

2 files changed

+111
-14
lines changed

server/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/EnableAllocationDecider.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,9 @@ public Decision canRebalance(RoutingAllocation allocation) {
149149

150150
if (enableRebalance == Rebalance.NONE) {
151151
for (IndexMetaData indexMetaData : allocation.metaData()) {
152-
if (INDEX_ROUTING_REBALANCE_ENABLE_SETTING.exists(indexMetaData.getSettings())) {
153-
return allocation.decision(Decision.YES, NAME, "rebalancing is overridden on one or more indices");
152+
if (INDEX_ROUTING_REBALANCE_ENABLE_SETTING.exists(indexMetaData.getSettings())
153+
&& INDEX_ROUTING_REBALANCE_ENABLE_SETTING.get(indexMetaData.getSettings()) != Rebalance.NONE) {
154+
return allocation.decision(Decision.YES, NAME, "rebalancing is permitted on one or more indices");
154155
}
155156
}
156157
return allocation.decision(Decision.NO, NAME, "no rebalancing is allowed due to %s", setting(enableRebalance, false));

server/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/EnableAllocationShortCircuitTests.java

Lines changed: 108 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.elasticsearch.cluster.routing.RoutingNode;
3131
import org.elasticsearch.cluster.routing.RoutingTable;
3232
import org.elasticsearch.cluster.routing.ShardRouting;
33+
import org.elasticsearch.cluster.routing.ShardRoutingState;
3334
import org.elasticsearch.cluster.routing.allocation.AllocationService;
3435
import org.elasticsearch.cluster.routing.allocation.RoutingAllocation;
3536
import org.elasticsearch.cluster.routing.allocation.allocator.BalancedShardsAllocator;
@@ -45,24 +46,106 @@
4546

4647
import static org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider.CLUSTER_ROUTING_ALLOCATION_ENABLE_SETTING;
4748
import static org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider.CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING;
49+
import static org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider.INDEX_ROUTING_REBALANCE_ENABLE_SETTING;
50+
import static org.hamcrest.Matchers.equalTo;
51+
import static org.hamcrest.Matchers.greaterThan;
4852

4953
public class EnableAllocationShortCircuitTests extends ESAllocationTestCase {
5054

55+
private static ClusterState createClusterStateWithAllShardsAssigned() {
56+
AllocationService allocationService = createAllocationService(Settings.EMPTY);
57+
58+
final int numberOfNodes = randomIntBetween(1, 5);
59+
final DiscoveryNodes.Builder discoveryNodesBuilder = DiscoveryNodes.builder();
60+
for (int i = 0; i < numberOfNodes; i++) {
61+
discoveryNodesBuilder.add(newNode("node" + i));
62+
}
63+
64+
final MetaData.Builder metadataBuilder = MetaData.builder();
65+
final RoutingTable.Builder routingTableBuilder = RoutingTable.builder();
66+
for (int i = randomIntBetween(1, 10); i >= 0; i--) {
67+
final IndexMetaData indexMetaData = IndexMetaData.builder("test" + i).settings(settings(Version.CURRENT))
68+
.numberOfShards(1).numberOfReplicas(randomIntBetween(0, numberOfNodes - 1)).build();
69+
metadataBuilder.put(indexMetaData, true);
70+
routingTableBuilder.addAsNew(indexMetaData);
71+
}
72+
73+
ClusterState clusterState = ClusterState.builder(ClusterName.CLUSTER_NAME_SETTING.get(Settings.EMPTY))
74+
.nodes(discoveryNodesBuilder).metaData(metadataBuilder).routingTable(routingTableBuilder.build()).build();
75+
76+
while (clusterState.getRoutingNodes().hasUnassignedShards()
77+
|| clusterState.getRoutingNodes().shardsWithState(ShardRoutingState.INITIALIZING).isEmpty() == false) {
78+
clusterState = allocationService.applyStartedShards(clusterState,
79+
clusterState.getRoutingNodes().shardsWithState(ShardRoutingState.INITIALIZING));
80+
clusterState = allocationService.reroute(clusterState, "reroute");
81+
}
82+
83+
return clusterState;
84+
}
85+
86+
public void testRebalancingAttemptedIfPermitted() {
87+
ClusterState clusterState = createClusterStateWithAllShardsAssigned();
88+
89+
final RebalanceShortCircuitPlugin plugin = new RebalanceShortCircuitPlugin();
90+
AllocationService allocationService = createAllocationService(Settings.builder()
91+
.put(CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING.getKey(),
92+
randomFrom(EnableAllocationDecider.Allocation.ALL,
93+
EnableAllocationDecider.Allocation.NEW_PRIMARIES,
94+
EnableAllocationDecider.Allocation.PRIMARIES).name()),
95+
plugin);
96+
allocationService.reroute(clusterState, "reroute").routingTable();
97+
assertThat(plugin.rebalanceAttempts, greaterThan(0));
98+
}
99+
51100
public void testRebalancingSkippedIfDisabled() {
101+
ClusterState clusterState = createClusterStateWithAllShardsAssigned();
102+
103+
final RebalanceShortCircuitPlugin plugin = new RebalanceShortCircuitPlugin();
52104
AllocationService allocationService = createAllocationService(Settings.builder()
53105
.put(CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING.getKey(), EnableAllocationDecider.Allocation.NONE.name()),
54-
new RebalanceShortCircuitPlugin());
106+
plugin);
107+
allocationService.reroute(clusterState, "reroute").routingTable();
108+
assertThat(plugin.rebalanceAttempts, equalTo(0));
109+
}
55110

56-
ClusterState clusterState = ClusterState.builder(ClusterName.CLUSTER_NAME_SETTING.get(Settings.EMPTY))
57-
.nodes(DiscoveryNodes.builder().add(newNode("node1"))).build();
111+
public void testRebalancingSkippedIfDisabledIncludingOnSpecificIndices() {
112+
ClusterState clusterState = createClusterStateWithAllShardsAssigned();
113+
final IndexMetaData indexMetaData = randomFrom(clusterState.metaData().indices().values().toArray(IndexMetaData.class));
114+
clusterState = ClusterState.builder(clusterState).metaData(MetaData.builder(clusterState.metaData())
115+
.put(IndexMetaData.builder(indexMetaData).settings(Settings.builder().put(indexMetaData.getSettings())
116+
.put(INDEX_ROUTING_REBALANCE_ENABLE_SETTING.getKey(), EnableAllocationDecider.Rebalance.NONE.name()))).build()).build();
117+
118+
final RebalanceShortCircuitPlugin plugin = new RebalanceShortCircuitPlugin();
119+
AllocationService allocationService = createAllocationService(Settings.builder()
120+
.put(CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING.getKey(), EnableAllocationDecider.Rebalance.NONE.name()),
121+
plugin);
122+
allocationService.reroute(clusterState, "reroute").routingTable();
123+
assertThat(plugin.rebalanceAttempts, equalTo(0));
124+
}
58125

126+
public void testRebalancingAttemptedIfDisabledButOverridenOnSpecificIndices() {
127+
ClusterState clusterState = createClusterStateWithAllShardsAssigned();
128+
final IndexMetaData indexMetaData = randomFrom(clusterState.metaData().indices().values().toArray(IndexMetaData.class));
129+
clusterState = ClusterState.builder(clusterState).metaData(MetaData.builder(clusterState.metaData())
130+
.put(IndexMetaData.builder(indexMetaData).settings(Settings.builder().put(indexMetaData.getSettings())
131+
.put(INDEX_ROUTING_REBALANCE_ENABLE_SETTING.getKey(),
132+
randomFrom(EnableAllocationDecider.Allocation.ALL,
133+
EnableAllocationDecider.Allocation.NEW_PRIMARIES,
134+
EnableAllocationDecider.Allocation.PRIMARIES).name()))).build()).build();
135+
136+
final RebalanceShortCircuitPlugin plugin = new RebalanceShortCircuitPlugin();
137+
AllocationService allocationService = createAllocationService(Settings.builder()
138+
.put(CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING.getKey(), EnableAllocationDecider.Rebalance.NONE.name()),
139+
plugin);
59140
allocationService.reroute(clusterState, "reroute").routingTable();
141+
assertThat(plugin.rebalanceAttempts, greaterThan(0));
60142
}
61143

62144
public void testAllocationSkippedIfDisabled() {
145+
final AllocateShortCircuitPlugin plugin = new AllocateShortCircuitPlugin();
63146
AllocationService allocationService = createAllocationService(Settings.builder()
64147
.put(CLUSTER_ROUTING_ALLOCATION_ENABLE_SETTING.getKey(), EnableAllocationDecider.Allocation.NONE.name()),
65-
new AllocateShortCircuitPlugin());
148+
plugin);
66149

67150
MetaData metaData = MetaData.builder()
68151
.put(IndexMetaData.builder("test").settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(0))
@@ -76,6 +159,7 @@ public void testAllocationSkippedIfDisabled() {
76159
.metaData(metaData).routingTable(routingTable).nodes(DiscoveryNodes.builder().add(newNode("node1"))).build();
77160

78161
allocationService.reroute(clusterState, "reroute").routingTable();
162+
assertThat(plugin.canAllocateAttempts, equalTo(0));
79163
}
80164

81165
private static AllocationService createAllocationService(Settings.Builder settings, ClusterPlugin plugin) {
@@ -88,49 +172,61 @@ private static AllocationService createAllocationService(Settings.Builder settin
88172
}
89173

90174
private static class RebalanceShortCircuitPlugin implements ClusterPlugin {
175+
int rebalanceAttempts;
176+
91177
@Override
92178
public Collection<AllocationDecider> createAllocationDeciders(Settings settings, ClusterSettings clusterSettings) {
93179
return Collections.singletonList(new RebalanceShortCircuitAllocationDecider());
94180
}
95181

96-
private static class RebalanceShortCircuitAllocationDecider extends AllocationDecider {
182+
private class RebalanceShortCircuitAllocationDecider extends AllocationDecider {
183+
97184
@Override
98185
public Decision canRebalance(ShardRouting shardRouting, RoutingAllocation allocation) {
99-
throw new AssertionError("canRebalance was not bypassed");
186+
rebalanceAttempts++;
187+
return super.canRebalance(shardRouting, allocation);
100188
}
101189

102190
@Override
103191
public Decision canRebalance(RoutingAllocation allocation) {
104-
throw new AssertionError("canRebalance was not bypassed");
192+
rebalanceAttempts++;
193+
return super.canRebalance(allocation);
105194
}
106195
}
107196
}
108197

109198
private static class AllocateShortCircuitPlugin implements ClusterPlugin {
199+
int canAllocateAttempts;
200+
110201
@Override
111202
public Collection<AllocationDecider> createAllocationDeciders(Settings settings, ClusterSettings clusterSettings) {
112203
return Collections.singletonList(new AllocateShortCircuitAllocationDecider());
113204
}
114205

115-
private static class AllocateShortCircuitAllocationDecider extends AllocationDecider {
206+
private class AllocateShortCircuitAllocationDecider extends AllocationDecider {
207+
116208
@Override
117209
public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, RoutingAllocation allocation) {
118-
throw new AssertionError("canAllocate was not bypassed");
210+
canAllocateAttempts++;
211+
return super.canAllocate(shardRouting, node, allocation);
119212
}
120213

121214
@Override
122215
public Decision canAllocate(ShardRouting shardRouting, RoutingAllocation allocation) {
123-
throw new AssertionError("canAllocate was not bypassed");
216+
canAllocateAttempts++;
217+
return super.canAllocate(shardRouting, allocation);
124218
}
125219

126220
@Override
127221
public Decision canAllocate(IndexMetaData indexMetaData, RoutingNode node, RoutingAllocation allocation) {
128-
throw new AssertionError("canAllocate was not bypassed");
222+
canAllocateAttempts++;
223+
return super.canAllocate(indexMetaData, node, allocation);
129224
}
130225

131226
@Override
132227
public Decision canAllocate(RoutingNode node, RoutingAllocation allocation) {
133-
throw new AssertionError("canAllocate was not bypassed");
228+
canAllocateAttempts++;
229+
return super.canAllocate(node, allocation);
134230
}
135231
}
136232
}

0 commit comments

Comments
 (0)