You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by st...@apache.org on 2011/11/24 00:31:13 UTC
svn commit: r1205660 - in /hbase/branches/0.92: CHANGES.txt
src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
src/main/java/org/apache/hadoop/hbase/util/SoftValueSortedMap.java
Author: stack
Date: Wed Nov 23 23:31:12 2011
New Revision: 1205660
URL: http://svn.apache.org/viewvc?rev=1205660&view=rev
Log:
HBASE-4785 Improve recovery time of HBase client when a region server dies
Modified:
hbase/branches/0.92/CHANGES.txt
hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/util/SoftValueSortedMap.java
Modified: hbase/branches/0.92/CHANGES.txt
URL: http://svn.apache.org/viewvc/hbase/branches/0.92/CHANGES.txt?rev=1205660&r1=1205659&r2=1205660&view=diff
==============================================================================
--- hbase/branches/0.92/CHANGES.txt (original)
+++ hbase/branches/0.92/CHANGES.txt Wed Nov 23 23:31:12 2011
@@ -442,6 +442,7 @@ Release 0.92.0 - Unreleased
HBASE-4308 Race between RegionOpenedHandler and AssignmentManager (Ram)
HBASE-4857 Recursive loop on KeeperException in
AuthenticationTokenSecretManager/ZKLeaderManager
+ HBASE-4785 Improve recovery time of HBase client when a region server dies
TESTS
HBASE-4492 TestRollingRestart fails intermittently
Modified: hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java?rev=1205660&r1=1205659&r2=1205660&view=diff
==============================================================================
--- hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java (original)
+++ hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java Wed Nov 23 23:31:12 2011
@@ -23,7 +23,9 @@ import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
+import java.net.ConnectException;
import java.net.InetSocketAddress;
+import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -31,8 +33,8 @@ import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.NoSuchElementException;
import java.util.Map.Entry;
+import java.util.NoSuchElementException;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.Callable;
@@ -512,6 +514,13 @@ public class HConnectionManager {
cachedRegionLocations =
new HashMap<Integer, SoftValueSortedMap<byte [], HRegionLocation>>();
+ // The presence of a server in the map implies it's likely that there is an
+ // entry in cachedRegionLocations that map to this server; but the absence
+ // of a server in this map guarentees that there is no entry in cache that
+ // maps to the absent server.
+ private final Set<String> cachedServers =
+ new HashSet<String>();
+
// region cache prefetch is enabled by default. this set contains all
// tables whose region cache prefetch are disabled.
private final Set<Integer> regionCachePrefetchDisabledTables =
@@ -1116,6 +1125,35 @@ public class HConnectionManager {
}
/*
+ * Delete all cached entries of a table that maps to a specific location.
+ *
+ * @param tablename
+ * @param server
+ */
+ private void clearCachedLocationForServer(
+ final String server) {
+ boolean deletedSomething = false;
+ synchronized (this.cachedRegionLocations) {
+ if (!cachedServers.contains(server)) {
+ return;
+ }
+ for (SoftValueSortedMap<byte[], HRegionLocation> tableLocations :
+ cachedRegionLocations.values()) {
+ for (Entry<byte[], HRegionLocation> e : tableLocations.entrySet()) {
+ if (e.getValue().getServerAddress().toString().equals(server)) {
+ tableLocations.remove(e.getKey());
+ deletedSomething = true;
+ }
+ }
+ }
+ cachedServers.remove(server);
+ }
+ if (deletedSomething && LOG.isDebugEnabled()) {
+ LOG.debug("Removed all cached region locations that map to " + server);
+ }
+ }
+
+ /*
* @param tableName
* @return Map of cached locations for passed <code>tableName</code>
*/
@@ -1140,6 +1178,7 @@ public class HConnectionManager {
public void clearRegionCache() {
synchronized(this.cachedRegionLocations) {
this.cachedRegionLocations.clear();
+ this.cachedServers.clear();
}
}
@@ -1158,7 +1197,12 @@ public class HConnectionManager {
byte [] startKey = location.getRegionInfo().getStartKey();
SoftValueSortedMap<byte [], HRegionLocation> tableLocations =
getTableLocations(tableName);
- if (tableLocations.put(startKey, location) == null) {
+ boolean hasNewCache = false;
+ synchronized (this.cachedRegionLocations) {
+ cachedServers.add(location.getServerAddress().toString());
+ hasNewCache = (tableLocations.put(startKey, location) == null);
+ }
+ if (hasNewCache) {
LOG.debug("Cached location for " +
location.getRegionInfo().getRegionNameAsString() +
" is " + location.getHostnamePort());
@@ -1281,6 +1325,17 @@ public class HConnectionManager {
} catch (Throwable t) {
callable.shouldRetry(t);
t = translateException(t);
+ if (t instanceof SocketTimeoutException ||
+ t instanceof ConnectException ||
+ t instanceof RetriesExhaustedException) {
+ // if thrown these exceptions, we clear all the cache entries that
+ // map to that slow/dead server; otherwise, let cache miss and ask
+ // .META. again to find the new location
+ HRegionLocation hrl = callable.location;
+ if (hrl != null) {
+ clearCachedLocationForServer(hrl.getServerAddress().toString());
+ }
+ }
RetriesExhaustedException.ThrowableWithExtraContext qt =
new RetriesExhaustedException.ThrowableWithExtraContext(t,
System.currentTimeMillis(), callable.toString());
Modified: hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/util/SoftValueSortedMap.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/util/SoftValueSortedMap.java?rev=1205660&r1=1205659&r2=1205660&view=diff
==============================================================================
--- hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/util/SoftValueSortedMap.java (original)
+++ hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/util/SoftValueSortedMap.java Wed Nov 23 23:31:12 2011
@@ -24,6 +24,7 @@ import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
+import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
@@ -172,7 +173,13 @@ public class SoftValueSortedMap<K,V> imp
}
public synchronized Set<Map.Entry<K,V>> entrySet() {
- throw new RuntimeException("Not implemented");
+ checkReferences();
+ Set<Map.Entry<K, SoftValue<K, V>>> entries = this.internalMap.entrySet();
+ Set<Map.Entry<K, V>> realEntries = new LinkedHashSet<Map.Entry<K, V>>();
+ for (Map.Entry<K, SoftValue<K, V>> entry : entries) {
+ realEntries.add(entry.getValue());
+ }
+ return realEntries;
}
public synchronized Collection<V> values() {
@@ -185,12 +192,24 @@ public class SoftValueSortedMap<K,V> imp
return hardValues;
}
- private static class SoftValue<K,V> extends SoftReference<V> {
+ private static class SoftValue<K,V> extends SoftReference<V> implements Map.Entry<K, V> {
final K key;
SoftValue(K key, V value, ReferenceQueue q) {
super(value, q);
this.key = key;
}
+
+ public K getKey() {
+ return this.key;
+ }
+
+ public V getValue() {
+ return get();
+ }
+
+ public V setValue(V value) {
+ throw new RuntimeException("Not implemented");
+ }
}
}