HBASE-3654 Weird blocking between getOnlineRegion and createRegionLoad

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1085114 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael Stack 2011-03-24 20:25:10 +00:00
parent 1cab7fc7b9
commit b500e86e2d
2 changed files with 68 additions and 121 deletions

View File

@ -171,6 +171,8 @@ Release 0.90.2 - Unreleased
HBASE-3627 NPE in EventHandler when region already reassigned HBASE-3627 NPE in EventHandler when region already reassigned
HBASE-3660 HMaster will exit when starting with stale data in cached locations HBASE-3660 HMaster will exit when starting with stale data in cached locations
such as -ROOT- or .META. such as -ROOT- or .META.
HBASE-3654 Weird blocking between getOnlineRegion and createRegionLoad
(Subbu M Iyer via Stack)
IMPROVEMENTS IMPROVEMENTS
HBASE-3542 MultiGet methods in Thrift HBASE-3542 MultiGet methods in Thrift

View File

@ -182,7 +182,7 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
* encoded region name. All access should be synchronized. * encoded region name. All access should be synchronized.
*/ */
protected final Map<String, HRegion> onlineRegions = protected final Map<String, HRegion> onlineRegions =
new HashMap<String, HRegion>(); new ConcurrentHashMap<String, HRegion>();
protected final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); protected final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final LinkedBlockingQueue<HMsg> outboundMsgs = new LinkedBlockingQueue<HMsg>(); private final LinkedBlockingQueue<HMsg> outboundMsgs = new LinkedBlockingQueue<HMsg>();
@ -688,11 +688,9 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
String getOnlineRegionsAsPrintableString() { String getOnlineRegionsAsPrintableString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
synchronized (this.onlineRegions) { for (HRegion r: this.onlineRegions.values()) {
for (HRegion r: this.onlineRegions.values()) { if (sb.length() > 0) sb.append(", ");
if (sb.length() > 0) sb.append(", "); sb.append(r.getRegionInfo().getEncodedName());
sb.append(r.getRegionInfo().getEncodedName());
}
} }
return sb.toString(); return sb.toString();
} }
@ -712,9 +710,7 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
// Only print out regions still closing if a small number else will // Only print out regions still closing if a small number else will
// swamp the log. // swamp the log.
if (count < 10 && LOG.isDebugEnabled()) { if (count < 10 && LOG.isDebugEnabled()) {
synchronized (this.onlineRegions) { LOG.debug(this.onlineRegions);
LOG.debug(this.onlineRegions);
}
} }
} }
Threads.sleep(1000); Threads.sleep(1000);
@ -756,10 +752,8 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
HServerLoad hsl = new HServerLoad(requestCount.get(), HServerLoad hsl = new HServerLoad(requestCount.get(),
(int)(memory.getUsed() / 1024 / 1024), (int)(memory.getUsed() / 1024 / 1024),
(int) (memory.getMax() / 1024 / 1024)); (int) (memory.getMax() / 1024 / 1024));
synchronized (this.onlineRegions) { for (HRegion r : this.onlineRegions.values()) {
for (HRegion r : this.onlineRegions.values()) { hsl.addRegionInfo(createRegionLoad(r));
hsl.addRegionInfo(createRegionLoad(r));
}
} }
return hsl; return hsl;
} }
@ -923,9 +917,7 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
*/ */
public HServerLoad.RegionLoad createRegionLoad(final String encodedRegionName) { public HServerLoad.RegionLoad createRegionLoad(final String encodedRegionName) {
HRegion r = null; HRegion r = null;
synchronized (this.onlineRegions) { r = this.onlineRegions.get(encodedRegionName);
r = this.onlineRegions.get(encodedRegionName);
}
return createRegionLoad(r); return createRegionLoad(r);
} }
@ -1042,17 +1034,15 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
@Override @Override
protected void chore() { protected void chore() {
synchronized (this.instance.onlineRegions) { for (HRegion r : this.instance.onlineRegions.values()) {
for (HRegion r : this.instance.onlineRegions.values()) { try {
try { if (r != null && r.isMajorCompaction()) {
if (r != null && r.isMajorCompaction()) { // Queue a compaction. Will recognize if major is needed.
// Queue a compaction. Will recognize if major is needed. this.instance.compactSplitThread.requestCompaction(r, getName()
this.instance.compactSplitThread.requestCompaction(r, getName() + " requests major compaction");
+ " requests major compaction");
}
} catch (IOException e) {
LOG.warn("Failed major compaction check on " + r, e);
} }
} catch (IOException e) {
LOG.warn("Failed major compaction check on " + r, e);
} }
} }
} }
@ -1154,8 +1144,7 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
long memstoreSize = 0; long memstoreSize = 0;
long requestsCount = 0; long requestsCount = 0;
long storefileIndexSize = 0; long storefileIndexSize = 0;
synchronized (this.onlineRegions) { for (Map.Entry<String, HRegion> e : this.onlineRegions.entrySet()) {
for (Map.Entry<String, HRegion> e : this.onlineRegions.entrySet()) {
HRegion r = e.getValue(); HRegion r = e.getValue();
memstoreSize += r.memstoreSize.get(); memstoreSize += r.memstoreSize.get();
requestsCount += r.requestsCount.get(); requestsCount += r.requestsCount.get();
@ -1168,7 +1157,6 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
} }
} }
} }
}
this.metrics.stores.set(stores); this.metrics.stores.set(stores);
this.metrics.storefiles.set(storefiles); this.metrics.storefiles.set(storefiles);
this.metrics.memstoreSizeMB.set((int) (memstoreSize / (1024 * 1024))); this.metrics.memstoreSizeMB.set((int) (memstoreSize / (1024 * 1024)));
@ -1547,16 +1535,14 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
HRegion root = null; HRegion root = null;
this.lock.writeLock().lock(); this.lock.writeLock().lock();
try { try {
synchronized (this.onlineRegions) { for (Map.Entry<String, HRegion> e: onlineRegions.entrySet()) {
for (Map.Entry<String, HRegion> e: onlineRegions.entrySet()) { HRegionInfo hri = e.getValue().getRegionInfo();
HRegionInfo hri = e.getValue().getRegionInfo(); if (hri.isRootRegion()) {
if (hri.isRootRegion()) { root = e.getValue();
root = e.getValue(); } else if (hri.isMetaRegion()) {
} else if (hri.isMetaRegion()) { meta = e.getValue();
meta = e.getValue();
}
if (meta != null && root != null) break;
} }
if (meta != null && root != null) break;
} }
} finally { } finally {
this.lock.writeLock().unlock(); this.lock.writeLock().unlock();
@ -1572,13 +1558,11 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
void closeUserRegions(final boolean abort) { void closeUserRegions(final boolean abort) {
this.lock.writeLock().lock(); this.lock.writeLock().lock();
try { try {
synchronized (this.onlineRegions) { for (Map.Entry<String, HRegion> e: this.onlineRegions.entrySet()) {
for (Map.Entry<String, HRegion> e: this.onlineRegions.entrySet()) { HRegion r = e.getValue();
HRegion r = e.getValue(); if (!r.getRegionInfo().isMetaRegion()) {
if (!r.getRegionInfo().isMetaRegion()) { // Don't update zk with this close transition; pass false.
// Don't update zk with this close transition; pass false. closeRegion(r.getRegionInfo(), abort, false);
closeRegion(r.getRegionInfo(), abort, false);
}
} }
} }
} finally { } finally {
@ -2267,14 +2251,12 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
public boolean closeRegion(HRegionInfo region, final boolean zk) public boolean closeRegion(HRegionInfo region, final boolean zk)
throws NotServingRegionException { throws NotServingRegionException {
LOG.info("Received close region: " + region.getRegionNameAsString()); LOG.info("Received close region: " + region.getRegionNameAsString());
synchronized (this.onlineRegions) { boolean hasit = this.onlineRegions.containsKey(region.getEncodedName());
boolean hasit = this.onlineRegions.containsKey(region.getEncodedName()); if (!hasit) {
if (!hasit) { LOG.warn("Received close for region we are not serving; " +
LOG.warn("Received close for region we are not serving; " + region.getEncodedName());
region.getEncodedName()); throw new NotServingRegionException("Received close for "
throw new NotServingRegionException("Received close for " + region.getRegionNameAsString() + " but we are not serving it");
+ region.getRegionNameAsString() + " but we are not serving it");
}
} }
return closeRegion(region, false, zk); return closeRegion(region, false, zk);
} }
@ -2376,10 +2358,8 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
@QosPriority(priority=HIGH_QOS) @QosPriority(priority=HIGH_QOS)
public List<HRegionInfo> getOnlineRegions() { public List<HRegionInfo> getOnlineRegions() {
List<HRegionInfo> list = new ArrayList<HRegionInfo>(); List<HRegionInfo> list = new ArrayList<HRegionInfo>();
synchronized(this.onlineRegions) { for (Map.Entry<String,HRegion> e: this.onlineRegions.entrySet()) {
for (Map.Entry<String,HRegion> e: this.onlineRegions.entrySet()) { list.add(e.getValue().getRegionInfo());
list.add(e.getValue().getRegionInfo());
}
} }
Collections.sort(list); Collections.sort(list);
return list; return list;
@ -2387,16 +2367,12 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
public int getNumberOfOnlineRegions() { public int getNumberOfOnlineRegions() {
int size = -1; int size = -1;
synchronized (this.onlineRegions) { size = this.onlineRegions.size();
size = this.onlineRegions.size();
}
return size; return size;
} }
boolean isOnlineRegionsEmpty() { boolean isOnlineRegionsEmpty() {
synchronized (this.onlineRegions) { return this.onlineRegions.isEmpty();
return this.onlineRegions.isEmpty();
}
} }
/** /**
@ -2406,35 +2382,19 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
* @see #getOnlineRegions() * @see #getOnlineRegions()
*/ */
public Collection<HRegion> getOnlineRegionsLocalContext() { public Collection<HRegion> getOnlineRegionsLocalContext() {
synchronized (this.onlineRegions) { Collection<HRegion> regions = this.onlineRegions.values();
Collection<HRegion> regions = this.onlineRegions.values(); return Collections.unmodifiableCollection(regions);
return Collections.unmodifiableCollection(regions);
}
} }
@Override @Override
public void addToOnlineRegions(HRegion region) { public void addToOnlineRegions(HRegion region) {
lock.writeLock().lock(); this.onlineRegions.put(region.getRegionInfo().getEncodedName(), region);
try {
synchronized (this.onlineRegions) {
this.onlineRegions.put(region.getRegionInfo().getEncodedName(), region);
}
} finally {
lock.writeLock().unlock();
}
} }
@Override @Override
public boolean removeFromOnlineRegions(final String encodedName) { public boolean removeFromOnlineRegions(final String encodedName) {
this.lock.writeLock().lock();
HRegion toReturn = null; HRegion toReturn = null;
try { toReturn = this.onlineRegions.remove(encodedName);
synchronized (this.onlineRegions) {
toReturn = this.onlineRegions.remove(encodedName);
}
} finally {
this.lock.writeLock().unlock();
}
return toReturn != null; return toReturn != null;
} }
@ -2451,10 +2411,8 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
} }
}); });
// Copy over all regions. Regions are sorted by size with biggest first. // Copy over all regions. Regions are sorted by size with biggest first.
synchronized (this.onlineRegions) { for (HRegion region : this.onlineRegions.values()) {
for (HRegion region : this.onlineRegions.values()) { sortedRegions.put(Long.valueOf(region.memstoreSize.get()), region);
sortedRegions.put(Long.valueOf(region.memstoreSize.get()), region);
}
} }
return sortedRegions; return sortedRegions;
} }
@ -2462,9 +2420,7 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
@Override @Override
public HRegion getFromOnlineRegions(final String encodedRegionName) { public HRegion getFromOnlineRegions(final String encodedRegionName) {
HRegion r = null; HRegion r = null;
synchronized (this.onlineRegions) { r = this.onlineRegions.get(encodedRegionName);
r = this.onlineRegions.get(encodedRegionName);
}
return r; return r;
} }
@ -2498,17 +2454,12 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
protected HRegion getRegion(final byte[] regionName) protected HRegion getRegion(final byte[] regionName)
throws NotServingRegionException { throws NotServingRegionException {
HRegion region = null; HRegion region = null;
this.lock.readLock().lock(); region = getOnlineRegion(regionName);
try { if (region == null) {
region = getOnlineRegion(regionName); throw new NotServingRegionException("Region is not online: " +
if (region == null) { Bytes.toStringBinary(regionName));
throw new NotServingRegionException("Region is not online: " +
Bytes.toStringBinary(regionName));
}
return region;
} finally {
this.lock.readLock().unlock();
} }
return region;
} }
/** /**
@ -2519,16 +2470,14 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
*/ */
protected HRegionInfo[] getMostLoadedRegions() { protected HRegionInfo[] getMostLoadedRegions() {
ArrayList<HRegionInfo> regions = new ArrayList<HRegionInfo>(); ArrayList<HRegionInfo> regions = new ArrayList<HRegionInfo>();
synchronized (onlineRegions) { for (HRegion r : onlineRegions.values()) {
for (HRegion r : onlineRegions.values()) { if (r.isClosed() || r.isClosing()) {
if (r.isClosed() || r.isClosing()) { continue;
continue; }
} if (regions.size() < numRegionsToReport) {
if (regions.size() < numRegionsToReport) { regions.add(r.getRegionInfo());
regions.add(r.getRegionInfo()); } else {
} else { break;
break;
}
} }
} }
return regions.toArray(new HRegionInfo[regions.size()]); return regions.toArray(new HRegionInfo[regions.size()]);
@ -2573,10 +2522,8 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
*/ */
public long getGlobalMemStoreSize() { public long getGlobalMemStoreSize() {
long total = 0; long total = 0;
synchronized (onlineRegions) { for (HRegion region : onlineRegions.values()) {
for (HRegion region : onlineRegions.values()) { total += region.memstoreSize.get();
total += region.memstoreSize.get();
}
} }
return total; return total;
} }
@ -2675,14 +2622,12 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
} }
public HRegionInfo[] getRegionsAssignment() throws IOException { public HRegionInfo[] getRegionsAssignment() throws IOException {
synchronized (this.onlineRegions) { HRegionInfo [] regions = new HRegionInfo[getNumberOfOnlineRegions()];
HRegionInfo [] regions = new HRegionInfo[getNumberOfOnlineRegions()]; Iterator<HRegion> ite = onlineRegions.values().iterator();
Iterator<HRegion> ite = onlineRegions.values().iterator(); for (int i = 0; ite.hasNext(); i++) {
for (int i = 0; ite.hasNext(); i++) { regions[i] = ite.next().getRegionInfo();
regions[i] = ite.next().getRegionInfo();
}
return regions;
} }
return regions;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */