Browse Source

HADOOP-11301. [optionally] update jmx cache to drop old metrics (Maysam Yabandeh via stack)

(cherry picked from commit b36f29298247f6c5db9f6eff7c2f5177a0fe3de5)
(cherry picked from commit 6d904985e8fbc5abbe9fe9f58badf5e0e1f55825)
stack 10 năm trước cách đây
mục cha
commit
fe1c738077

+ 3 - 0
hadoop-common-project/hadoop-common/CHANGES.txt

@@ -20,6 +20,9 @@ Release 2.6.5 - UNRELEASED
     HADOOP-13298. Fix the leftover L&N files in
     hadoop-build-tools/src/main/resources/META-INF/. (ozawa)
 
+    HADOOP-11301. [optionally] update jmx cache to drop old metrics
+    (Maysam Yabandeh via stack)
+
   OPTIMIZATIONS
 
     HADOOP-12810. FileSystem#listLocatedStatus causes unnecessary RPC calls

+ 2 - 3
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/impl/MetricsSourceAdapter.java

@@ -173,9 +173,8 @@ class MetricsSourceAdapter implements DynamicMBean {
     }
 
     synchronized(this) {
-      int oldCacheSize = attrCache.size();
-      int newCacheSize = updateAttrCache();
-      if (oldCacheSize < newCacheSize) {
+      updateAttrCache();
+      if (getAllMetrics) {
         updateInfoCache();
       }
       jmxCacheTS = Time.now();

+ 51 - 0
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/metrics2/impl/TestMetricsSourceAdapter.java

@@ -23,6 +23,8 @@ import static org.junit.Assert.*;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.hadoop.metrics2.MetricsCollector;
+import org.apache.hadoop.metrics2.MetricsRecordBuilder;
 import org.apache.hadoop.metrics2.MetricsSource;
 import org.apache.hadoop.metrics2.MetricsTag;
 import org.apache.hadoop.metrics2.annotation.Metric;
@@ -31,10 +33,59 @@ import org.apache.hadoop.metrics2.lib.MetricsAnnotations;
 import org.apache.hadoop.metrics2.lib.MetricsRegistry;
 import org.apache.hadoop.metrics2.lib.MetricsSourceBuilder;
 import org.apache.hadoop.metrics2.lib.MutableCounterLong;
+import static org.apache.hadoop.metrics2.lib.Interns.info;
+import static org.junit.Assert.assertEquals;
+
 import org.junit.Test;
 
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+
 public class TestMetricsSourceAdapter {
 
+
+  @Test
+  public void testPurgeOldMetrics() throws Exception {
+    // create test source with a single metric counter of value 1
+    PurgableSource source = new PurgableSource();
+    MetricsSourceBuilder sb = MetricsAnnotations.newSourceBuilder(source);
+    final MetricsSource s = sb.build();
+
+    List<MetricsTag> injectedTags = new ArrayList<MetricsTag>();
+    MetricsSourceAdapter sa = new MetricsSourceAdapter(
+        "tst", "tst", "testdesc", s, injectedTags, null, null, 1, false);
+
+    MBeanInfo info = sa.getMBeanInfo();
+    boolean sawIt = false;
+    for (MBeanAttributeInfo mBeanAttributeInfo : info.getAttributes()) {
+      sawIt |= mBeanAttributeInfo.getName().equals(source.lastKeyName);
+    };
+    assertTrue("The last generated metric is not exported to jmx", sawIt);
+
+    Thread.sleep(1000); // skip JMX cache TTL
+
+    info = sa.getMBeanInfo();
+    sawIt = false;
+    for (MBeanAttributeInfo mBeanAttributeInfo : info.getAttributes()) {
+      sawIt |= mBeanAttributeInfo.getName().equals(source.lastKeyName);
+    };
+    assertTrue("The last generated metric is not exported to jmx", sawIt);
+  }
+
+  //generate a new key per each call
+  class PurgableSource implements MetricsSource {
+    int nextKey = 0;
+    String lastKeyName = null;
+    @Override
+    public void getMetrics(MetricsCollector collector, boolean all) {
+      MetricsRecordBuilder rb =
+          collector.addRecord("purgablesource")
+              .setContext("test");
+      lastKeyName = "key" + nextKey++;
+      rb.addGauge(info(lastKeyName, "desc"), 1);
+    }
+  }
+
   @Test
   public void testGetMetricsAndJmx() throws Exception {
     // create test source with a single metric counter of value 0