diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/client/ConnectionUtils.java hbase-server/src/main/java/org/apache/hadoop/hbase/client/ConnectionUtils.java index 1278545..8a314d1 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/client/ConnectionUtils.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/client/ConnectionUtils.java @@ -21,6 +21,7 @@ import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.hbase.HConstants; +import java.util.Random; /** * Utility used by client connections such as {@link HConnection} and @@ -29,6 +30,8 @@ import org.apache.hadoop.hbase.HConstants; @InterfaceAudience.Public @InterfaceStability.Evolving public class ConnectionUtils { + + private static final Random RANDOM = new Random(); /** * Calculate pause time. * Built on {@link HConstants#RETRY_BACKOFF}. @@ -41,6 +44,9 @@ public class ConnectionUtils { if (ntries >= HConstants.RETRY_BACKOFF.length) { ntries = HConstants.RETRY_BACKOFF.length - 1; } - return pause * HConstants.RETRY_BACKOFF[ntries]; + + long normalPause = pause * HConstants.RETRY_BACKOFF[ntries]; + long jitter = (long)(normalPause * RANDOM.nextFloat() * 0.01f); // 1% possible jitter + return normalPause + jitter; } } \ No newline at end of file diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestConnectionUtils.java hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestConnectionUtils.java new file mode 100644 index 0000000..4120ec3 --- /dev/null +++ hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestConnectionUtils.java @@ -0,0 +1,56 @@ +/** + * Copyright The Apache Software Foundation + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hbase.client; + +import org.apache.hadoop.hbase.SmallTests; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.util.Set; +import java.util.TreeSet; + +import static org.junit.Assert.assertTrue; + +@Category(SmallTests.class) +public class TestConnectionUtils { + + @Test + public void testRetryTimeJitter() { + long[] retries = new long[200]; + long baseTime = 1000000; //Larger number than reality to help test randomness. + long maxTimeExpected = (long) (baseTime * 1.01f); + for (int i = 0; i < retries.length; i++) { + retries[i] = ConnectionUtils.getPauseTime(baseTime, 0); + } + + Set retyTimeSet = new TreeSet(); + for (long l : retries) { + /*make sure that there is some jitter but only 1%*/ + assertTrue(l >= baseTime); + assertTrue(l <= maxTimeExpected); + // Add the long to the set + retyTimeSet.add(l); + } + + //Make sure that most are unique. some overlap will happen + assertTrue(retyTimeSet.size() > (retries.length * 0.80)); + } + +}