Remove deprecated gateway settings (#53845)

This commit removes the following deprecated settings in v8:

- `gateway.expected_nodes`
- `gateway.expected_master_nodes`
- `gateway.recover_after_nodes`
- `gateway.recover_after_master_nodes`

Co-authored-by: ShawnLi1014 <shawnli1014@gmail.com>
This commit is contained in:
Tianlun Li 2021-02-03 09:10:45 -05:00 committed by GitHub
parent 86005dedaf
commit b0d185bb0d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 61 additions and 174 deletions

View file

@ -144,3 +144,25 @@ may be set to false.
Discontinue use of the removed settings. Specifying these settings in Discontinue use of the removed settings. Specifying these settings in
`elasticsearch.yml` will result in an error on startup. `elasticsearch.yml` will result in an error on startup.
==== ====
.Settings used to defer cluster recovery pending a certain number of master nodes have been removed.
[%collapsible]
====
*Details* +
The following settings were deprecated in {es} 7.8.0 and have been removed in
{es} 8.0.0:
* `gateway.expected_nodes`
* `gateway.expected_master_nodes`
* `gateway.recover_after_nodes`
* `gateway.recover_after_master_nodes`
It is safe to recover the cluster as soon as a majority of master-eligible
nodes have joined so there is no benefit in waiting for any additional
master-eligible nodes to start.
*Impact* +
Discontinue use of the removed settings. If needed, use
`gateway.expected_data_nodes` or `gateway.recover_after_data_nodes` to defer
cluster recovery pending a certain number of data nodes.
====

View file

@ -10,20 +10,6 @@ recover the cluster state and the cluster's data.
NOTE: These settings only take effect on a full cluster restart. NOTE: These settings only take effect on a full cluster restart.
`gateway.expected_nodes`::
(<<static-cluster-setting,Static>>)
deprecated:[7.7.0, This setting will be removed in 8.0. Use `gateway.expected_data_nodes` instead.]
Number of data or master nodes expected in the cluster.
Recovery of local shards begins when the expected number of
nodes join the cluster. Defaults to `0`.
`gateway.expected_master_nodes`::
(<<static-cluster-setting,Static>>)
deprecated:[7.7.0, This setting will be removed in 8.0. Use `gateway.expected_data_nodes` instead.]
Number of master nodes expected in the cluster.
Recovery of local shards begins when the expected number of
master nodes join the cluster. Defaults to `0`.
`gateway.expected_data_nodes`:: `gateway.expected_data_nodes`::
(<<static-cluster-setting,Static>>) (<<static-cluster-setting,Static>>)
Number of data nodes expected in the cluster. Number of data nodes expected in the cluster.
@ -34,25 +20,24 @@ data nodes join the cluster. Defaults to `0`.
(<<static-cluster-setting,Static>>) (<<static-cluster-setting,Static>>)
If the expected number of nodes is not achieved, the recovery process waits If the expected number of nodes is not achieved, the recovery process waits
for the configured amount of time before trying to recover. for the configured amount of time before trying to recover.
Defaults to `5m` if one of the `expected_nodes` settings is configured. Defaults to `5m`.
+ +
Once the `recover_after_time` duration has timed out, recovery will start Once the `recover_after_time` duration has timed out, recovery will start
as long as the following conditions are met: as long as the following condition is met:
`gateway.recover_after_nodes`::
(<<static-cluster-setting,Static>>)
deprecated:[7.7.0, This setting will be removed in 8.0. Use `gateway.recover_after_data_nodes` instead.]
Recover as long as this many data or master nodes have joined the cluster.
`gateway.recover_after_master_nodes`::
(<<static-cluster-setting,Static>>)
deprecated:[7.7.0, This setting will be removed in 8.0. Use `gateway.recover_after_data_nodes` instead.]
Recover as long as this many master nodes have joined the cluster.
`gateway.recover_after_data_nodes`:: `gateway.recover_after_data_nodes`::
(<<static-cluster-setting,Static>>) (<<static-cluster-setting,Static>>)
Recover as long as this many data nodes have joined the cluster. Recover as long as this many data nodes have joined the cluster.
These settings can be configured in `elasticsearch.yml` as follows:
[source,yaml]
--------------------------------------------------
gateway.expected_data_nodes: 3
gateway.recover_after_time: 600s
gateway.recover_after_data_nodes: 3
--------------------------------------------------
[[dangling-indices]] [[dangling-indices]]
==== Dangling indices ==== Dangling indices

View file

@ -18,6 +18,7 @@ import org.elasticsearch.cluster.node.DiscoveryNodeRole;
import org.elasticsearch.common.Priority; import org.elasticsearch.common.Priority;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.EsExecutors; import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.gateway.GatewayService;
import org.elasticsearch.monitor.os.OsStats; import org.elasticsearch.monitor.os.OsStats;
import org.elasticsearch.node.NodeRoleSettings; import org.elasticsearch.node.NodeRoleSettings;
import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.ESIntegTestCase;
@ -225,16 +226,12 @@ public class ClusterStatsIT extends ESIntegTestCase {
assertThat(response.getNodesStats().getOs().getAllocatedProcessors(), equalTo(nodeProcessors)); assertThat(response.getNodesStats().getOs().getAllocatedProcessors(), equalTo(nodeProcessors));
} }
public void testClusterStatusWhenStateNotRecovered() throws Exception { public void testClusterStatusWhenStateNotRecovered() {
internalCluster().startMasterOnlyNode(Settings.builder().put("gateway.recover_after_nodes", 2).build()); internalCluster().startMasterOnlyNode(Settings.builder().put(GatewayService.RECOVER_AFTER_DATA_NODES_SETTING.getKey(), 1).build());
ClusterStatsResponse response = client().admin().cluster().prepareClusterStats().get(); ClusterStatsResponse response = client().admin().cluster().prepareClusterStats().get();
assertThat(response.getStatus(), equalTo(ClusterHealthStatus.RED)); assertThat(response.getStatus(), equalTo(ClusterHealthStatus.RED));
if (randomBoolean()) { internalCluster().startDataOnlyNode();
internalCluster().startMasterOnlyNode();
} else {
internalCluster().startDataOnlyNode();
}
// wait for the cluster status to settle // wait for the cluster status to settle
ensureGreen(); ensureGreen();
response = client().admin().cluster().prepareClusterStats().get(); response = client().admin().cluster().prepareClusterStats().get();

View file

@ -62,12 +62,12 @@ public class PendingTasksBlocksIT extends ESIntegTestCase {
} }
// restart the cluster but prevent it from performing state recovery // restart the cluster but prevent it from performing state recovery
final int nodeCount = client().admin().cluster().prepareNodesInfo("data:true", "master:true").get().getNodes().size(); final int nodeCount = client().admin().cluster().prepareNodesInfo("data:true").get().getNodes().size();
internalCluster().fullRestart(new InternalTestCluster.RestartCallback() { internalCluster().fullRestart(new InternalTestCluster.RestartCallback() {
@Override @Override
public Settings onNodeStopped(String nodeName) { public Settings onNodeStopped(String nodeName) {
return Settings.builder() return Settings.builder()
.put(GatewayService.RECOVER_AFTER_NODES_SETTING.getKey(), nodeCount + 1) .put(GatewayService.RECOVER_AFTER_DATA_NODES_SETTING.getKey(), nodeCount + 1)
.build(); .build();
} }

View file

@ -19,6 +19,7 @@ import org.elasticsearch.test.ESIntegTestCase.Scope;
import java.util.Set; import java.util.Set;
import static org.elasticsearch.gateway.GatewayService.RECOVER_AFTER_DATA_NODES_SETTING;
import static org.elasticsearch.test.NodeRoles.dataOnlyNode; import static org.elasticsearch.test.NodeRoles.dataOnlyNode;
import static org.elasticsearch.test.NodeRoles.masterOnlyNode; import static org.elasticsearch.test.NodeRoles.masterOnlyNode;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
@ -44,79 +45,16 @@ public class RecoverAfterNodesIT extends ESIntegTestCase {
return internalCluster().client(name); return internalCluster().client(name);
} }
public void testRecoverAfterNodes() throws Exception { public void testRecoverAfterDataNodes() {
internalCluster().setBootstrapMasterNodeIndex(0);
logger.info("--> start node (1)");
Client clientNode1 = startNode(Settings.builder().put("gateway.recover_after_nodes", 3));
assertThat(clientNode1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start node (2)");
Client clientNode2 = startNode(Settings.builder().put("gateway.recover_after_nodes", 3));
Thread.sleep(BLOCK_WAIT_TIMEOUT.millis());
assertThat(clientNode1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
assertThat(clientNode2.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start node (3)");
Client clientNode3 = startNode(Settings.builder().put("gateway.recover_after_nodes", 3));
assertThat(waitForNoBlocksOnNode(BLOCK_WAIT_TIMEOUT, clientNode1).isEmpty(), equalTo(true));
assertThat(waitForNoBlocksOnNode(BLOCK_WAIT_TIMEOUT, clientNode2).isEmpty(), equalTo(true));
assertThat(waitForNoBlocksOnNode(BLOCK_WAIT_TIMEOUT, clientNode3).isEmpty(), equalTo(true));
}
public void testRecoverAfterMasterNodes() throws Exception {
internalCluster().setBootstrapMasterNodeIndex(0); internalCluster().setBootstrapMasterNodeIndex(0);
logger.info("--> start master_node (1)"); logger.info("--> start master_node (1)");
Client master1 = startNode(Settings.builder().put("gateway.recover_after_master_nodes", 2).put(masterOnlyNode())); Client master1 = startNode(Settings.builder().put(RECOVER_AFTER_DATA_NODES_SETTING.getKey(), 2).put(masterOnlyNode()));
assertThat(master1.admin().cluster().prepareState().setLocal(true).execute().actionGet() assertThat(master1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE), .getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK)); hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start data_node (1)"); logger.info("--> start data_node (1)");
Client data1 = startNode(Settings.builder().put("gateway.recover_after_master_nodes", 2).put(dataOnlyNode())); Client data1 = startNode(Settings.builder().put(RECOVER_AFTER_DATA_NODES_SETTING.getKey(), 2).put(dataOnlyNode()));
assertThat(master1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
assertThat(data1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start data_node (2)");
Client data2 = startNode(Settings.builder().put("gateway.recover_after_master_nodes", 2).put(dataOnlyNode()));
assertThat(master1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
assertThat(data1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
assertThat(data2.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start master_node (2)");
Client master2 = startNode(Settings.builder().put("gateway.recover_after_master_nodes", 2).put(masterOnlyNode()));
assertThat(waitForNoBlocksOnNode(BLOCK_WAIT_TIMEOUT, master1).isEmpty(), equalTo(true));
assertThat(waitForNoBlocksOnNode(BLOCK_WAIT_TIMEOUT, master2).isEmpty(), equalTo(true));
assertThat(waitForNoBlocksOnNode(BLOCK_WAIT_TIMEOUT, data1).isEmpty(), equalTo(true));
assertThat(waitForNoBlocksOnNode(BLOCK_WAIT_TIMEOUT, data2).isEmpty(), equalTo(true));
}
public void testRecoverAfterDataNodes() throws Exception {
internalCluster().setBootstrapMasterNodeIndex(0);
logger.info("--> start master_node (1)");
Client master1 = startNode(Settings.builder().put("gateway.recover_after_data_nodes", 2).put(masterOnlyNode()));
assertThat(master1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start data_node (1)");
Client data1 = startNode(Settings.builder().put("gateway.recover_after_data_nodes", 2).put(dataOnlyNode()));
assertThat(master1.admin().cluster().prepareState().setLocal(true).execute().actionGet() assertThat(master1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE), .getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK)); hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
@ -125,7 +63,7 @@ public class RecoverAfterNodesIT extends ESIntegTestCase {
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK)); hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start master_node (2)"); logger.info("--> start master_node (2)");
Client master2 = startNode(Settings.builder().put("gateway.recover_after_data_nodes", 2).put(masterOnlyNode())); Client master2 = startNode(Settings.builder().put(RECOVER_AFTER_DATA_NODES_SETTING.getKey(), 2).put(masterOnlyNode()));
assertThat(master2.admin().cluster().prepareState().setLocal(true).execute().actionGet() assertThat(master2.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE), .getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK)); hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
@ -137,7 +75,7 @@ public class RecoverAfterNodesIT extends ESIntegTestCase {
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK)); hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start data_node (2)"); logger.info("--> start data_node (2)");
Client data2 = startNode(Settings.builder().put("gateway.recover_after_data_nodes", 2).put(dataOnlyNode())); Client data2 = startNode(Settings.builder().put(RECOVER_AFTER_DATA_NODES_SETTING.getKey(), 2).put(dataOnlyNode()));
assertThat(waitForNoBlocksOnNode(BLOCK_WAIT_TIMEOUT, master1).isEmpty(), equalTo(true)); assertThat(waitForNoBlocksOnNode(BLOCK_WAIT_TIMEOUT, master1).isEmpty(), equalTo(true));
assertThat(waitForNoBlocksOnNode(BLOCK_WAIT_TIMEOUT, master2).isEmpty(), equalTo(true)); assertThat(waitForNoBlocksOnNode(BLOCK_WAIT_TIMEOUT, master2).isEmpty(), equalTo(true));
assertThat(waitForNoBlocksOnNode(BLOCK_WAIT_TIMEOUT, data1).isEmpty(), equalTo(true)); assertThat(waitForNoBlocksOnNode(BLOCK_WAIT_TIMEOUT, data1).isEmpty(), equalTo(true));

View file

@ -62,7 +62,7 @@ import static org.elasticsearch.cluster.coordination.ClusterBootstrapService.INI
import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_NUMBER_OF_REPLICAS; import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_NUMBER_OF_REPLICAS;
import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_NUMBER_OF_SHARDS; import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_NUMBER_OF_SHARDS;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.gateway.GatewayService.RECOVER_AFTER_NODES_SETTING; import static org.elasticsearch.gateway.GatewayService.RECOVER_AFTER_DATA_NODES_SETTING;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery; import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
@ -304,7 +304,7 @@ public class RecoveryFromGatewayIT extends ESIntegTestCase {
@Override @Override
public Settings onNodeStopped(String nodeName) { public Settings onNodeStopped(String nodeName) {
return Settings.builder() return Settings.builder()
.put(RECOVER_AFTER_NODES_SETTING.getKey(), 2) .put(RECOVER_AFTER_DATA_NODES_SETTING.getKey(), 2)
.putList(INITIAL_MASTER_NODES_SETTING.getKey()) // disable bootstrapping .putList(INITIAL_MASTER_NODES_SETTING.getKey()) // disable bootstrapping
.build(); .build();
} }
@ -329,7 +329,7 @@ public class RecoveryFromGatewayIT extends ESIntegTestCase {
public void testLatestVersionLoaded() throws Exception { public void testLatestVersionLoaded() throws Exception {
// clean two nodes // clean two nodes
List<String> nodes = internalCluster().startNodes(2, Settings.builder().put("gateway.recover_after_nodes", 2).build()); List<String> nodes = internalCluster().startNodes(2, Settings.builder().put(RECOVER_AFTER_DATA_NODES_SETTING.getKey(), 2).build());
Settings node1DataPathSettings = internalCluster().dataPathSettings(nodes.get(0)); Settings node1DataPathSettings = internalCluster().dataPathSettings(nodes.get(0));
Settings node2DataPathSettings = internalCluster().dataPathSettings(nodes.get(1)); Settings node2DataPathSettings = internalCluster().dataPathSettings(nodes.get(1));
@ -386,8 +386,8 @@ public class RecoveryFromGatewayIT extends ESIntegTestCase {
logger.info("--> starting the two nodes back"); logger.info("--> starting the two nodes back");
internalCluster().startNodes( internalCluster().startNodes(
Settings.builder().put(node1DataPathSettings).put("gateway.recover_after_nodes", 2).build(), Settings.builder().put(node1DataPathSettings).put(RECOVER_AFTER_DATA_NODES_SETTING.getKey(), 2).build(),
Settings.builder().put(node2DataPathSettings).put("gateway.recover_after_nodes", 2).build()); Settings.builder().put(node2DataPathSettings).put(RECOVER_AFTER_DATA_NODES_SETTING.getKey(), 2).build());
logger.info("--> running cluster_health (wait for the shards to startup)"); logger.info("--> running cluster_health (wait for the shards to startup)");
ensureGreen(); ensureGreen();
@ -542,7 +542,7 @@ public class RecoveryFromGatewayIT extends ESIntegTestCase {
@Override @Override
public Settings onNodeStopped(String nodeName) throws Exception { public Settings onNodeStopped(String nodeName) throws Exception {
// make sure state is not recovered // make sure state is not recovered
return Settings.builder().put(RECOVER_AFTER_NODES_SETTING.getKey(), 2).build(); return Settings.builder().put(RECOVER_AFTER_DATA_NODES_SETTING.getKey(), 2).build();
} }
}); });

View file

@ -229,11 +229,7 @@ public final class ClusterSettings extends AbstractScopedSettings {
DestructiveOperations.REQUIRES_NAME_SETTING, DestructiveOperations.REQUIRES_NAME_SETTING,
NoMasterBlockService.NO_MASTER_BLOCK_SETTING, NoMasterBlockService.NO_MASTER_BLOCK_SETTING,
GatewayService.EXPECTED_DATA_NODES_SETTING, GatewayService.EXPECTED_DATA_NODES_SETTING,
GatewayService.EXPECTED_MASTER_NODES_SETTING,
GatewayService.EXPECTED_NODES_SETTING,
GatewayService.RECOVER_AFTER_DATA_NODES_SETTING, GatewayService.RECOVER_AFTER_DATA_NODES_SETTING,
GatewayService.RECOVER_AFTER_MASTER_NODES_SETTING,
GatewayService.RECOVER_AFTER_NODES_SETTING,
GatewayService.RECOVER_AFTER_TIME_SETTING, GatewayService.RECOVER_AFTER_TIME_SETTING,
PersistedClusterStateService.SLOW_WRITE_LOGGING_THRESHOLD, PersistedClusterStateService.SLOW_WRITE_LOGGING_THRESHOLD,
NetworkModule.HTTP_DEFAULT_TYPE_SETTING, NetworkModule.HTTP_DEFAULT_TYPE_SETTING,

View file

@ -40,20 +40,12 @@ import java.util.function.Function;
public class GatewayService extends AbstractLifecycleComponent implements ClusterStateListener { public class GatewayService extends AbstractLifecycleComponent implements ClusterStateListener {
private static final Logger logger = LogManager.getLogger(GatewayService.class); private static final Logger logger = LogManager.getLogger(GatewayService.class);
public static final Setting<Integer> EXPECTED_NODES_SETTING =
Setting.intSetting("gateway.expected_nodes", -1, -1, Property.NodeScope, Property.Deprecated);
public static final Setting<Integer> EXPECTED_DATA_NODES_SETTING = public static final Setting<Integer> EXPECTED_DATA_NODES_SETTING =
Setting.intSetting("gateway.expected_data_nodes", -1, -1, Property.NodeScope); Setting.intSetting("gateway.expected_data_nodes", -1, -1, Property.NodeScope);
public static final Setting<Integer> EXPECTED_MASTER_NODES_SETTING =
Setting.intSetting("gateway.expected_master_nodes", -1, -1, Property.NodeScope, Property.Deprecated);
public static final Setting<TimeValue> RECOVER_AFTER_TIME_SETTING = public static final Setting<TimeValue> RECOVER_AFTER_TIME_SETTING =
Setting.positiveTimeSetting("gateway.recover_after_time", TimeValue.timeValueMillis(0), Property.NodeScope); Setting.positiveTimeSetting("gateway.recover_after_time", TimeValue.timeValueMillis(0), Property.NodeScope);
public static final Setting<Integer> RECOVER_AFTER_NODES_SETTING =
Setting.intSetting("gateway.recover_after_nodes", -1, -1, Property.NodeScope, Property.Deprecated);
public static final Setting<Integer> RECOVER_AFTER_DATA_NODES_SETTING = public static final Setting<Integer> RECOVER_AFTER_DATA_NODES_SETTING =
Setting.intSetting("gateway.recover_after_data_nodes", -1, -1, Property.NodeScope); Setting.intSetting("gateway.recover_after_data_nodes", -1, -1, Property.NodeScope);
public static final Setting<Integer> RECOVER_AFTER_MASTER_NODES_SETTING =
Setting.intSetting("gateway.recover_after_master_nodes", 0, 0, Property.NodeScope, Property.Deprecated);
public static final ClusterBlock STATE_NOT_RECOVERED_BLOCK = new ClusterBlock(1, "state not recovered / initialized", true, true, public static final ClusterBlock STATE_NOT_RECOVERED_BLOCK = new ClusterBlock(1, "state not recovered / initialized", true, true,
false, RestStatus.SERVICE_UNAVAILABLE, ClusterBlockLevel.ALL); false, RestStatus.SERVICE_UNAVAILABLE, ClusterBlockLevel.ALL);
@ -67,12 +59,8 @@ public class GatewayService extends AbstractLifecycleComponent implements Cluste
private final ClusterService clusterService; private final ClusterService clusterService;
private final TimeValue recoverAfterTime; private final TimeValue recoverAfterTime;
private final int recoverAfterNodes;
private final int expectedNodes;
private final int recoverAfterDataNodes; private final int recoverAfterDataNodes;
private final int expectedDataNodes; private final int expectedDataNodes;
private final int recoverAfterMasterNodes;
private final int expectedMasterNodes;
private final Runnable recoveryRunnable; private final Runnable recoveryRunnable;
@ -85,26 +73,16 @@ public class GatewayService extends AbstractLifecycleComponent implements Cluste
this.allocationService = allocationService; this.allocationService = allocationService;
this.clusterService = clusterService; this.clusterService = clusterService;
this.threadPool = threadPool; this.threadPool = threadPool;
// allow to control a delay of when indices will get created
this.expectedNodes = EXPECTED_NODES_SETTING.get(settings);
this.expectedDataNodes = EXPECTED_DATA_NODES_SETTING.get(settings); this.expectedDataNodes = EXPECTED_DATA_NODES_SETTING.get(settings);
this.expectedMasterNodes = EXPECTED_MASTER_NODES_SETTING.get(settings);
if (RECOVER_AFTER_TIME_SETTING.exists(settings)) { if (RECOVER_AFTER_TIME_SETTING.exists(settings)) {
recoverAfterTime = RECOVER_AFTER_TIME_SETTING.get(settings); recoverAfterTime = RECOVER_AFTER_TIME_SETTING.get(settings);
} else if (expectedNodes >= 0 || expectedDataNodes >= 0 || expectedMasterNodes >= 0) { } else if (expectedDataNodes >= 0) {
recoverAfterTime = DEFAULT_RECOVER_AFTER_TIME_IF_EXPECTED_NODES_IS_SET; recoverAfterTime = DEFAULT_RECOVER_AFTER_TIME_IF_EXPECTED_NODES_IS_SET;
} else { } else {
recoverAfterTime = null; recoverAfterTime = null;
} }
this.recoverAfterNodes = RECOVER_AFTER_NODES_SETTING.get(settings);
this.recoverAfterDataNodes = RECOVER_AFTER_DATA_NODES_SETTING.get(settings); this.recoverAfterDataNodes = RECOVER_AFTER_DATA_NODES_SETTING.get(settings);
// default the recover after master nodes to the minimum master nodes in the discovery
if (RECOVER_AFTER_MASTER_NODES_SETTING.exists(settings)) {
recoverAfterMasterNodes = RECOVER_AFTER_MASTER_NODES_SETTING.get(settings);
} else {
recoverAfterMasterNodes = -1;
}
if (discovery instanceof Coordinator) { if (discovery instanceof Coordinator) {
recoveryRunnable = () -> recoveryRunnable = () ->
@ -153,37 +131,24 @@ public class GatewayService extends AbstractLifecycleComponent implements Cluste
final DiscoveryNodes nodes = state.nodes(); final DiscoveryNodes nodes = state.nodes();
if (state.nodes().getMasterNodeId() == null) { if (state.nodes().getMasterNodeId() == null) {
logger.debug("not recovering from gateway, no master elected yet"); logger.debug("not recovering from gateway, no master elected yet");
} else if (recoverAfterNodes != -1 && (nodes.getMasterAndDataNodes().size()) < recoverAfterNodes) {
logger.debug("not recovering from gateway, nodes_size (data+master) [{}] < recover_after_nodes [{}]",
nodes.getMasterAndDataNodes().size(), recoverAfterNodes);
} else if (recoverAfterDataNodes != -1 && nodes.getDataNodes().size() < recoverAfterDataNodes) { } else if (recoverAfterDataNodes != -1 && nodes.getDataNodes().size() < recoverAfterDataNodes) {
logger.debug("not recovering from gateway, nodes_size (data) [{}] < recover_after_data_nodes [{}]", logger.debug("not recovering from gateway, nodes_size (data) [{}] < recover_after_data_nodes [{}]",
nodes.getDataNodes().size(), recoverAfterDataNodes); nodes.getDataNodes().size(), recoverAfterDataNodes);
} else if (recoverAfterMasterNodes != -1 && nodes.getMasterNodes().size() < recoverAfterMasterNodes) {
logger.debug("not recovering from gateway, nodes_size (master) [{}] < recover_after_master_nodes [{}]",
nodes.getMasterNodes().size(), recoverAfterMasterNodes);
} else { } else {
boolean enforceRecoverAfterTime; boolean enforceRecoverAfterTime;
String reason; String reason;
if (expectedNodes == -1 && expectedMasterNodes == -1 && expectedDataNodes == -1) { if (expectedDataNodes == -1) {
// no expected is set, honor the setting if they are there // no expected is set, honor recover_after_data_nodes
enforceRecoverAfterTime = true; enforceRecoverAfterTime = true;
reason = "recover_after_time was set to [" + recoverAfterTime + "]"; reason = "recover_after_time was set to [" + recoverAfterTime + "]";
} else { } else if (expectedDataNodes <= nodes.getDataNodes().size()) {
// one of the expected is set, see if all of them meet the need, and ignore the timeout in this case // expected is set and satisfied so recover immediately
enforceRecoverAfterTime = false; enforceRecoverAfterTime = false;
reason = ""; reason = "";
if (expectedNodes != -1 && (nodes.getMasterAndDataNodes().size() < expectedNodes)) { // does not meet the expected... } else {
enforceRecoverAfterTime = true; // expected is set but not satisfied so wait until it is satisfied or times out
reason = "expecting [" + expectedNodes + "] nodes, but only have [" + nodes.getMasterAndDataNodes().size() + "]"; enforceRecoverAfterTime = true;
} else if (expectedDataNodes != -1 && (nodes.getDataNodes().size() < expectedDataNodes)) { // does not meet the expected... reason = "expecting [" + expectedDataNodes + "] data nodes, but only have [" + nodes.getDataNodes().size() + "]";
enforceRecoverAfterTime = true;
reason = "expecting [" + expectedDataNodes + "] data nodes, but only have [" + nodes.getDataNodes().size() + "]";
} else if (expectedMasterNodes != -1 && (nodes.getMasterNodes().size() < expectedMasterNodes)) {
// does not meet the expected...
enforceRecoverAfterTime = true;
reason = "expecting [" + expectedMasterNodes + "] master nodes, but only have [" + nodes.getMasterNodes().size() + "]";
}
} }
performStateRecovery(enforceRecoverAfterTime, reason); performStateRecovery(enforceRecoverAfterTime, reason);
} }

View file

@ -24,7 +24,6 @@ import org.elasticsearch.cluster.routing.allocation.decider.ReplicaAfterPrimaryA
import org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider; import org.elasticsearch.cluster.routing.allocation.decider.SameShardAllocationDecider;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
@ -66,28 +65,13 @@ public class GatewayServiceTests extends ESTestCase {
// ensure settings override default // ensure settings override default
final TimeValue timeValue = TimeValue.timeValueHours(3); final TimeValue timeValue = TimeValue.timeValueHours(3);
// ensure default is set when setting expected_nodes // ensure default is set when setting expected_nodes
service = createService(Settings.builder().put("gateway.recover_after_time", service = createService(Settings.builder().put("gateway.recover_after_time",
timeValue.toString())); timeValue.toString()));
assertThat(service.recoverAfterTime().millis(), Matchers.equalTo(timeValue.millis())); assertThat(service.recoverAfterTime().millis(), Matchers.equalTo(timeValue.millis()));
} }
public void testDeprecatedSettings() {
GatewayService service = createService(Settings.builder());
service = createService(Settings.builder().put("gateway.expected_nodes", 1));
assertSettingDeprecationsAndWarnings(new Setting<?>[] {GatewayService.EXPECTED_NODES_SETTING });
service = createService(Settings.builder().put("gateway.expected_master_nodes", 1));
assertSettingDeprecationsAndWarnings(new Setting<?>[] {GatewayService.EXPECTED_MASTER_NODES_SETTING });
service = createService(Settings.builder().put("gateway.recover_after_nodes", 1));
assertSettingDeprecationsAndWarnings(new Setting<?>[] {GatewayService.RECOVER_AFTER_NODES_SETTING });
service = createService(Settings.builder().put("gateway.recover_after_master_nodes", 1));
assertSettingDeprecationsAndWarnings(new Setting<?>[] {GatewayService.RECOVER_AFTER_MASTER_NODES_SETTING });
}
public void testRecoverStateUpdateTask() throws Exception { public void testRecoverStateUpdateTask() throws Exception {
GatewayService service = createService(Settings.builder()); GatewayService service = createService(Settings.builder());
ClusterStateUpdateTask clusterStateUpdateTask = service.new RecoverStateUpdateTask(); ClusterStateUpdateTask clusterStateUpdateTask = service.new RecoverStateUpdateTask();