InternalClusterInfoService should not ignore hidden indices (#62995) (#63048)

Today InternalClusterInfoService ignores hidden indices when
retrieving shard stats of the cluster. This can lead to suboptimal
shard allocation decisions as the size of shards are taken into
account when allocating new shards or rebalancing existing shards.
This commit is contained in:
Tanguy Leroux 2020-09-30 11:02:57 +02:00 committed by GitHub
parent ee985ea716
commit b099bfb789
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 11 deletions

View File

@ -41,8 +41,10 @@ import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.shard.IndexShard; import org.elasticsearch.index.shard.IndexShard;
import org.elasticsearch.index.store.Store; import org.elasticsearch.index.store.Store;
import org.elasticsearch.indices.IndicesService; import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.indices.SystemIndexDescriptor;
import org.elasticsearch.plugins.ActionPlugin; import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.plugins.SystemIndexPlugin;
import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.InternalTestCluster; import org.elasticsearch.test.InternalTestCluster;
import org.elasticsearch.test.transport.MockTransportService; import org.elasticsearch.test.transport.MockTransportService;
@ -51,7 +53,9 @@ import org.hamcrest.Matchers;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@ -70,7 +74,9 @@ import static org.hamcrest.Matchers.greaterThanOrEqualTo;
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0) @ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0)
public class ClusterInfoServiceIT extends ESIntegTestCase { public class ClusterInfoServiceIT extends ESIntegTestCase {
public static class TestPlugin extends Plugin implements ActionPlugin { private static final String TEST_SYSTEM_INDEX_NAME = ".test-cluster-info-system-index";
public static class TestPlugin extends Plugin implements ActionPlugin, SystemIndexPlugin {
private final BlockingActionFilter blockingActionFilter; private final BlockingActionFilter blockingActionFilter;
@ -82,6 +88,12 @@ public class ClusterInfoServiceIT extends ESIntegTestCase {
public List<ActionFilter> getActionFilters() { public List<ActionFilter> getActionFilters() {
return singletonList(blockingActionFilter); return singletonList(blockingActionFilter);
} }
@Override
public Collection<SystemIndexDescriptor> getSystemIndexDescriptors(Settings settings) {
return Collections.singletonList(new SystemIndexDescriptor(TEST_SYSTEM_INDEX_NAME,
"System index for [" + getTestClass().getName() + ']'));
}
} }
public static class BlockingActionFilter extends org.elasticsearch.action.support.ActionFilter.Simple { public static class BlockingActionFilter extends org.elasticsearch.action.support.ActionFilter.Simple {
@ -117,13 +129,18 @@ public class ClusterInfoServiceIT extends ESIntegTestCase {
public void testClusterInfoServiceCollectsInformation() { public void testClusterInfoServiceCollectsInformation() {
internalCluster().startNodes(2); internalCluster().startNodes(2);
assertAcked(prepareCreate("test").setSettings(Settings.builder()
final String indexName = randomBoolean() ? randomAlphaOfLength(5).toLowerCase(Locale.ROOT) : TEST_SYSTEM_INDEX_NAME;
assertAcked(prepareCreate(indexName)
.setSettings(Settings.builder()
.put(Store.INDEX_STORE_STATS_REFRESH_INTERVAL_SETTING.getKey(), 0) .put(Store.INDEX_STORE_STATS_REFRESH_INTERVAL_SETTING.getKey(), 0)
.put(EnableAllocationDecider.INDEX_ROUTING_REBALANCE_ENABLE_SETTING.getKey(), EnableAllocationDecider.Rebalance.NONE).build())); .put(EnableAllocationDecider.INDEX_ROUTING_REBALANCE_ENABLE_SETTING.getKey(), EnableAllocationDecider.Rebalance.NONE)
.put(IndexMetadata.SETTING_INDEX_HIDDEN, randomBoolean())
.build()));
if (randomBoolean()) { if (randomBoolean()) {
assertAcked(client().admin().indices().prepareClose("test")); assertAcked(client().admin().indices().prepareClose(indexName));
} }
ensureGreen("test"); ensureGreen(indexName);
InternalTestCluster internalTestCluster = internalCluster(); InternalTestCluster internalTestCluster = internalCluster();
// Get the cluster info service on the master node // Get the cluster info service on the master node
final InternalClusterInfoService infoService = (InternalClusterInfoService) internalTestCluster final InternalClusterInfoService infoService = (InternalClusterInfoService) internalTestCluster

View File

@ -206,7 +206,7 @@ public class InternalClusterInfoService implements ClusterInfoService, ClusterSt
final IndicesStatsRequest indicesStatsRequest = new IndicesStatsRequest(); final IndicesStatsRequest indicesStatsRequest = new IndicesStatsRequest();
indicesStatsRequest.clear(); indicesStatsRequest.clear();
indicesStatsRequest.store(true); indicesStatsRequest.store(true);
indicesStatsRequest.indicesOptions(IndicesOptions.STRICT_EXPAND_OPEN_CLOSED); indicesStatsRequest.indicesOptions(IndicesOptions.STRICT_EXPAND_OPEN_CLOSED_HIDDEN);
client.admin().indices().stats(indicesStatsRequest, new LatchedActionListener<>(listener, latch)); client.admin().indices().stats(indicesStatsRequest, new LatchedActionListener<>(listener, latch));
return latch; return latch;
@ -348,8 +348,8 @@ public class InternalClusterInfoService implements ClusterInfoService, ClusterSt
} }
static void fillDiskUsagePerNode(Logger logger, List<NodeStats> nodeStatsArray, static void fillDiskUsagePerNode(Logger logger, List<NodeStats> nodeStatsArray,
ImmutableOpenMap.Builder<String, DiskUsage> newLeastAvaiableUsages, ImmutableOpenMap.Builder<String, DiskUsage> newLeastAvailableUsages,
ImmutableOpenMap.Builder<String, DiskUsage> newMostAvaiableUsages) { ImmutableOpenMap.Builder<String, DiskUsage> newMostAvailableUsages) {
for (NodeStats nodeStats : nodeStatsArray) { for (NodeStats nodeStats : nodeStatsArray) {
if (nodeStats.getFs() == null) { if (nodeStats.getFs() == null) {
logger.warn("Unable to retrieve node FS stats for {}", nodeStats.getNode().getName()); logger.warn("Unable to retrieve node FS stats for {}", nodeStats.getNode().getName());
@ -380,7 +380,7 @@ public class InternalClusterInfoService implements ClusterInfoService, ClusterSt
nodeId, leastAvailablePath.getTotal().getBytes()); nodeId, leastAvailablePath.getTotal().getBytes());
} }
} else { } else {
newLeastAvaiableUsages.put(nodeId, new DiskUsage(nodeId, nodeName, leastAvailablePath.getPath(), newLeastAvailableUsages.put(nodeId, new DiskUsage(nodeId, nodeName, leastAvailablePath.getPath(),
leastAvailablePath.getTotal().getBytes(), leastAvailablePath.getAvailable().getBytes())); leastAvailablePath.getTotal().getBytes(), leastAvailablePath.getAvailable().getBytes()));
} }
if (mostAvailablePath.getTotal().getBytes() < 0) { if (mostAvailablePath.getTotal().getBytes() < 0) {
@ -389,7 +389,7 @@ public class InternalClusterInfoService implements ClusterInfoService, ClusterSt
nodeId, mostAvailablePath.getTotal().getBytes()); nodeId, mostAvailablePath.getTotal().getBytes());
} }
} else { } else {
newMostAvaiableUsages.put(nodeId, new DiskUsage(nodeId, nodeName, mostAvailablePath.getPath(), newMostAvailableUsages.put(nodeId, new DiskUsage(nodeId, nodeName, mostAvailablePath.getPath(),
mostAvailablePath.getTotal().getBytes(), mostAvailablePath.getAvailable().getBytes())); mostAvailablePath.getTotal().getBytes(), mostAvailablePath.getAvailable().getBytes()));
} }