From fa5b48d2f7de209a046de7b897d2f64709b80e29 Mon Sep 17 00:00:00 2001 From: chenheng Date: Mon, 25 Apr 2016 18:08:36 +0800 Subject: [PATCH] HBASE-15702 Improve PerClientRandomNonceGenerator --- .../hbase/client/ConnectionImplementation.java | 28 +++++++++++++++------- .../client/PerClientRandomNonceGenerator.java | 25 +++++++++++++++---- .../hbase/client/CoprocessorHConnection.java | 2 +- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java index 9a7dfc7..d039793 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java @@ -124,8 +124,6 @@ class ConnectionImplementation implements ClusterConnection, Closeable { * Once it's set under nonceGeneratorCreateLock, it is never unset or changed. */ private static volatile NonceGenerator nonceGenerator = null; - /** The nonce generator lock. Only taken when creating HConnection, which gets a private copy. */ - private static Object nonceGeneratorCreateLock = new Object(); private final AsyncProcess asyncProcess; // single tracker per connection @@ -203,13 +201,9 @@ class ConnectionImplementation implements ClusterConnection, Closeable { HConstants.HBASE_RPC_TIMEOUT_KEY, HConstants.DEFAULT_HBASE_RPC_TIMEOUT); if (conf.getBoolean(CLIENT_NONCES_ENABLED_KEY, true)) { - synchronized (nonceGeneratorCreateLock) { - if (nonceGenerator == null) { - nonceGenerator = new PerClientRandomNonceGenerator(); - } - } + nonceGenerator = PerClientRandomNonceGenerator.getInstance(); } else { - nonceGenerator = new NoNonceGenerator(); + nonceGenerator = NoNonceGenerator.getInstance(); } this.stats = ServerStatisticTracker.create(conf); @@ -1021,7 +1015,23 @@ class ConnectionImplementation implements ClusterConnection, Closeable { } /** Dummy nonce generator for disabled nonces. */ - static class NoNonceGenerator implements NonceGenerator { + final static class NoNonceGenerator implements NonceGenerator { + + private static NoNonceGenerator noNonceGenerator = null; + + public static NoNonceGenerator getInstance() { + if (noNonceGenerator == null) { + synchronized (NoNonceGenerator.class) { + if (noNonceGenerator == null) { + noNonceGenerator = new NoNonceGenerator(); + } + } + } + return noNonceGenerator; + } + + private NoNonceGenerator() {} + @Override public long getNonceGroup() { return HConstants.NO_NONCE; diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/PerClientRandomNonceGenerator.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/PerClientRandomNonceGenerator.java index 875e1f6..47a9256 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/PerClientRandomNonceGenerator.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/PerClientRandomNonceGenerator.java @@ -18,8 +18,10 @@ */ package org.apache.hadoop.hbase.client; +import com.google.common.annotations.VisibleForTesting; + +import io.netty.util.internal.ThreadLocalRandom; import java.util.Arrays; -import java.util.Random; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.classification.InterfaceAudience; @@ -30,12 +32,25 @@ import org.apache.hadoop.hbase.classification.InterfaceAudience; */ @InterfaceAudience.Private public class PerClientRandomNonceGenerator implements NonceGenerator { - private final Random rdm = new Random(); private final long clientId; + private static PerClientRandomNonceGenerator clientRandomNonceGenerator = null; + + public static PerClientRandomNonceGenerator getInstance() { + if (clientRandomNonceGenerator == null) { + synchronized (PerClientRandomNonceGenerator.class) { + if (clientRandomNonceGenerator == null) { + clientRandomNonceGenerator = new PerClientRandomNonceGenerator(); + } + } + } + return clientRandomNonceGenerator; + } - public PerClientRandomNonceGenerator() { + @VisibleForTesting + protected PerClientRandomNonceGenerator() { byte[] clientIdBase = ClientIdGenerator.generateClientId(); - this.clientId = (((long)Arrays.hashCode(clientIdBase)) << 32) + rdm.nextInt(); + this.clientId = (((long)Arrays.hashCode(clientIdBase)) << 32) + + ThreadLocalRandom.current().nextInt(); } public long getNonceGroup() { @@ -45,7 +60,7 @@ public class PerClientRandomNonceGenerator implements NonceGenerator { public long newNonce() { long result = HConstants.NO_NONCE; do { - result = rdm.nextLong(); + result = ThreadLocalRandom.current().nextLong(); } while (result == HConstants.NO_NONCE); return result; } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/CoprocessorHConnection.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/CoprocessorHConnection.java index 285737d..81c3122 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/CoprocessorHConnection.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/CoprocessorHConnection.java @@ -40,7 +40,7 @@ import org.apache.hadoop.hbase.security.UserProvider; @InterfaceAudience.Private @InterfaceStability.Evolving public class CoprocessorHConnection extends ConnectionImplementation { - private static final NonceGenerator NO_NONCE_GEN = new NoNonceGenerator(); + private static final NonceGenerator NO_NONCE_GEN = NoNonceGenerator.getInstance(); /** * Create an {@link HConnection} based on the environment in which we are running the -- 1.9.3 (Apple Git-50)