From b9e1d4d45f2208bd5fa6cdac5c335f80b6c32716 Mon Sep 17 00:00:00 2001 From: chenheng Date: Thu, 28 Apr 2016 14:12:33 +0800 Subject: [PATCH] HBASE-15702 Improve PerClientRandomNonceGenerator --- .../hbase/client/ConnectionImplementation.java | 27 +++++++++------------- .../client/PerClientRandomNonceGenerator.java | 11 +++++---- 2 files changed, 18 insertions(+), 20 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..d53fa29 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 @@ -119,13 +119,7 @@ class ConnectionImplementation implements ClusterConnection, Closeable { private final int numTries; final int rpcTimeout; - /** - * Global nonceGenerator shared per client.Currently there's no reason to limit its scope. - * 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 volatile NonceGenerator nonceGenerator = null; private final AsyncProcess asyncProcess; // single tracker per connection @@ -203,13 +197,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.INSTANCE; } else { - nonceGenerator = new NoNonceGenerator(); + nonceGenerator = NoNonceGenerator.INSTANCE; } this.stats = ServerStatisticTracker.create(conf); @@ -275,11 +265,10 @@ class ConnectionImplementation implements ClusterConnection, Closeable { NonceGenerator ng = connImpl.getNonceGenerator(); LOG.warn("Nonce generator is being replaced by test code for " + cnm.getClass().getName()); - nonceGenerator = cnm; + connImpl.setNonceGenerator(cnm); return ng; } - @Override public HTableInterface getTable(String tableName) throws IOException { return getTable(TableName.valueOf(tableName)); @@ -1021,7 +1010,9 @@ class ConnectionImplementation implements ClusterConnection, Closeable { } /** Dummy nonce generator for disabled nonces. */ - static class NoNonceGenerator implements NonceGenerator { + final static class NoNonceGenerator implements NonceGenerator { + static NoNonceGenerator INSTANCE = new NoNonceGenerator(); + @Override public long getNonceGroup() { return HConstants.NO_NONCE; @@ -2223,6 +2214,10 @@ class ConnectionImplementation implements ClusterConnection, Closeable { return nonceGenerator; } + public void setNonceGenerator(NonceGenerator nonceGenerator) { + this.nonceGenerator = nonceGenerator; + } + /** * Connects to the master to get the table descriptor. * @param tableName table name 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..c3cc8f4 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,8 @@ */ package org.apache.hadoop.hbase.client; +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 +30,15 @@ import org.apache.hadoop.hbase.classification.InterfaceAudience; */ @InterfaceAudience.Private public class PerClientRandomNonceGenerator implements NonceGenerator { - private final Random rdm = new Random(); private final long clientId; + static final PerClientRandomNonceGenerator INSTANCE = + new PerClientRandomNonceGenerator(); + public 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 +48,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; } -- 1.9.3 (Apple Git-50)