From d0b61e75ae232507ee5fbcc351da1769159a9974 Mon Sep 17 00:00:00 2001 From: Michael Stack Date: Tue, 8 Dec 2009 00:24:21 +0000 Subject: [PATCH] HBASE-2027 HConnectionManager.HBASE_INSTANCES leaks TableServers git-svn-id: https://svn.apache.org/repos/asf/hadoop/hbase/trunk@888202 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 2 ++ .../hadoop/hbase/HBaseConfiguration.java | 29 ++++++++++++++++++- .../hbase/client/HConnectionManager.java | 18 ++++++++---- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index ca7a7fc66f2..2e99a829a1b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -219,6 +219,8 @@ Release 0.21.0 - Unreleased HBASE-2019 [EC2] remember credentials if not configured HBASE-2029 Reduce shell exception dump on console (Lars George and J-D via Stack) + HBASE-2027 HConnectionManager.HBASE_INSTANCES leaks TableServers + (Dave Latham via Stack) NEW FEATURES HBASE-1901 "General" partitioner for "hbase-48" bulk (behind the api, write diff --git a/src/java/org/apache/hadoop/hbase/HBaseConfiguration.java b/src/java/org/apache/hadoop/hbase/HBaseConfiguration.java index 4b54c36671c..03e65aa83d2 100644 --- a/src/java/org/apache/hadoop/hbase/HBaseConfiguration.java +++ b/src/java/org/apache/hadoop/hbase/HBaseConfiguration.java @@ -52,7 +52,7 @@ public class HBaseConfiguration extends Configuration { /** * Returns the hash code value for this HBaseConfiguration. The hash code of a - * HBaseConfiguration is defined by the sum of the hash codes of its entries. + * HBaseConfiguration is defined by the xor of the hash codes of its entries. * * @see Configuration#iterator() How the entries are obtained. */ @@ -66,5 +66,32 @@ public class HBaseConfiguration extends Configuration { } return hash; } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof HBaseConfiguration)) + return false; + + HBaseConfiguration otherConf = (HBaseConfiguration) obj; + if (size() != otherConf.size()) { + return false; + } + Iterator> propertyIterator = this.iterator(); + while (propertyIterator.hasNext()) { + Entry entry = propertyIterator.next(); + String key = entry.getKey(); + String value = entry.getValue(); + if (!value.equals(otherConf.getRaw(key))) { + return false; + } + } + + return true; + } + } diff --git a/src/java/org/apache/hadoop/hbase/client/HConnectionManager.java b/src/java/org/apache/hadoop/hbase/client/HConnectionManager.java index 33aa73378ff..12124fc441d 100644 --- a/src/java/org/apache/hadoop/hbase/client/HConnectionManager.java +++ b/src/java/org/apache/hadoop/hbase/client/HConnectionManager.java @@ -24,10 +24,10 @@ import java.lang.reflect.UndeclaredThrowableException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.TreeSet; -import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.logging.Log; @@ -85,12 +85,20 @@ public class HConnectionManager implements HConstants { super(); } - // A Map of master HBaseConfiguration -> connection information for that - // instance. Note that although the Map is synchronized, the objects it - // contains are mutable and hence require synchronized access to them + private static final int MAX_CACHED_HBASE_INSTANCES=31; + // A LRU Map of master HBaseConfiguration -> connection information for that + // instance. The objects it contains are mutable and hence require + // synchronized access to them. We set instances to 31. The zk default max + // connections is 30 so should run into zk issues before hit this value of 31. private static final Map HBASE_INSTANCES = - new WeakHashMap(); + new LinkedHashMap + ((int) (MAX_CACHED_HBASE_INSTANCES/0.75F)+1, 0.75F, true) { + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > MAX_CACHED_HBASE_INSTANCES; + } + }; private static final Map ZK_WRAPPERS = new HashMap();