HADOOP-11361. Fix a race condition in MetricsSourceAdapter.updateJmxCache. Contributed by Vinayakumar B, Yongjun Zhang, and Brahma Reddy Battula. (ozawa)
This commit is contained in:
parent
438b7c5935
commit
77ffe76212
|
@ -31,6 +31,7 @@ import javax.management.ReflectionException;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.*;
|
import static com.google.common.base.Preconditions.*;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
@ -59,7 +60,6 @@ class MetricsSourceAdapter implements DynamicMBean {
|
||||||
private final MBeanInfoBuilder infoBuilder;
|
private final MBeanInfoBuilder infoBuilder;
|
||||||
private final Iterable<MetricsTag> injectedTags;
|
private final Iterable<MetricsTag> injectedTags;
|
||||||
|
|
||||||
private Iterable<MetricsRecordImpl> lastRecs;
|
|
||||||
private boolean lastRecsCleared;
|
private boolean lastRecsCleared;
|
||||||
private long jmxCacheTS = 0;
|
private long jmxCacheTS = 0;
|
||||||
private long jmxCacheTTL;
|
private long jmxCacheTTL;
|
||||||
|
@ -175,18 +175,19 @@ class MetricsSourceAdapter implements DynamicMBean {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HADOOP-11361: Release lock here for avoid deadlock between
|
||||||
|
// MetricsSystemImpl's lock and MetricsSourceAdapter's lock.
|
||||||
|
Iterable<MetricsRecordImpl> lastRecs = null;
|
||||||
if (getAllMetrics) {
|
if (getAllMetrics) {
|
||||||
MetricsCollectorImpl builder = new MetricsCollectorImpl();
|
lastRecs = getMetrics(new MetricsCollectorImpl(), true);
|
||||||
getMetrics(builder, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized(this) {
|
synchronized (this) {
|
||||||
updateAttrCache();
|
if (lastRecs != null) {
|
||||||
if (getAllMetrics) {
|
updateAttrCache(lastRecs);
|
||||||
updateInfoCache();
|
updateInfoCache(lastRecs);
|
||||||
}
|
}
|
||||||
jmxCacheTS = Time.now();
|
jmxCacheTS = Time.now();
|
||||||
lastRecs = null; // in case regular interval update is not running
|
|
||||||
lastRecsCleared = true;
|
lastRecsCleared = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,11 +195,6 @@ class MetricsSourceAdapter implements DynamicMBean {
|
||||||
Iterable<MetricsRecordImpl> getMetrics(MetricsCollectorImpl builder,
|
Iterable<MetricsRecordImpl> getMetrics(MetricsCollectorImpl builder,
|
||||||
boolean all) {
|
boolean all) {
|
||||||
builder.setRecordFilter(recordFilter).setMetricFilter(metricFilter);
|
builder.setRecordFilter(recordFilter).setMetricFilter(metricFilter);
|
||||||
synchronized(this) {
|
|
||||||
if (lastRecs == null && jmxCacheTS == 0) {
|
|
||||||
all = true; // Get all the metrics to populate the sink caches
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
source.getMetrics(builder, all);
|
source.getMetrics(builder, all);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -209,10 +205,7 @@ class MetricsSourceAdapter implements DynamicMBean {
|
||||||
rb.add(t);
|
rb.add(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
synchronized(this) {
|
return builder.getRecords();
|
||||||
lastRecs = builder.getRecords();
|
|
||||||
return lastRecs;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void stop() {
|
synchronized void stop() {
|
||||||
|
@ -246,13 +239,15 @@ class MetricsSourceAdapter implements DynamicMBean {
|
||||||
return jmxCacheTTL;
|
return jmxCacheTTL;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateInfoCache() {
|
private void updateInfoCache(Iterable<MetricsRecordImpl> lastRecs) {
|
||||||
|
Preconditions.checkNotNull(lastRecs, "LastRecs should not be null");
|
||||||
LOG.debug("Updating info cache...");
|
LOG.debug("Updating info cache...");
|
||||||
infoCache = infoBuilder.reset(lastRecs).get();
|
infoCache = infoBuilder.reset(lastRecs).get();
|
||||||
LOG.debug("Done");
|
LOG.debug("Done");
|
||||||
}
|
}
|
||||||
|
|
||||||
private int updateAttrCache() {
|
private int updateAttrCache(Iterable<MetricsRecordImpl> lastRecs) {
|
||||||
|
Preconditions.checkNotNull(lastRecs, "LastRecs should not be null");
|
||||||
LOG.debug("Updating attr cache...");
|
LOG.debug("Updating attr cache...");
|
||||||
int recNo = 0;
|
int recNo = 0;
|
||||||
int numMetrics = 0;
|
int numMetrics = 0;
|
||||||
|
|
Loading…
Reference in New Issue