HBASE-7871 HBase can be stuck when closing regions concurrently (Ted Yu)

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1464012 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Zhihong Yu 2013-04-03 13:51:01 +00:00
parent ac97504dc5
commit b16e84e632
2 changed files with 44 additions and 10 deletions

View File

@ -25,10 +25,13 @@ import org.apache.hadoop.metrics2.MetricsBuilder;
import org.apache.hadoop.metrics2.MetricsRecordBuilder; import org.apache.hadoop.metrics2.MetricsRecordBuilder;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class MetricsRegionAggregateSourceImpl extends BaseSourceImpl public class MetricsRegionAggregateSourceImpl extends BaseSourceImpl
implements MetricsRegionAggregateSource { implements MetricsRegionAggregateSource {
private final Log LOG = LogFactory.getLog(this.getClass()); private final Log LOG = LogFactory.getLog(this.getClass());
// lock to guard against concurrent access to regionSources
final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final TreeSet<MetricsRegionSourceImpl> regionSources = private final TreeSet<MetricsRegionSourceImpl> regionSources =
new TreeSet<MetricsRegionSourceImpl>(); new TreeSet<MetricsRegionSourceImpl>();
@ -47,12 +50,22 @@ public class MetricsRegionAggregateSourceImpl extends BaseSourceImpl
@Override @Override
public void register(MetricsRegionSource source) { public void register(MetricsRegionSource source) {
lock.writeLock().lock();
try {
regionSources.add((MetricsRegionSourceImpl) source); regionSources.add((MetricsRegionSourceImpl) source);
} finally {
lock.writeLock().unlock();
}
} }
@Override @Override
public void deregister(MetricsRegionSource source) { public void deregister(MetricsRegionSource source) {
lock.writeLock().lock();
try {
regionSources.remove(source); regionSources.remove(source);
} finally {
lock.writeLock().unlock();
}
} }
/** /**
@ -66,16 +79,19 @@ public class MetricsRegionAggregateSourceImpl extends BaseSourceImpl
@Override @Override
public void getMetrics(MetricsBuilder metricsBuilder, boolean all) { public void getMetrics(MetricsBuilder metricsBuilder, boolean all) {
MetricsRecordBuilder mrb = metricsBuilder.addRecord(metricsName) MetricsRecordBuilder mrb = metricsBuilder.addRecord(metricsName)
.setContext(metricsContext); .setContext(metricsContext);
if (regionSources != null) { if (regionSources != null) {
lock.readLock().lock();
try {
for (MetricsRegionSourceImpl regionMetricSource : regionSources) { for (MetricsRegionSourceImpl regionMetricSource : regionSources) {
regionMetricSource.snapshot(mrb, all); regionMetricSource.snapshot(mrb, all);
} }
} finally {
lock.readLock().unlock();
}
} }
metricsRegistry.snapshot(mrb, all); metricsRegistry.snapshot(mrb, all);
} }

View File

@ -25,11 +25,14 @@ import org.apache.hadoop.metrics2.MetricsCollector;
import org.apache.hadoop.metrics2.MetricsRecordBuilder; import org.apache.hadoop.metrics2.MetricsRecordBuilder;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class MetricsRegionAggregateSourceImpl extends BaseSourceImpl public class MetricsRegionAggregateSourceImpl extends BaseSourceImpl
implements MetricsRegionAggregateSource { implements MetricsRegionAggregateSource {
private final Log LOG = LogFactory.getLog(this.getClass()); private final Log LOG = LogFactory.getLog(this.getClass());
// lock to guard against concurrent access to regionSources
final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final TreeSet<MetricsRegionSourceImpl> regionSources = private final TreeSet<MetricsRegionSourceImpl> regionSources =
new TreeSet<MetricsRegionSourceImpl>(); new TreeSet<MetricsRegionSourceImpl>();
@ -48,12 +51,22 @@ public class MetricsRegionAggregateSourceImpl extends BaseSourceImpl
@Override @Override
public void register(MetricsRegionSource source) { public void register(MetricsRegionSource source) {
lock.writeLock().lock();
try {
regionSources.add((MetricsRegionSourceImpl) source); regionSources.add((MetricsRegionSourceImpl) source);
} finally {
lock.writeLock().unlock();
}
} }
@Override @Override
public void deregister(MetricsRegionSource source) { public void deregister(MetricsRegionSource source) {
lock.writeLock().lock();
try {
regionSources.remove(source); regionSources.remove(source);
} finally {
lock.writeLock().unlock();
}
} }
/** /**
@ -72,9 +85,14 @@ public class MetricsRegionAggregateSourceImpl extends BaseSourceImpl
.setContext(metricsContext); .setContext(metricsContext);
if (regionSources != null) { if (regionSources != null) {
lock.readLock().lock();
try {
for (MetricsRegionSourceImpl regionMetricSource : regionSources) { for (MetricsRegionSourceImpl regionMetricSource : regionSources) {
regionMetricSource.snapshot(mrb, all); regionMetricSource.snapshot(mrb, all);
} }
} finally {
lock.readLock().unlock();
}
} }
metricsRegistry.snapshot(mrb, all); metricsRegistry.snapshot(mrb, all);