Skip to content

Commit

Permalink
Issue #10588 Display low disk watermark to be consistent with
Browse files Browse the repository at this point in the history
documentaiton

Change log entries, add convenience methods, unit tests

Correct allocation decision messages to display used space

Missed a word

Correct displayed threshold value
  • Loading branch information
mkis- committed Jun 1, 2015
1 parent 4e206cd commit 4261ee3
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 20 deletions.
4 changes: 4 additions & 0 deletions src/main/java/org/elasticsearch/cluster/DiskUsage.java
Expand Up @@ -59,6 +59,10 @@ public double getFreeDiskAsPercentage() {
return 100.0 * ((double)freeBytes / totalBytes);
}

public double getUsedDiskAsPercentage() {
return 100.0 - getFreeDiskAsPercentage();
}

public long getFreeBytes() {
return freeBytes;
}
Expand Down
Expand Up @@ -142,20 +142,20 @@ class DiskListener implements ClusterInfoService.Listener {
private void warnAboutDiskIfNeeded(DiskUsage usage) {
// Check absolute disk values
if (usage.getFreeBytes() < DiskThresholdDecider.this.freeBytesThresholdHigh.bytes()) {
logger.warn("high disk watermark [{} free] exceeded on {}, shards will be relocated away from this node",
logger.warn("high disk watermark [{}] exceeded on {}, shards will be relocated away from this node",
DiskThresholdDecider.this.freeBytesThresholdHigh, usage);
} else if (usage.getFreeBytes() < DiskThresholdDecider.this.freeBytesThresholdLow.bytes()) {
logger.info("low disk watermark [{} free] exceeded on {}, replicas will not be assigned to this node",
logger.info("low disk watermark [{}] exceeded on {}, replicas will not be assigned to this node",
DiskThresholdDecider.this.freeBytesThresholdLow, usage);
}

// Check percentage disk values
if (usage.getFreeDiskAsPercentage() < DiskThresholdDecider.this.freeDiskThresholdHigh) {
logger.warn("high disk watermark [{} free] exceeded on {}, shards will be relocated away from this node",
Strings.format1Decimals(DiskThresholdDecider.this.freeDiskThresholdHigh, "%"), usage);
logger.warn("high disk watermark [{}] exceeded on {}, shards will be relocated away from this node",
Strings.format1Decimals(100.0 - DiskThresholdDecider.this.freeDiskThresholdHigh, "%"), usage);
} else if (usage.getFreeDiskAsPercentage() < DiskThresholdDecider.this.freeDiskThresholdLow) {
logger.info("low disk watermark [{} free] exceeded on {}, replicas will not be assigned to this node",
Strings.format1Decimals(DiskThresholdDecider.this.freeDiskThresholdLow, "%"), usage);
logger.info("low disk watermark [{}] exceeded on {}, replicas will not be assigned to this node",
Strings.format1Decimals(100.0 - DiskThresholdDecider.this.freeDiskThresholdLow, "%"), usage);
}
}

Expand Down Expand Up @@ -234,6 +234,16 @@ public Double getFreeDiskThresholdHigh() {
return freeDiskThresholdHigh;
}

// For Testing
public Double getUsedDiskThresholdLow() {
return 100.0 - freeDiskThresholdLow;
}

// For Testing
public Double getUsedDiskThresholdHigh() {
return 100.0 - freeDiskThresholdHigh;
}

// For Testing
public ByteSizeValue getFreeBytesThresholdLow() {
return freeBytesThresholdLow;
Expand Down Expand Up @@ -285,6 +295,8 @@ private long getShardSize(ShardRouting routing, Map<String, Long> shardSizes) {

@Override
public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, RoutingAllocation allocation) {
double usedDiskThresholdLow = 100.0 - DiskThresholdDecider.this.freeDiskThresholdLow;
double usedDiskThresholdHigh = 100.0 - DiskThresholdDecider.this.freeDiskThresholdHigh;

// Always allow allocation if the decider is disabled
if (!enabled) {
Expand Down Expand Up @@ -342,9 +354,11 @@ public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, Routing

// First, check that the node currently over the low watermark
double freeDiskPercentage = usage.getFreeDiskAsPercentage();
// Cache the used disk percentage for displaying disk percentages consistent with documentation
double usedDiskPercentage = usage.getUsedDiskAsPercentage();
long freeBytes = usage.getFreeBytes();
if (logger.isTraceEnabled()) {
logger.trace("Node [{}] has {}% free disk", node.nodeId(), freeDiskPercentage);
logger.trace("Node [{}] has {}% used disk", node.nodeId(), usedDiskPercentage);
}

// a flag for whether the primary shard has been previously allocated
Expand Down Expand Up @@ -387,20 +401,20 @@ public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, Routing
// If the shard is a replica or has a primary that has already been allocated before, check the low threshold
if (!shardRouting.primary() || (shardRouting.primary() && primaryHasBeenAllocated)) {
if (logger.isDebugEnabled()) {
logger.debug("Less than the required {} free disk threshold ({} free) on node [{}], preventing allocation",
Strings.format1Decimals(freeDiskThresholdLow, "%"),
Strings.format1Decimals(freeDiskPercentage, "%"), node.nodeId());
logger.debug("More than the allowed {} used disk threshold ({} used) on node [{}], preventing allocation",
Strings.format1Decimals(usedDiskThresholdLow, "%"),
Strings.format1Decimals(usedDiskPercentage, "%"), node.nodeId());
}
return allocation.decision(Decision.NO, NAME, "less than required [%s%%] free disk on node, free: [%s%%]",
freeDiskThresholdLow, freeDiskPercentage);
return allocation.decision(Decision.NO, NAME, "more than allowed [%s%%] used disk on node, free: [%s%%]",
usedDiskThresholdLow, freeDiskPercentage);
} else if (freeDiskPercentage > freeDiskThresholdHigh) {
// Allow the shard to be allocated because it is primary that
// has never been allocated if it's under the high watermark
if (logger.isDebugEnabled()) {
logger.debug("Less than the required {} free disk threshold ({} free) on node [{}], " +
logger.debug("More than the allowed {} used disk threshold ({} used) on node [{}], " +
"but allowing allocation because primary has never been allocated",
Strings.format1Decimals(freeDiskThresholdLow, "%"),
Strings.format1Decimals(freeDiskPercentage, "%"), node.nodeId());
Strings.format1Decimals(usedDiskThresholdLow, "%"),
Strings.format1Decimals(usedDiskPercentage, "%"), node.nodeId());
}
return allocation.decision(Decision.YES, NAME, "primary has never been allocated before");
} else {
Expand All @@ -412,8 +426,8 @@ public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, Routing
Strings.format1Decimals(freeDiskThresholdHigh, "%"),
Strings.format1Decimals(freeDiskPercentage, "%"), node.nodeId());
}
return allocation.decision(Decision.NO, NAME, "less than required [%s%%] free disk on node, free: [%s%%]",
freeDiskThresholdLow, freeDiskPercentage);
return allocation.decision(Decision.NO, NAME, "more than allowed [%s%%] used disk on node, free: [%s%%]",
usedDiskThresholdHigh, freeDiskPercentage);
}
}

Expand All @@ -429,10 +443,10 @@ public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, Routing
freeBytesThresholdLow, new ByteSizeValue(freeBytesAfterShard));
}
if (freeSpaceAfterShard < freeDiskThresholdHigh) {
logger.warn("After allocating, node [{}] would have less than the required {} free disk threshold ({} free), preventing allocation",
logger.warn("After allocating, node [{}] would have more than the allowed {} free disk threshold ({} free), preventing allocation",
node.nodeId(), Strings.format1Decimals(freeDiskThresholdHigh, "%"), Strings.format1Decimals(freeSpaceAfterShard, "%"));
return allocation.decision(Decision.NO, NAME, "after allocation less than required [%s%%] free disk on node, free: [%s%%]",
freeDiskThresholdLow, freeSpaceAfterShard);
return allocation.decision(Decision.NO, NAME, "after allocation more than allowed [%s%%] used disk on node, free: [%s%%]",
usedDiskThresholdLow, freeSpaceAfterShard);
}

return allocation.decision(Decision.YES, NAME, "enough disk for shard on node, free: [%s]", new ByteSizeValue(freeBytes));
Expand Down
3 changes: 3 additions & 0 deletions src/test/java/org/elasticsearch/cluster/DiskUsageTests.java
Expand Up @@ -30,6 +30,7 @@ public class DiskUsageTests extends ElasticsearchTestCase {
public void diskUsageCalcTest() {
DiskUsage du = new DiskUsage("node1", "n1", 100, 40);
assertThat(du.getFreeDiskAsPercentage(), equalTo(40.0));
assertThat(du.getUsedDiskAsPercentage(), equalTo(100.0 - 40.0));
assertThat(du.getFreeBytes(), equalTo(40L));
assertThat(du.getUsedBytes(), equalTo(60L));
assertThat(du.getTotalBytes(), equalTo(100L));
Expand Down Expand Up @@ -67,11 +68,13 @@ public void randomDiskUsageTest() {
assertThat(du.getTotalBytes(), equalTo(0L));
assertThat(du.getUsedBytes(), equalTo(-free));
assertThat(du.getFreeDiskAsPercentage(), equalTo(100.0));
assertThat(du.getUsedDiskAsPercentage(), equalTo(0.0));
} else {
assertThat(du.getFreeBytes(), equalTo(free));
assertThat(du.getTotalBytes(), equalTo(total));
assertThat(du.getUsedBytes(), equalTo(total - free));
assertThat(du.getFreeDiskAsPercentage(), equalTo(100.0 * ((double) free / total)));
assertThat(du.getUsedDiskAsPercentage(), equalTo(100.0 - (100.0 * ((double) free / total))));
}
}
}
Expand Down
Expand Up @@ -20,6 +20,7 @@
package org.elasticsearch.cluster.routing.allocation.decider;

import com.google.common.collect.ImmutableMap;

import org.elasticsearch.cluster.ClusterInfo;
import org.elasticsearch.cluster.ClusterInfoService;
import org.elasticsearch.cluster.DiskUsage;
Expand Down Expand Up @@ -62,6 +63,7 @@ public void addListener(Listener listener) {
assertThat(decider.getFreeDiskThresholdHigh(), equalTo(10.0d));
assertThat(decider.getFreeBytesThresholdLow(), equalTo(ByteSizeValue.parseBytesSizeValue("0b")));
assertThat(decider.getFreeDiskThresholdLow(), equalTo(15.0d));
assertThat(decider.getUsedDiskThresholdLow(), equalTo(85.0d));
assertThat(decider.getRerouteInterval().seconds(), equalTo(60L));
assertTrue(decider.isEnabled());
assertTrue(decider.isIncludeRelocations());
Expand Down

0 comments on commit 4261ee3

Please sign in to comment.