When considering the size of shadow replica indices, set size to 0
Otherwise, when trying to calculate the amount of disk usage *after* the shard has been allocated, it has incorrectly subtracted the shadow replica size. Resolves #17460
This commit is contained in:
parent
7d4ed5b19e
commit
8e01b093d0
|
@ -30,7 +30,10 @@ import org.elasticsearch.action.admin.indices.stats.IndicesStatsRequest;
|
||||||
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
|
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
|
||||||
import org.elasticsearch.action.admin.indices.stats.ShardStats;
|
import org.elasticsearch.action.admin.indices.stats.ShardStats;
|
||||||
import org.elasticsearch.action.admin.indices.stats.TransportIndicesStatsAction;
|
import org.elasticsearch.action.admin.indices.stats.TransportIndicesStatsAction;
|
||||||
|
import org.elasticsearch.cluster.ClusterState;
|
||||||
import org.elasticsearch.cluster.block.ClusterBlockException;
|
import org.elasticsearch.cluster.block.ClusterBlockException;
|
||||||
|
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||||
|
import org.elasticsearch.cluster.metadata.MetaData;
|
||||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||||
import org.elasticsearch.cluster.routing.ShardRouting;
|
import org.elasticsearch.cluster.routing.ShardRouting;
|
||||||
import org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider;
|
import org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider;
|
||||||
|
@ -330,7 +333,7 @@ public class InternalClusterInfoService extends AbstractComponent implements Clu
|
||||||
ShardStats[] stats = indicesStatsResponse.getShards();
|
ShardStats[] stats = indicesStatsResponse.getShards();
|
||||||
ImmutableOpenMap.Builder<String, Long> newShardSizes = ImmutableOpenMap.builder();
|
ImmutableOpenMap.Builder<String, Long> newShardSizes = ImmutableOpenMap.builder();
|
||||||
ImmutableOpenMap.Builder<ShardRouting, String> newShardRoutingToDataPath = ImmutableOpenMap.builder();
|
ImmutableOpenMap.Builder<ShardRouting, String> newShardRoutingToDataPath = ImmutableOpenMap.builder();
|
||||||
buildShardLevelInfo(logger, stats, newShardSizes, newShardRoutingToDataPath);
|
buildShardLevelInfo(logger, stats, newShardSizes, newShardRoutingToDataPath, clusterService.state());
|
||||||
shardSizes = newShardSizes.build();
|
shardSizes = newShardSizes.build();
|
||||||
shardRoutingToDataPath = newShardRoutingToDataPath.build();
|
shardRoutingToDataPath = newShardRoutingToDataPath.build();
|
||||||
}
|
}
|
||||||
|
@ -379,14 +382,24 @@ public class InternalClusterInfoService extends AbstractComponent implements Clu
|
||||||
}
|
}
|
||||||
|
|
||||||
static void buildShardLevelInfo(ESLogger logger, ShardStats[] stats, ImmutableOpenMap.Builder<String, Long> newShardSizes,
|
static void buildShardLevelInfo(ESLogger logger, ShardStats[] stats, ImmutableOpenMap.Builder<String, Long> newShardSizes,
|
||||||
ImmutableOpenMap.Builder<ShardRouting, String> newShardRoutingToDataPath) {
|
ImmutableOpenMap.Builder<ShardRouting, String> newShardRoutingToDataPath, ClusterState state) {
|
||||||
|
MetaData meta = state.getMetaData();
|
||||||
for (ShardStats s : stats) {
|
for (ShardStats s : stats) {
|
||||||
|
IndexMetaData indexMeta = meta.index(s.getShardRouting().index());
|
||||||
|
Settings indexSettings = indexMeta == null ? null : indexMeta.getSettings();
|
||||||
newShardRoutingToDataPath.put(s.getShardRouting(), s.getDataPath());
|
newShardRoutingToDataPath.put(s.getShardRouting(), s.getDataPath());
|
||||||
long size = s.getStats().getStore().sizeInBytes();
|
long size = s.getStats().getStore().sizeInBytes();
|
||||||
String sid = ClusterInfo.shardIdentifierFromRouting(s.getShardRouting());
|
String sid = ClusterInfo.shardIdentifierFromRouting(s.getShardRouting());
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("shard: {} size: {}", sid, size);
|
logger.trace("shard: {} size: {}", sid, size);
|
||||||
}
|
}
|
||||||
|
if (indexSettings != null && IndexMetaData.isIndexUsingShadowReplicas(indexSettings)) {
|
||||||
|
// Shards on a shared filesystem should be considered of size 0
|
||||||
|
if (logger.isTraceEnabled()) {
|
||||||
|
logger.trace("shard: {} is using shadow replicas and will be treated as size 0", sid);
|
||||||
|
}
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
newShardSizes.put(sid, size);
|
newShardSizes.put(sid, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,16 @@ import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.action.admin.cluster.node.stats.NodeStats;
|
import org.elasticsearch.action.admin.cluster.node.stats.NodeStats;
|
||||||
import org.elasticsearch.action.admin.indices.stats.CommonStats;
|
import org.elasticsearch.action.admin.indices.stats.CommonStats;
|
||||||
import org.elasticsearch.action.admin.indices.stats.ShardStats;
|
import org.elasticsearch.action.admin.indices.stats.ShardStats;
|
||||||
|
import org.elasticsearch.cluster.ClusterName;
|
||||||
|
import org.elasticsearch.cluster.ClusterState;
|
||||||
|
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||||
|
import org.elasticsearch.cluster.metadata.MetaData;
|
||||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||||
import org.elasticsearch.cluster.routing.ShardRouting;
|
import org.elasticsearch.cluster.routing.ShardRouting;
|
||||||
import org.elasticsearch.cluster.routing.ShardRoutingHelper;
|
import org.elasticsearch.cluster.routing.ShardRoutingHelper;
|
||||||
import org.elasticsearch.cluster.routing.UnassignedInfo;
|
import org.elasticsearch.cluster.routing.UnassignedInfo;
|
||||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.transport.DummyTransportAddress;
|
import org.elasticsearch.common.transport.DummyTransportAddress;
|
||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.shard.ShardPath;
|
import org.elasticsearch.index.shard.ShardPath;
|
||||||
|
@ -113,7 +118,8 @@ public class DiskUsageTests extends ESTestCase {
|
||||||
};
|
};
|
||||||
ImmutableOpenMap.Builder<String, Long> shardSizes = ImmutableOpenMap.builder();
|
ImmutableOpenMap.Builder<String, Long> shardSizes = ImmutableOpenMap.builder();
|
||||||
ImmutableOpenMap.Builder<ShardRouting, String> routingToPath = ImmutableOpenMap.builder();
|
ImmutableOpenMap.Builder<ShardRouting, String> routingToPath = ImmutableOpenMap.builder();
|
||||||
InternalClusterInfoService.buildShardLevelInfo(logger, stats, shardSizes, routingToPath);
|
ClusterState state = ClusterState.builder(new ClusterName("blarg")).version(0).build();
|
||||||
|
InternalClusterInfoService.buildShardLevelInfo(logger, stats, shardSizes, routingToPath, state);
|
||||||
assertEquals(2, shardSizes.size());
|
assertEquals(2, shardSizes.size());
|
||||||
assertTrue(shardSizes.containsKey(ClusterInfo.shardIdentifierFromRouting(test_0)));
|
assertTrue(shardSizes.containsKey(ClusterInfo.shardIdentifierFromRouting(test_0)));
|
||||||
assertTrue(shardSizes.containsKey(ClusterInfo.shardIdentifierFromRouting(test_1)));
|
assertTrue(shardSizes.containsKey(ClusterInfo.shardIdentifierFromRouting(test_1)));
|
||||||
|
@ -127,6 +133,53 @@ public class DiskUsageTests extends ESTestCase {
|
||||||
assertEquals(test1Path.getParent().getParent().getParent().toAbsolutePath().toString(), routingToPath.get(test_1));
|
assertEquals(test1Path.getParent().getParent().getParent().toAbsolutePath().toString(), routingToPath.get(test_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testFillShardsWithShadowIndices() {
|
||||||
|
final Index index = new Index("non-shadow", "0xcafe0000");
|
||||||
|
ShardRouting s0 = ShardRouting.newUnassigned(index, 0, null, false, new UnassignedInfo(UnassignedInfo.Reason.INDEX_CREATED, "foo"));
|
||||||
|
ShardRoutingHelper.initialize(s0, "node1");
|
||||||
|
ShardRoutingHelper.moveToStarted(s0);
|
||||||
|
Path i0Path = createTempDir().resolve("indices").resolve(index.getUUID()).resolve("0");
|
||||||
|
CommonStats commonStats0 = new CommonStats();
|
||||||
|
commonStats0.store = new StoreStats(100, 1);
|
||||||
|
final Index index2 = new Index("shadow", "0xcafe0001");
|
||||||
|
ShardRouting s1 = ShardRouting.newUnassigned(index2, 0, null, false, new UnassignedInfo(UnassignedInfo.Reason.INDEX_CREATED, "foo"));
|
||||||
|
ShardRoutingHelper.initialize(s1, "node2");
|
||||||
|
ShardRoutingHelper.moveToStarted(s1);
|
||||||
|
Path i1Path = createTempDir().resolve("indices").resolve(index2.getUUID()).resolve("0");
|
||||||
|
CommonStats commonStats1 = new CommonStats();
|
||||||
|
commonStats1.store = new StoreStats(1000, 1);
|
||||||
|
ShardStats[] stats = new ShardStats[] {
|
||||||
|
new ShardStats(s0, new ShardPath(false, i0Path, i0Path, s0.shardId()), commonStats0 , null),
|
||||||
|
new ShardStats(s1, new ShardPath(false, i1Path, i1Path, s1.shardId()), commonStats1 , null)
|
||||||
|
};
|
||||||
|
ImmutableOpenMap.Builder<String, Long> shardSizes = ImmutableOpenMap.builder();
|
||||||
|
ImmutableOpenMap.Builder<ShardRouting, String> routingToPath = ImmutableOpenMap.builder();
|
||||||
|
ClusterState state = ClusterState.builder(new ClusterName("blarg"))
|
||||||
|
.version(0)
|
||||||
|
.metaData(MetaData.builder()
|
||||||
|
.put(IndexMetaData.builder("non-shadow")
|
||||||
|
.settings(Settings.builder()
|
||||||
|
.put(IndexMetaData.SETTING_INDEX_UUID, "0xcafe0000")
|
||||||
|
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT))
|
||||||
|
.numberOfShards(1)
|
||||||
|
.numberOfReplicas(0))
|
||||||
|
.put(IndexMetaData.builder("shadow")
|
||||||
|
.settings(Settings.builder()
|
||||||
|
.put(IndexMetaData.SETTING_INDEX_UUID, "0xcafe0001")
|
||||||
|
.put(IndexMetaData.SETTING_SHADOW_REPLICAS, true)
|
||||||
|
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT))
|
||||||
|
.numberOfShards(1)
|
||||||
|
.numberOfReplicas(0)))
|
||||||
|
.build();
|
||||||
|
logger.info("--> calling buildShardLevelInfo with state: {}", state);
|
||||||
|
InternalClusterInfoService.buildShardLevelInfo(logger, stats, shardSizes, routingToPath, state);
|
||||||
|
assertEquals(2, shardSizes.size());
|
||||||
|
assertTrue(shardSizes.containsKey(ClusterInfo.shardIdentifierFromRouting(s0)));
|
||||||
|
assertTrue(shardSizes.containsKey(ClusterInfo.shardIdentifierFromRouting(s1)));
|
||||||
|
assertEquals(100L, shardSizes.get(ClusterInfo.shardIdentifierFromRouting(s0)).longValue());
|
||||||
|
assertEquals(0L, shardSizes.get(ClusterInfo.shardIdentifierFromRouting(s1)).longValue());
|
||||||
|
}
|
||||||
|
|
||||||
public void testFillDiskUsage() {
|
public void testFillDiskUsage() {
|
||||||
ImmutableOpenMap.Builder<String, DiskUsage> newLeastAvaiableUsages = ImmutableOpenMap.builder();
|
ImmutableOpenMap.Builder<String, DiskUsage> newLeastAvaiableUsages = ImmutableOpenMap.builder();
|
||||||
ImmutableOpenMap.Builder<String, DiskUsage> newMostAvaiableUsages = ImmutableOpenMap.builder();
|
ImmutableOpenMap.Builder<String, DiskUsage> newMostAvaiableUsages = ImmutableOpenMap.builder();
|
||||||
|
|
Loading…
Reference in New Issue