diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/CostFromRegionLoadAsRateFunction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/CostFromRegionLoadAsRateFunction.java index 88af49e1a06..e6d0cf83174 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/CostFromRegionLoadAsRateFunction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/CostFromRegionLoadAsRateFunction.java @@ -42,9 +42,9 @@ abstract class CostFromRegionLoadAsRateFunction extends CostFromRegionLoadFuncti double cost = 0; do { double current = getCostFromRl(iter.next()); - cost += current - previous; + cost += current >= previous ? current - previous : current; previous = current; } while (iter.hasNext()); return Math.max(0, cost / (regionLoadList.size() - 1)); } -} \ No newline at end of file +} diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.java index 9f9ac84dd21..bd80e15b2cd 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.java @@ -23,7 +23,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -50,7 +49,6 @@ import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.junit.ClassRule; import org.junit.Test; import org.junit.experimental.categories.Category; - import org.apache.hbase.thirdparty.org.apache.commons.collections4.CollectionUtils; @Category({ MasterTests.class, MediumTests.class }) @@ -449,6 +447,32 @@ public class TestStochasticLoadBalancer extends BalancerTestBase { assertEquals(2.5, result, 0.01); } + @Test + public void testRegionLoadCostWhenDecrease() { + List regionLoads = new ArrayList<>(); + // test region loads of [1,2,1,4] + for (int i = 1; i < 5; i++) { + int load = i == 3 ? 1 : i; + BalancerRegionLoad regionLoad = mock(BalancerRegionLoad.class); + when(regionLoad.getReadRequestsCount()).thenReturn((long)load); + when(regionLoad.getCpRequestsCount()).thenReturn((long)load); + regionLoads.add(regionLoad); + } + + Configuration conf = HBaseConfiguration.create(); + ReadRequestCostFunction readCostFunction = + new ReadRequestCostFunction(conf); + double rateResult = readCostFunction.getRegionLoadCost(regionLoads); + // read requests are treated as a rate so the average rate here is simply 1 + assertEquals(1.67, rateResult, 0.01); + + CPRequestCostFunction cpCostFunction = + new CPRequestCostFunction(conf); + rateResult = cpCostFunction.getRegionLoadCost(regionLoads); + // coprocessor requests are treated as a rate so the average rate here is simply 1 + assertEquals(1.67, rateResult, 0.01); + } + @Test public void testLosingRs() throws Exception { int numNodes = 3;