HBASE-14544 Allow HConnectionImpl to not refresh the dns on errors

This commit is contained in:
Elliott Clark 2015-10-05 09:44:30 -07:00
parent 86b505c224
commit ef8cc7a575
1 changed files with 17 additions and 7 deletions

View File

@ -210,6 +210,7 @@ class ConnectionManager {
public static final String RETRIES_BY_SERVER_KEY = "hbase.client.retries.by.server"; public static final String RETRIES_BY_SERVER_KEY = "hbase.client.retries.by.server";
private static final String CLIENT_NONCES_ENABLED_KEY = "hbase.client.nonces.enabled"; private static final String CLIENT_NONCES_ENABLED_KEY = "hbase.client.nonces.enabled";
private static final String RESOLVE_HOSTNAME_ON_FAIL_KEY = "hbase.resolve.hostnames.on.failure";
// An LRU Map of HConnectionKey -> HConnection (TableServer). All // An LRU Map of HConnectionKey -> HConnection (TableServer). All
// access must be synchronized. This map is not private because tests // access must be synchronized. This map is not private because tests
@ -554,6 +555,7 @@ class ConnectionManager {
justification="Access to the conncurrent hash map is under a lock so should be fine.") justification="Access to the conncurrent hash map is under a lock so should be fine.")
static class HConnectionImplementation implements ClusterConnection, Closeable { static class HConnectionImplementation implements ClusterConnection, Closeable {
static final Log LOG = LogFactory.getLog(HConnectionImplementation.class); static final Log LOG = LogFactory.getLog(HConnectionImplementation.class);
private final boolean hostnamesCanChange;
private final long pause; private final long pause;
private final boolean useMetaReplicas; private final boolean useMetaReplicas;
private final int numTries; private final int numTries;
@ -669,6 +671,7 @@ class ConnectionManager {
this.backoffPolicy = ClientBackoffPolicyFactory.create(conf); this.backoffPolicy = ClientBackoffPolicyFactory.create(conf);
this.asyncProcess = createAsyncProcess(this.conf); this.asyncProcess = createAsyncProcess(this.conf);
this.hostnamesCanChange = conf.getBoolean(RESOLVE_HOSTNAME_ON_FAIL_KEY, true);
boolean shouldListen = conf.getBoolean(HConstants.STATUS_PUBLISHED, boolean shouldListen = conf.getBoolean(HConstants.STATUS_PUBLISHED,
HConstants.STATUS_PUBLISHED_DEFAULT); HConstants.STATUS_PUBLISHED_DEFAULT);
Class<? extends ClusterStatusListener.Listener> listenerClass = Class<? extends ClusterStatusListener.Listener> listenerClass =
@ -1504,7 +1507,8 @@ class ConnectionManager {
throw new MasterNotRunningException(sn + " is dead."); throw new MasterNotRunningException(sn + " is dead.");
} }
// Use the security info interface name as our stub key // Use the security info interface name as our stub key
String key = getStubKey(getServiceName(), sn.getHostname(), sn.getPort()); String key = getStubKey(getServiceName(),
sn.getHostname(), sn.getPort(), hostnamesCanChange);
connectionLock.putIfAbsent(key, key); connectionLock.putIfAbsent(key, key);
Object stub = null; Object stub = null;
synchronized (connectionLock.get(key)) { synchronized (connectionLock.get(key)) {
@ -1593,7 +1597,7 @@ class ConnectionManager {
throw new RegionServerStoppedException(serverName + " is dead."); throw new RegionServerStoppedException(serverName + " is dead.");
} }
String key = getStubKey(AdminService.BlockingInterface.class.getName(), String key = getStubKey(AdminService.BlockingInterface.class.getName(),
serverName.getHostname(), serverName.getPort()); serverName.getHostname(), serverName.getPort(), this.hostnamesCanChange);
this.connectionLock.putIfAbsent(key, key); this.connectionLock.putIfAbsent(key, key);
AdminService.BlockingInterface stub = null; AdminService.BlockingInterface stub = null;
synchronized (this.connectionLock.get(key)) { synchronized (this.connectionLock.get(key)) {
@ -1615,7 +1619,7 @@ class ConnectionManager {
throw new RegionServerStoppedException(sn + " is dead."); throw new RegionServerStoppedException(sn + " is dead.");
} }
String key = getStubKey(ClientService.BlockingInterface.class.getName(), sn.getHostname(), String key = getStubKey(ClientService.BlockingInterface.class.getName(), sn.getHostname(),
sn.getPort()); sn.getPort(), this.hostnamesCanChange);
this.connectionLock.putIfAbsent(key, key); this.connectionLock.putIfAbsent(key, key);
ClientService.BlockingInterface stub = null; ClientService.BlockingInterface stub = null;
synchronized (this.connectionLock.get(key)) { synchronized (this.connectionLock.get(key)) {
@ -1632,17 +1636,23 @@ class ConnectionManager {
return stub; return stub;
} }
static String getStubKey(final String serviceName, final String rsHostname, int port) { static String getStubKey(final String serviceName,
final String rsHostname,
int port,
boolean resolveHostnames) {
// Sometimes, servers go down and they come back up with the same hostname but a different // Sometimes, servers go down and they come back up with the same hostname but a different
// IP address. Force a resolution of the rsHostname by trying to instantiate an // IP address. Force a resolution of the rsHostname by trying to instantiate an
// InetSocketAddress, and this way we will rightfully get a new stubKey. // InetSocketAddress, and this way we will rightfully get a new stubKey.
// Also, include the hostname in the key so as to take care of those cases where the // Also, include the hostname in the key so as to take care of those cases where the
// DNS name is different but IP address remains the same. // DNS name is different but IP address remains the same.
InetAddress i = new InetSocketAddress(rsHostname, port).getAddress();
String address = rsHostname; String address = rsHostname;
if (resolveHostnames) {
InetAddress i = new InetSocketAddress(rsHostname, port).getAddress();
if (i != null) { if (i != null) {
address = i.getHostAddress() + "-" + rsHostname; address = i.getHostAddress() + "-" + rsHostname;
} }
}
return serviceName + "@" + address + ":" + port; return serviceName + "@" + address + ":" + port;
} }