You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ab...@apache.org on 2019/12/18 16:39:09 UTC

[lucene-solr] 31/36: Interim check-in, mostly fixed.

This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit f336d7c6343c091fccaa605a9f4e565aba58bade
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Wed Nov 20 12:29:44 2019 +0100

    Interim check-in, mostly fixed.
---
 .../java/org/apache/solr/core/CoreContainer.java   |  2 +-
 .../apache/solr/handler/RequestHandlerBase.java    | 20 ++++-----
 .../solr/handler/admin/ResourceManagerHandler.java |  7 ++-
 .../handler/component/HttpShardHandlerFactory.java |  2 +-
 .../solr/handler/component/SearchComponent.java    |  2 +-
 .../solr/handler/component/SuggestComponent.java   |  4 +-
 .../solr/highlight/HighlightingPluginBase.java     |  4 +-
 .../solr/managed/DefaultResourceManagerPool.java   |  4 +-
 .../org/apache/solr/managed/ManagedComponent.java  | 10 +++--
 .../apache/solr/managed/ManagedComponentId.java    | 25 ++++++++---
 .../org/apache/solr/managed/ManagedContext.java    | 33 ++++++++++----
 .../apache/solr/managed/NoOpResourceManager.java   |  9 +---
 .../java/org/apache/solr/managed/PoolContext.java  |  9 ++++
 .../apache/solr/managed/ResourceManagerPool.java   |  2 +-
 .../solr/managed/types/CacheManagerPlugin.java     |  2 +-
 .../apache/solr/metrics/SolrCoreMetricManager.java |  4 +-
 .../apache/solr/metrics/SolrMetricProducer.java    |  8 ++--
 .../apache/solr/metrics/SolrMetricsContext.java    | 45 +++++++++++++++----
 .../java/org/apache/solr/search/CaffeineCache.java | 12 ++++--
 .../src/java/org/apache/solr/search/SolrCache.java |  3 +-
 .../org/apache/solr/search/SolrCacheHolder.java    |  6 +++
 .../org/apache/solr/search/SolrIndexSearcher.java  |  5 +--
 .../apache/solr/security/AuditLoggerPlugin.java    | 20 ++++-----
 .../apache/solr/security/AuthenticationPlugin.java | 18 ++++----
 .../org/apache/solr/store/blockcache/Metrics.java  |  4 +-
 .../solr/store/hdfs/HdfsLocalityReporter.java      |  4 +-
 .../apache/solr/update/DirectUpdateHandler2.java   | 50 +++++++++++-----------
 .../src/java/org/apache/solr/update/PeerSync.java  |  2 +-
 .../org/apache/solr/update/PeerSyncWithLeader.java |  2 +-
 .../org/apache/solr/update/SolrIndexWriter.java    |  2 +-
 .../src/java/org/apache/solr/update/UpdateLog.java | 14 +++---
 .../org/apache/solr/update/UpdateShardHandler.java |  2 +-
 .../stats/InstrumentedHttpRequestExecutor.java     |  6 +--
 ...rumentedPoolingHttpClientConnectionManager.java | 14 +++---
 .../apache/solr/core/HdfsDirectoryFactoryTest.java |  2 +-
 .../test/org/apache/solr/core/MockInfoBean.java    |  4 +-
 .../solr/handler/admin/MBeansHandlerTest.java      |  2 +-
 .../managed/TestDefaultResourceManagerPool.java    | 19 +++++---
 .../apache/solr/metrics/SolrMetricTestUtils.java   |  2 +-
 .../org/apache/solr/search/TestSolrCachePerf.java  |  2 +-
 .../apache/solr/search/TestSolrFieldCacheBean.java |  4 +-
 41 files changed, 230 insertions(+), 161 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index e969f11..a4dea32 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -635,7 +635,7 @@ public class CoreContainer {
 
     metricManager = new SolrMetricManager(loader, cfg.getMetricsConfig());
     String registryName = SolrMetricManager.getRegistryName(SolrInfoBean.Group.node);
-    solrMetricsContext = new SolrMetricsContext(metricManager, registryName, metricTag);
+    solrMetricsContext = new SolrMetricsContext(metricManager, registryName, "container", metricTag);
 
     coreContainerWorkExecutor = MetricUtils.instrumentedExecutorService(
         coreContainerWorkExecutor, null,
diff --git a/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java b/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
index 7149821..cb53d41 100644
--- a/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
+++ b/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
@@ -146,18 +146,18 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    this.solrMetricsContext = parentContext.getChildContext(this);
-    numErrors = solrMetricsContext.meter("errors", getCategory().toString(), scope);
-    numServerErrors = solrMetricsContext.meter("serverErrors", getCategory().toString(), scope);
-    numClientErrors = solrMetricsContext.meter("clientErrors", getCategory().toString(), scope);
-    numTimeouts = solrMetricsContext.meter("timeouts", getCategory().toString(), scope);
-    requests = solrMetricsContext.counter("requests", getCategory().toString(), scope);
+    this.solrMetricsContext = parentContext.getChildContext(this, scope);
+    numErrors = solrMetricsContext.meter("errors", getCategory().toString());
+    numServerErrors = solrMetricsContext.meter("serverErrors", getCategory().toString());
+    numClientErrors = solrMetricsContext.meter("clientErrors", getCategory().toString());
+    numTimeouts = solrMetricsContext.meter("timeouts", getCategory().toString());
+    requests = solrMetricsContext.counter("requests", getCategory().toString());
     MetricsMap metricsMap = new MetricsMap((detail, map) ->
         shardPurposes.forEach((k, v) -> map.put(k, v.getCount())));
-    solrMetricsContext.gauge(metricsMap, true, "shardRequests", getCategory().toString(), scope);
-    requestTimes = solrMetricsContext.timer("requestTimes", getCategory().toString(), scope);
-    totalTime = solrMetricsContext.counter("totalTime", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> handlerStart, true, "handlerStart", getCategory().toString(), scope);
+    solrMetricsContext.gauge(metricsMap, true, "shardRequests", getCategory().toString());
+    requestTimes = solrMetricsContext.timer("requestTimes", getCategory().toString());
+    totalTime = solrMetricsContext.counter("totalTime", getCategory().toString());
+    solrMetricsContext.gauge(() -> handlerStart, true, "handlerStart", getCategory().toString());
   }
 
   public static SolrParams getSolrParamsFromNamedList(NamedList args, String key) {
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
index 8c58dea..854da43 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
@@ -17,7 +17,6 @@
 package org.apache.solr.handler.admin;
 
 import java.lang.invoke.MethodHandles;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
@@ -151,8 +150,8 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
         result.add("poolParams", pool.getParams());
         result.add("resources", pool.getComponents().keySet());
         try {
-          pool.getCurrentValues();
-          result.add("totalValues", pool.getTotalValues());
+          Map<String, Map<String, Object>> values = pool.getCurrentValues();
+          result.add("totalValues", pool.getResourceManagerPlugin().aggregateTotalValues(values));
         } catch (Exception e) {
           log.warn("Error getting current values from pool " + name, e);
           result.add("error", "Error getting current values: " + e.toString());
@@ -331,4 +330,4 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
   public Category getCategory() {
     return Category.ADMIN;
   }
-}
+}
\ No newline at end of file
diff --git a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
index a091874..d4b58ff 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
@@ -452,7 +452,7 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory implements org.
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     String expandedScope = SolrMetricManager.mkName(scope, SolrInfoBean.Category.QUERY.name());
     httpListenerFactory.initializeMetrics(solrMetricsContext, expandedScope);
     commExecutor = MetricUtils.instrumentedExecutorService(commExecutor, null,
diff --git a/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java b/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java
index 5a524a9..7735b12 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java
@@ -120,7 +120,7 @@ public abstract class SearchComponent implements SolrInfoBean, NamedListInitiali
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
     // By default don't register any metrics - but prepare a child context
-    this.solrMetricsContext = parentContext.getChildContext(this);
+    this.solrMetricsContext = parentContext.getChildContext(this, scope);
   }
 
   public static final Map<String, Class<? extends SearchComponent>> standard_components;
diff --git a/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
index fe24f5e..a284f5d 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
@@ -356,7 +356,7 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    this.metricsContext = parentContext.getChildContext(this);
+    this.metricsContext = parentContext.getChildContext(this, scope);
 
     this.metricsContext.gauge(() -> ramBytesUsed(), true, "totalSizeInBytes", getCategory().toString());
     MetricsMap suggestersMap = new MetricsMap((detailed, map) -> {
@@ -365,7 +365,7 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
         map.put(entry.getKey(), suggester.toString());
       }
     });
-    this.metricsContext.gauge(suggestersMap, true, "suggesters", getCategory().toString(), scope);
+    this.metricsContext.gauge(suggestersMap, true, "suggesters", getCategory().toString());
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java b/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java
index 5c41b13..afb3e91 100644
--- a/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java
+++ b/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java
@@ -68,8 +68,8 @@ public abstract class HighlightingPluginBase implements SolrInfoBean
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
-    numRequests = solrMetricsContext.counter("requests", getCategory().toString(), scope);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
+    numRequests = solrMetricsContext.counter("requests", getCategory().toString());
   }
 }
 
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
index 98771b8..f00866c 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
@@ -43,7 +43,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   private final String name;
   private final ResourceManagerPlugin resourceManagerPlugin;
   private final Map<String, Object> args;
-  private final ManagedContext poolContext = new ManagedContext();
+  private final PoolContext poolContext = new PoolContext();
   private final ReentrantLock updateLock = new ReentrantLock();
   int scheduleDelaySeconds;
   ScheduledFuture<?> scheduledFuture;
@@ -143,7 +143,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   }
 
   @Override
-  public ManagedContext getPoolContext() {
+  public PoolContext getPoolContext() {
     return poolContext;
   }
 
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java b/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
index d8e6692..4ea5922 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
@@ -16,23 +16,25 @@
  */
 package org.apache.solr.managed;
 
-import org.apache.solr.core.SolrInfoBean;
-
 /**
  * A managed component.
  */
-public interface ManagedComponent extends SolrInfoBean {
+public interface ManagedComponent extends AutoCloseable {
   /**
    * Unique name of this component. By convention id-s form a colon-separated hierarchy.
    */
   ManagedComponentId getManagedComponentId();
 
+  void initializeManagedComponent(ResourceManager resourceManager, String poolName, String... otherPools);
+
   /**
    * Component context used for managing additional component state for the purpose of resource management.
    */
   ManagedContext getManagedContext();
 
   default void close() throws Exception {
-    SolrInfoBean.super.close();
+    if (getManagedContext() != null) {
+      getManagedContext().close();
+    }
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java b/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
index 7b5d908..9b80e2d 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
@@ -19,30 +19,41 @@ package org.apache.solr.managed;
 
 import java.util.Arrays;
 
+import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
+
 /**
  * Hierarchical component id.
  */
 public class ManagedComponentId {
+
+  public static final String SEPARATOR = ":";
+
   private final String type;
   private final String name;
   private final String[] path;
   private final String id;
 
-  public ManagedComponentId(String type, String name, String... path) {
+  public ManagedComponentId(String type, Object component, String... path) {
+    this(type, SolrMetricProducer.getUniqueMetricTag(component, null), path);
+  }
+
+  ManagedComponentId(String type, String name, String... path) {
     this.type = type;
     this.name = name;
     this.path = path;
     StringBuilder sb = new StringBuilder();
+    sb.append(type);
     if (path != null) {
       for (String pathEl : path) {
         if (sb.length() > 0) {
-          sb.append(':');
+          sb.append(SEPARATOR);
         }
         sb.append(pathEl);
       }
     }
     if (sb.length() > 0) {
-      sb.append(':');
+      sb.append(SEPARATOR);
     }
     sb.append(name);
     id = sb.toString();
@@ -68,14 +79,14 @@ public class ManagedComponentId {
     if (fullName == null || fullName.isEmpty()) {
       return null;
     }
-    String[] parts = fullName.split(":");
+    String[] parts = fullName.split(SEPARATOR);
     if (parts.length < 2) {
       throw new RuntimeException("at least 2 parts (type and name) must be present: " + fullName);
     }
     if (parts.length > 2) {
-      String type = parts[parts.length - 1];
-      String name = parts[parts.length - 2];
-      String[] path = Arrays.copyOfRange(parts, 0, parts.length - 2);
+      String type = parts[0];
+      String name = parts[parts.length - 1];
+      String[] path = Arrays.copyOfRange(parts, 1, parts.length - 1);
       return new ManagedComponentId(type, name, path);
     } else {
       return new ManagedComponentId(parts[0], parts[1]);
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedContext.java b/solr/core/src/java/org/apache/solr/managed/ManagedContext.java
index 3cf6839..f426d7c 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedContext.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedContext.java
@@ -16,30 +16,45 @@
  */
 package org.apache.solr.managed;
 
+import java.io.Closeable;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
 /**
  *
  */
-public class ManagedContext {
+public class ManagedContext implements Closeable {
   private final ResourceManager resourceManager;
-  private final String poolName;
+  private final String[] poolNames;
   private final ManagedComponent component;
 
-  public ManagedContext(ResourceManager resourceManager, String poolName, ManagedComponent component) {
+  public ManagedContext(ResourceManager resourceManager, ManagedComponent component, String poolName, String... otherPools) {
     this.resourceManager = resourceManager;
-    this.poolName = poolName;
+    Set<String> pools = new LinkedHashSet<>();
+    pools.add(poolName);
+    if (otherPools != null) {
+      Collections.addAll(pools, otherPools);
+    }
+    this.poolNames = (String[])pools.toArray(new String[pools.size()]);
     this.component = component;
-    this.resourceManager.registerComponent(poolName, component);
+    for (String pool : poolNames) {
+      this.resourceManager.registerComponent(pool, component);
+    }
   }
 
   public ResourceManager getResourceManager() {
     return resourceManager;
   }
 
-  public String getPoolName() {
-    return poolName;
+  public String[] getPoolNames() {
+    return poolNames;
   }
 
-  public void unregister() {
-    resourceManager.unregisterComponent(poolName, component.getManagedComponentId());
+  @Override
+  public void close() {
+    for (String poolName : poolNames) {
+      resourceManager.unregisterComponent(poolName, component.getManagedComponentId());
+    }
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
index d828a4f..9dc0fc3 100644
--- a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
@@ -118,11 +118,6 @@ public class NoOpResourceManager extends ResourceManager {
     }
 
     @Override
-    public Map<String, Object> getTotalValues() throws InterruptedException {
-      return Collections.emptyMap();
-    }
-
-    @Override
     public Map<String, Object> getPoolLimits() {
       return Collections.emptyMap();
     }
@@ -138,7 +133,7 @@ public class NoOpResourceManager extends ResourceManager {
     }
 
     @Override
-    public ManagedContext getPoolContext() {
+    public PoolContext getPoolContext() {
       return null;
     }
 
@@ -184,7 +179,7 @@ public class NoOpResourceManager extends ResourceManager {
   }
 
   @Override
-  public void registerComponent(String pool, ManagedComponent managedComponent) throws Exception {
+  public void registerComponent(String pool, ManagedComponent managedComponent) {
     // no-op
   }
 
diff --git a/solr/core/src/java/org/apache/solr/managed/PoolContext.java b/solr/core/src/java/org/apache/solr/managed/PoolContext.java
new file mode 100644
index 0000000..221e1d0
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/PoolContext.java
@@ -0,0 +1,9 @@
+package org.apache.solr.managed;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ *
+ */
+public class PoolContext extends ConcurrentHashMap<String, Object> {
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index 9f2b4ff..4f1a786 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -52,5 +52,5 @@ public interface ResourceManagerPool extends Runnable, Closeable {
   /**
    * Pool context used for managing additional pool state.
    */
-  ManagedContext getPoolContext();
+  PoolContext getPoolContext();
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
index 4956c58..695b046 100644
--- a/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
@@ -131,7 +131,7 @@ public class CacheManagerPlugin implements ResourceManagerPlugin<SolrCache> {
   @Override
   public void manage(ResourceManagerPool pool) throws Exception {
     Map<String, Map<String, Object>> currentValues = pool.getCurrentValues();
-    Map<String, Object> totalValues = pool.getTotalValues();
+    Map<String, Object> totalValues = pool.getResourceManagerPlugin().aggregateTotalValues(currentValues);
     // pool limits are defined using controlled tags
     pool.getPoolLimits().forEach((poolLimitName, value) -> {
       // only numeric limits are supported
diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java b/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
index 572c01c..7fb0944 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
@@ -53,7 +53,7 @@ public class SolrCoreMetricManager implements Closeable {
     initCloudMode();
     metricManager = core.getCoreContainer().getMetricManager();
     String registryName = createRegistryName(cloudMode, collectionName, shardName, replicaName, core.getName());
-    solrMetricsContext = new SolrMetricsContext(metricManager, registryName, core.getMetricTag());
+    solrMetricsContext = new SolrMetricsContext(metricManager, registryName, "SolrCore", core.getMetricTag());
     leaderRegistryName = createLeaderRegistryName(cloudMode, collectionName, shardName);
   }
 
@@ -106,7 +106,7 @@ public class SolrCoreMetricManager implements Closeable {
     if (oldLeaderRegistryName != null) {
       metricManager.closeReporters(oldLeaderRegistryName, solrMetricsContext.getTag());
     }
-    solrMetricsContext = new SolrMetricsContext(metricManager, newRegistryName, solrMetricsContext.getTag());
+    solrMetricsContext = new SolrMetricsContext(metricManager, newRegistryName, "SolrCore", solrMetricsContext.getTag());
     // load reporters again, using the new core name
     loadReporters();
   }
diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java b/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java
index c321a11..69a356b 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java
@@ -44,11 +44,11 @@ public interface SolrMetricProducer extends AutoCloseable {
    * Initialize metrics specific to this producer.
    * @param parentContext parent metrics context. If this component has the same life-cycle as the parent
    *                it can simply use the parent context, otherwise it should obtain a child context
-   *                using {@link SolrMetricsContext#getChildContext(Object)} passing <code>this</code>
-   *                as the child object.
-   * @param scope component scope
+   *                using {@link SolrMetricsContext#getChildContext(Object, String)} passing <code>this</code>
+   *                as the child object and <code>childScope</code> as the scope.
+   * @param childScope component scope
    */
-  void initializeMetrics(SolrMetricsContext parentContext, String scope);
+  void initializeMetrics(SolrMetricsContext parentContext, String childScope);
 
   /**
    * Implementations should return the context used in
diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrMetricsContext.java b/solr/core/src/java/org/apache/solr/metrics/SolrMetricsContext.java
index 6861457..66a3718 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricsContext.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricsContext.java
@@ -17,6 +17,8 @@
 
 package org.apache.solr.metrics;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -38,15 +40,28 @@ import org.apache.solr.util.stats.MetricUtils;
 public class SolrMetricsContext {
   private final String registryName;
   private final SolrMetricManager metricManager;
+  private final String scope;
   private final String tag;
   private final Set<String> metricNames = ConcurrentHashMap.newKeySet();
 
-  public SolrMetricsContext(SolrMetricManager metricManager, String registryName, String tag) {
+  public SolrMetricsContext(SolrMetricManager metricManager, String registryName, String scope, String tag) {
     this.registryName = registryName;
     this.metricManager = metricManager;
+    this.scope = scope;
     this.tag = tag;
   }
 
+  public SolrMetricsContext(SolrMetricManager metricManager, String registryName, String tag) {
+    this(metricManager, registryName, null, tag);
+  }
+
+  /**
+   * Scope of the component where this context is used.
+   */
+  public String getScope() {
+    return scope;
+  }
+
   /**
    * Metrics tag that represents objects with the same life-cycle.
    */
@@ -92,8 +107,8 @@ public class SolrMetricsContext {
    * and child are different.
    * @param child child object that produces metrics with a different life-cycle than the parent.
    */
-  public SolrMetricsContext getChildContext(Object child) {
-    SolrMetricsContext childContext = new SolrMetricsContext(metricManager, registryName, SolrMetricProducer.getUniqueMetricTag(child, tag));
+  public SolrMetricsContext getChildContext(Object child, String childScope) {
+    SolrMetricsContext childContext = new SolrMetricsContext(metricManager, registryName, childScope, SolrMetricProducer.getUniqueMetricTag(child, tag));
     return childContext;
   }
 
@@ -113,18 +128,32 @@ public class SolrMetricsContext {
     return MetricUtils.convertMetrics(getMetricRegistry(), metricNames);
   }
 
+  private String createName(String metricName, String... metricpath) {
+    ArrayList<String> l = new ArrayList<>();
+    if(metricpath != null ) {
+      Collections.addAll(l, metricpath);
+    }
+    if (scope != null) {
+      l.add(scope);
+    }
+    if (metricName != null) {
+      l.add(metricName);
+    }
+    return String.join(".", l);
+  }
+
   /**
    * Convenience method for {@link SolrMetricManager#meter(SolrMetricsContext, String, String, String...)}.
    */
   public Meter meter(String metricName, String... metricPath) {
-    return metricManager.meter(this, registryName, metricName, metricPath);
+    return metricManager.meter(this, registryName, createName(metricName, metricPath));
   }
 
   /**
    * Convenience method for {@link SolrMetricManager#counter(SolrMetricsContext, String, String, String...)}.
    */
   public Counter counter(String metricName, String... metricPath) {
-    return metricManager.counter(this, registryName, metricName, metricPath);
+    return metricManager.counter(this, registryName, createName(metricName, metricPath));
 
   }
 
@@ -132,21 +161,21 @@ public class SolrMetricsContext {
    * Convenience method for {@link SolrMetricManager#registerGauge(SolrMetricsContext, String, Gauge, String, boolean, String, String...)}.
    */
   public void gauge(Gauge<?> gauge, boolean force, String metricName, String... metricPath) {
-    metricManager.registerGauge(this, registryName, gauge, tag, force, metricName, metricPath);
+    metricManager.registerGauge(this, registryName, gauge, tag, force, createName(metricName, metricPath));
   }
 
   /**
    * Convenience method for {@link SolrMetricManager#meter(SolrMetricsContext, String, String, String...)}.
    */
   public Timer timer(String metricName, String... metricPath) {
-    return metricManager.timer(this, registryName, metricName, metricPath);
+    return metricManager.timer(this, registryName, createName(metricName, metricPath));
   }
 
   /**
    * Convenience method for {@link SolrMetricManager#histogram(SolrMetricsContext, String, String, String...)}.
    */
   public Histogram histogram(String metricName, String... metricPath) {
-    return metricManager.histogram(this, registryName, metricName, metricPath);
+    return metricManager.histogram(this, registryName, createName(metricName, metricPath));
   }
 
   /**
diff --git a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
index ea1db54..2002d4b 100644
--- a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
+++ b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
@@ -37,7 +37,7 @@ import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.managed.ManagedComponentId;
 import org.apache.solr.managed.ManagedContext;
-import org.apache.solr.managed.ResourceManagerPluginFactory;
+import org.apache.solr.managed.ResourceManager;
 import org.apache.solr.managed.types.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricsContext;
@@ -364,7 +364,7 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     cacheMap = new MetricsMap((detailed, map) -> {
       if (cache != null) {
         CacheStats stats = cache.stats();
@@ -389,8 +389,12 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
       }
     });
     solrMetricsContext.gauge(cacheMap, true, scope, getCategory().toString());
-    managedComponentId = new ManagedComponentId(CacheManagerPlugin.TYPE, solrMetricsContext.getTag(), solrMetricsContext.getRegistryName(), getCategory().toString(), scope);
-    managedContext = new ManagedContext()
+  }
+
+  @Override
+  public void initializeManagedComponent(ResourceManager resourceManager, String poolName, String... otherPools) {
+    managedComponentId = new ManagedComponentId(CacheManagerPlugin.TYPE, this, solrMetricsContext.getRegistryName(), getCategory().toString(), solrMetricsContext.getScope());
+    managedContext = new ManagedContext(resourceManager, this, poolName, otherPools);
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCache.java b/solr/core/src/java/org/apache/solr/search/SolrCache.java
index 3744895..a8ead8c 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCache.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCache.java
@@ -163,9 +163,10 @@ public interface SolrCache<K,V> extends SolrInfoBean, ManagedComponent, Accounta
   // init and have the cache implementation save it.
 
 
-  /** Frees any non-memory resources */
+  /** Frees any non-memory resources and unregisters this instance from resource management. */
   default void close() throws Exception {
     SolrInfoBean.super.close();
+    ManagedComponent.super.close();
   }
 
   /** Returns maximum size limit (number of items) if set and supported, -1 otherwise. */
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java b/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
index 88a821d..5f1dbf8 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
@@ -23,6 +23,7 @@ import java.util.function.Function;
 
 import org.apache.solr.managed.ManagedComponentId;
 import org.apache.solr.managed.ManagedContext;
+import org.apache.solr.managed.ResourceManager;
 import org.apache.solr.metrics.SolrMetricsContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -160,6 +161,11 @@ public class SolrCacheHolder<K, V> implements SolrCache<K,V> {
   }
 
   @Override
+  public void initializeManagedComponent(ResourceManager resourceManager, String poolName, String... otherPools) {
+    delegate.initializeManagedComponent(resourceManager, poolName, otherPools);
+  }
+
+  @Override
   public ManagedContext getManagedContext() {
     return delegate.getManagedContext();
   }
diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
index fba2aa1..3994b2c 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -433,11 +433,11 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
       infoRegistry.put(cache.name(), cache);
     }
     ResourceManager resourceManager = core.getCoreContainer().getResourceManager();
-    this.solrMetricsContext = core.getSolrMetricsContext().getChildContext(this);
+    this.solrMetricsContext = core.getSolrMetricsContext().getChildContext(this, null);
     for (SolrCache cache : cacheList) {
       cache.initializeMetrics(solrMetricsContext, SolrMetricManager.mkName(cache.name(), STATISTICS_KEY));
       try {
-        resourceManager.registerComponent(DefaultResourceManager.NODE_SEARCHER_CACHE_POOL, cache);
+        cache.initializeManagedComponent(resourceManager, DefaultResourceManager.NODE_SEARCHER_CACHE_POOL);
       } catch (Exception e) {
         log.warn("Exception adding cache '" + cache.getManagedComponentId() + "' to the resource manager pool", e);
       }
@@ -486,7 +486,6 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
 
     for (SolrCache cache : cacheList) {
       try {
-        core.getCoreContainer().getResourceManager().unregisterComponent(DefaultResourceManager.NODE_SEARCHER_CACHE_POOL, cache.getManagedComponentId().toString());
         cache.close();
       } catch (Exception e) {
         SolrException.log(log, "Exception closing cache " + cache.name(), e);
diff --git a/solr/core/src/java/org/apache/solr/security/AuditLoggerPlugin.java b/solr/core/src/java/org/apache/solr/security/AuditLoggerPlugin.java
index c3ff254..2569118 100644
--- a/solr/core/src/java/org/apache/solr/security/AuditLoggerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/security/AuditLoggerPlugin.java
@@ -236,20 +236,20 @@ public abstract class AuditLoggerPlugin implements Closeable, Runnable, SolrInfo
   
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, final String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     String className = this.getClass().getSimpleName();
     log.debug("Initializing metrics for {}", className);
-    numErrors = solrMetricsContext.meter("errors", getCategory().toString(), scope, className);
-    numLost = solrMetricsContext.meter("lost", getCategory().toString(), scope, className);
-    numLogged = solrMetricsContext.meter("count", getCategory().toString(), scope, className);
-    requestTimes = solrMetricsContext.timer("requestTimes", getCategory().toString(), scope, className);
-    totalTime = solrMetricsContext.counter("totalTime", getCategory().toString(), scope, className);
+    numErrors = solrMetricsContext.meter("errors", getCategory().toString(), className);
+    numLost = solrMetricsContext.meter("lost", getCategory().toString(), className);
+    numLogged = solrMetricsContext.meter("count", getCategory().toString(), className);
+    requestTimes = solrMetricsContext.timer("requestTimes", getCategory().toString(), className);
+    totalTime = solrMetricsContext.counter("totalTime", getCategory().toString(), className);
     if (async) {
-      solrMetricsContext.gauge(() -> blockingQueueSize, true, "queueCapacity", getCategory().toString(), scope, className);
-      solrMetricsContext.gauge(() -> blockingQueueSize - queue.remainingCapacity(), true, "queueSize", getCategory().toString(), scope, className);
-      queuedTime = solrMetricsContext.timer("queuedTime", getCategory().toString(), scope, className);
+      solrMetricsContext.gauge(() -> blockingQueueSize, true, "queueCapacity", getCategory().toString(), className);
+      solrMetricsContext.gauge(() -> blockingQueueSize - queue.remainingCapacity(), true, "queueSize", getCategory().toString(), className);
+      queuedTime = solrMetricsContext.timer("queuedTime", getCategory().toString(), className);
     }
-    solrMetricsContext.gauge(() -> async, true, "async", getCategory().toString(), scope, className);
+    solrMetricsContext.gauge(() -> async, true, "async", getCategory().toString(), className);
   }
   
   @Override
diff --git a/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java b/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java
index f08651a..f083a31 100644
--- a/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java
+++ b/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java
@@ -144,16 +144,16 @@ public abstract class AuthenticationPlugin implements SolrInfoBean {
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    this.solrMetricsContext = parentContext.getChildContext(this);
+    this.solrMetricsContext = parentContext.getChildContext(this, scope);
     // Metrics
-    numErrors = this.solrMetricsContext.meter("errors", getCategory().toString(), scope);
-    requests = this.solrMetricsContext.counter("requests", getCategory().toString(), scope);
-    numAuthenticated = this.solrMetricsContext.counter("authenticated",getCategory().toString(), scope);
-    numPassThrough = this.solrMetricsContext.counter("passThrough",  getCategory().toString(), scope);
-    numWrongCredentials = this.solrMetricsContext.counter("failWrongCredentials",getCategory().toString(), scope);
-    numMissingCredentials = this.solrMetricsContext.counter("failMissingCredentials",getCategory().toString(), scope);
-    requestTimes = this.solrMetricsContext.timer("requestTimes", getCategory().toString(), scope);
-    totalTime = this.solrMetricsContext.counter("totalTime", getCategory().toString(), scope);
+    numErrors = this.solrMetricsContext.meter("errors", getCategory().toString());
+    requests = this.solrMetricsContext.counter("requests", getCategory().toString());
+    numAuthenticated = this.solrMetricsContext.counter("authenticated",getCategory().toString());
+    numPassThrough = this.solrMetricsContext.counter("passThrough",  getCategory().toString());
+    numWrongCredentials = this.solrMetricsContext.counter("failWrongCredentials",getCategory().toString());
+    numMissingCredentials = this.solrMetricsContext.counter("failMissingCredentials",getCategory().toString());
+    requestTimes = this.solrMetricsContext.timer("requestTimes", getCategory().toString());
+    totalTime = this.solrMetricsContext.counter("totalTime", getCategory().toString());
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java b/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java
index 37d735e..809a31b 100644
--- a/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java
+++ b/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java
@@ -58,7 +58,7 @@ public class Metrics extends SolrCacheBase implements SolrInfoBean {
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     metricsMap = new MetricsMap((detailed, map) -> {
       long now = System.nanoTime();
       long delta = Math.max(now - previous, 1);
@@ -102,7 +102,7 @@ public class Metrics extends SolrCacheBase implements SolrInfoBean {
       previous = now;
 
     });
-    solrMetricsContext.gauge(metricsMap, true, getName(), getCategory().toString(), scope);
+    solrMetricsContext.gauge(metricsMap, true, getName(), getCategory().toString());
   }
 
   private float getPerSecond(long value, double seconds) {
diff --git a/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java b/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java
index 4cf9090..2b8a1b7 100644
--- a/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java
+++ b/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java
@@ -88,7 +88,7 @@ public class HdfsLocalityReporter implements SolrInfoBean {
    */
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     MetricsMap metricsMap = new MetricsMap((detailed, map) -> {
       long totalBytes = 0;
       long localBytes = 0;
@@ -138,7 +138,7 @@ public class HdfsLocalityReporter implements SolrInfoBean {
         map.put(LOCALITY_BLOCKS_RATIO, localCount / (double) totalCount);
       }
     });
-    solrMetricsContext.gauge(metricsMap, true, "hdfsLocality", getCategory().toString(), scope);
+    solrMetricsContext.gauge(metricsMap, true, "hdfsLocality", getCategory().toString());
   }
 
   /**
diff --git a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
index b6232ae..8cec555 100644
--- a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
+++ b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
@@ -169,45 +169,45 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
-    commitCommands = solrMetricsContext.meter("commits", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> commitTracker.getCommitCount(), true, "autoCommits", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> softCommitTracker.getCommitCount(), true, "softAutoCommits", getCategory().toString(), scope);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
+    commitCommands = solrMetricsContext.meter("commits", getCategory().toString());
+    solrMetricsContext.gauge(() -> commitTracker.getCommitCount(), true, "autoCommits", getCategory().toString());
+    solrMetricsContext.gauge(() -> softCommitTracker.getCommitCount(), true, "softAutoCommits", getCategory().toString());
     if (commitTracker.getDocsUpperBound() > 0) {
       solrMetricsContext.gauge(() -> commitTracker.getDocsUpperBound(), true, "autoCommitMaxDocs",
-          getCategory().toString(), scope);
+          getCategory().toString());
     }
     if (commitTracker.getTimeUpperBound() > 0) {
       solrMetricsContext.gauge(() -> "" + commitTracker.getTimeUpperBound() + "ms", true, "autoCommitMaxTime",
-          getCategory().toString(), scope);
+          getCategory().toString());
     }
     if (commitTracker.getTLogFileSizeUpperBound() > 0) {
       solrMetricsContext.gauge(() -> commitTracker.getTLogFileSizeUpperBound(), true, "autoCommitMaxSize",
-          getCategory().toString(), scope);
+          getCategory().toString());
     }
     if (softCommitTracker.getDocsUpperBound() > 0) {
       solrMetricsContext.gauge(() -> softCommitTracker.getDocsUpperBound(), true, "softAutoCommitMaxDocs",
-          getCategory().toString(), scope);
+          getCategory().toString());
     }
     if (softCommitTracker.getTimeUpperBound() > 0) {
       solrMetricsContext.gauge(() -> "" + softCommitTracker.getTimeUpperBound() + "ms", true, "softAutoCommitMaxTime",
-          getCategory().toString(), scope);
-    }
-    optimizeCommands = solrMetricsContext.meter("optimizes", getCategory().toString(), scope);
-    rollbackCommands = solrMetricsContext.meter("rollbacks", getCategory().toString(), scope);
-    splitCommands = solrMetricsContext.meter("splits", getCategory().toString(), scope);
-    mergeIndexesCommands = solrMetricsContext.meter("merges", getCategory().toString(), scope);
-    expungeDeleteCommands = solrMetricsContext.meter("expungeDeletes", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> numDocsPending.longValue(), true, "docsPending", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> addCommands.longValue(), true, "adds", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> deleteByIdCommands.longValue(), true, "deletesById", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> deleteByQueryCommands.longValue(), true, "deletesByQuery", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> numErrors.longValue(), true, "errors", getCategory().toString(), scope);
-
-    addCommandsCumulative = solrMetricsContext.meter("cumulativeAdds", getCategory().toString(), scope);
-    deleteByIdCommandsCumulative = solrMetricsContext.meter("cumulativeDeletesById", getCategory().toString(), scope);
-    deleteByQueryCommandsCumulative = solrMetricsContext.meter("cumulativeDeletesByQuery", getCategory().toString(), scope);
-    numErrorsCumulative = solrMetricsContext.meter("cumulativeErrors", getCategory().toString(), scope);
+          getCategory().toString());
+    }
+    optimizeCommands = solrMetricsContext.meter("optimizes", getCategory().toString());
+    rollbackCommands = solrMetricsContext.meter("rollbacks", getCategory().toString());
+    splitCommands = solrMetricsContext.meter("splits", getCategory().toString());
+    mergeIndexesCommands = solrMetricsContext.meter("merges", getCategory().toString());
+    expungeDeleteCommands = solrMetricsContext.meter("expungeDeletes", getCategory().toString());
+    solrMetricsContext.gauge(() -> numDocsPending.longValue(), true, "docsPending", getCategory().toString());
+    solrMetricsContext.gauge(() -> addCommands.longValue(), true, "adds", getCategory().toString());
+    solrMetricsContext.gauge(() -> deleteByIdCommands.longValue(), true, "deletesById", getCategory().toString());
+    solrMetricsContext.gauge(() -> deleteByQueryCommands.longValue(), true, "deletesByQuery", getCategory().toString());
+    solrMetricsContext.gauge(() -> numErrors.longValue(), true, "errors", getCategory().toString());
+
+    addCommandsCumulative = solrMetricsContext.meter("cumulativeAdds", getCategory().toString());
+    deleteByIdCommandsCumulative = solrMetricsContext.meter("cumulativeDeletesById", getCategory().toString());
+    deleteByQueryCommandsCumulative = solrMetricsContext.meter("cumulativeDeletesByQuery", getCategory().toString());
+    numErrorsCumulative = solrMetricsContext.meter("cumulativeErrors", getCategory().toString());
   }
 
   private void deleteAll() throws IOException {
diff --git a/solr/core/src/java/org/apache/solr/update/PeerSync.java b/solr/core/src/java/org/apache/solr/update/PeerSync.java
index 801e48f..a47a339 100644
--- a/solr/core/src/java/org/apache/solr/update/PeerSync.java
+++ b/solr/core/src/java/org/apache/solr/update/PeerSync.java
@@ -140,7 +140,7 @@ public class PeerSync implements SolrMetricProducer {
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    this.solrMetricsContext = parentContext.getChildContext(this);
+    this.solrMetricsContext = parentContext.getChildContext(this, null);
     syncTime = solrMetricsContext.timer("time", scope, METRIC_SCOPE);
     syncErrors = solrMetricsContext.counter("errors", scope, METRIC_SCOPE);
     syncSkipped = solrMetricsContext.counter("skipped", scope, METRIC_SCOPE);
diff --git a/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java b/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java
index fca105e..f03bd8d 100644
--- a/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java
+++ b/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java
@@ -97,7 +97,7 @@ public class PeerSyncWithLeader implements SolrMetricProducer {
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    this.solrMetricsContext = parentContext.getChildContext(this);
+    this.solrMetricsContext = parentContext.getChildContext(this, null);
     syncTime = solrMetricsContext.timer("time", scope, METRIC_SCOPE);
     syncErrors = solrMetricsContext.counter("errors", scope, METRIC_SCOPE);
     syncSkipped = solrMetricsContext.counter("skipped", scope, METRIC_SCOPE);
diff --git a/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
index 4070ea9..4d92481 100644
--- a/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
+++ b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
@@ -133,7 +133,7 @@ public class SolrIndexWriter extends IndexWriter {
     infoStream = getConfig().getInfoStream();
     this.directory = directory;
     numOpens.incrementAndGet();
-    solrMetricsContext = core.getSolrMetricsContext().getChildContext(this);
+    solrMetricsContext = core.getSolrMetricsContext().getChildContext(this, null);
     if (config.metricsInfo != null && config.metricsInfo.initArgs != null) {
       Object v = config.metricsInfo.initArgs.get("majorMergeDocs");
       if (v != null) {
diff --git a/solr/core/src/java/org/apache/solr/update/UpdateLog.java b/solr/core/src/java/org/apache/solr/update/UpdateLog.java
index 9fd185d..03cfebe 100644
--- a/solr/core/src/java/org/apache/solr/update/UpdateLog.java
+++ b/solr/core/src/java/org/apache/solr/update/UpdateLog.java
@@ -432,7 +432,7 @@ public class UpdateLog implements PluginInfoInitialized, SolrMetricProducer {
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     bufferedOpsGauge = () -> {
       if (state == State.BUFFERING) {
         if (bufferTlog == null) return  0;
@@ -449,13 +449,13 @@ public class UpdateLog implements PluginInfoInitialized, SolrMetricProducer {
       }
     };
 
-    solrMetricsContext.gauge(bufferedOpsGauge, true, "ops", scope, "buffered");
-    solrMetricsContext.gauge(() -> logs.size(), true, "logs", scope, "replay", "remaining");
-    solrMetricsContext.gauge(() -> getTotalLogsSize(), true, "bytes", scope, "replay", "remaining");
-    applyingBufferedOpsMeter = solrMetricsContext.meter("ops", scope, "applyingBuffered");
+    solrMetricsContext.gauge(bufferedOpsGauge, true, "ops", "buffered");
+    solrMetricsContext.gauge(() -> logs.size(), true, "logs", "replay", "remaining");
+    solrMetricsContext.gauge(() -> getTotalLogsSize(), true, "bytes", "replay", "remaining");
+    applyingBufferedOpsMeter = solrMetricsContext.meter("ops", "applyingBuffered");
     replayOpsMeter = solrMetricsContext.meter("ops", scope, "replay");
-    copyOverOldUpdatesMeter = solrMetricsContext.meter("ops", scope, "copyOverOldUpdates");
-    solrMetricsContext.gauge(() -> state.getValue(), true, "state", scope);
+    copyOverOldUpdatesMeter = solrMetricsContext.meter("ops", "copyOverOldUpdates");
+    solrMetricsContext.gauge(() -> state.getValue(), true, "state");
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
index 2060978..9a56f12 100644
--- a/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
+++ b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
@@ -179,7 +179,7 @@ public class UpdateShardHandler implements SolrInfoBean {
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     String expandedScope = SolrMetricManager.mkName(scope, getCategory().name());
     updateHttpListenerFactory.initializeMetrics(solrMetricsContext, expandedScope);
     defaultConnectionManager.initializeMetrics(solrMetricsContext, expandedScope);
diff --git a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpRequestExecutor.java b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpRequestExecutor.java
index 4adbe68..501ee12 100644
--- a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpRequestExecutor.java
+++ b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpRequestExecutor.java
@@ -90,7 +90,6 @@ public class InstrumentedHttpRequestExecutor extends HttpRequestExecutor impleme
     KNOWN_METRIC_NAME_STRATEGIES.put("methodOnly", METHOD_ONLY);
   }
 
-  protected String scope;
   protected HttpClientMetricNameStrategy nameStrategy;
   protected SolrMetricsContext solrMetricsContext;
 
@@ -128,12 +127,11 @@ public class InstrumentedHttpRequestExecutor extends HttpRequestExecutor impleme
   }
 
   private Timer timer(HttpRequest request) {
-    return solrMetricsContext.timer(null, nameStrategy.getNameFor(scope, request));
+    return solrMetricsContext.timer(null, nameStrategy.getNameFor(solrMetricsContext.getScope(), request));
   }
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    this.solrMetricsContext = parentContext.getChildContext(this);
-    this.scope = scope;
+    this.solrMetricsContext = parentContext.getChildContext(this, scope);
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingHttpClientConnectionManager.java b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingHttpClientConnectionManager.java
index e9144df..c69738b 100644
--- a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingHttpClientConnectionManager.java
+++ b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingHttpClientConnectionManager.java
@@ -43,16 +43,12 @@ public class InstrumentedPoolingHttpClientConnectionManager extends PoolingHttpC
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    this.solrMetricsContext = parentContext.getChildContext(this);
-    solrMetricsContext.gauge(() -> getTotalStats().getAvailable(),
-        true, SolrMetricManager.mkName("availableConnections", scope));
+    this.solrMetricsContext = parentContext.getChildContext(this, scope);
+    solrMetricsContext.gauge(() -> getTotalStats().getAvailable(), true, "availableConnections");
     // this acquires a lock on the connection pool; remove if contention sucks
-    solrMetricsContext.gauge(() -> getTotalStats().getLeased(),
-        true, SolrMetricManager.mkName("leasedConnections", scope));
-    solrMetricsContext.gauge(() -> getTotalStats().getMax(),
-        true, SolrMetricManager.mkName("maxConnections", scope));
-    solrMetricsContext.gauge(() -> getTotalStats().getPending(),
-        true, SolrMetricManager.mkName("pendingConnections", scope));
+    solrMetricsContext.gauge(() -> getTotalStats().getLeased(), true, "leasedConnections");
+    solrMetricsContext.gauge(() -> getTotalStats().getMax(), true, "maxConnections");
+    solrMetricsContext.gauge(() -> getTotalStats().getPending(), true, "pendingConnections");
   }
 
   @Override
diff --git a/solr/core/src/test/org/apache/solr/core/HdfsDirectoryFactoryTest.java b/solr/core/src/test/org/apache/solr/core/HdfsDirectoryFactoryTest.java
index 632fcb6..bbffe90 100644
--- a/solr/core/src/test/org/apache/solr/core/HdfsDirectoryFactoryTest.java
+++ b/solr/core/src/test/org/apache/solr/core/HdfsDirectoryFactoryTest.java
@@ -194,7 +194,7 @@ public class HdfsDirectoryFactoryTest extends SolrTestCaseJ4 {
       props.put(HdfsDirectoryFactory.NRTCACHINGDIRECTORY_ENABLE, "false");
       props.put(HdfsDirectoryFactory.LOCALITYMETRICS_ENABLED, "true");
       factory.init(new NamedList<>(props));
-      factory.initializeMetrics(new SolrMetricsContext(metricManager, registry, "foo"), scope);
+      factory.initializeMetrics(new SolrMetricsContext(metricManager, registry, "foo", "foo"), scope);
 
       // get the metrics map for the locality bean
       MetricsMap metrics = (MetricsMap) ((SolrMetricManager.GaugeWrapper) metricManager.registry(registry).getMetrics().get("OTHER." + scope + ".hdfsLocality")).getGauge();
diff --git a/solr/core/src/test/org/apache/solr/core/MockInfoBean.java b/solr/core/src/test/org/apache/solr/core/MockInfoBean.java
index ce73a02..5c527b4 100644
--- a/solr/core/src/test/org/apache/solr/core/MockInfoBean.java
+++ b/solr/core/src/test/org/apache/solr/core/MockInfoBean.java
@@ -49,7 +49,7 @@ class MockInfoBean implements SolrInfoBean, SolrMetricProducer {
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     MetricsMap metricsMap = new MetricsMap((detailed, map) -> {
       map.put("Integer", 123);
       map.put("Double",567.534);
@@ -60,6 +60,6 @@ class MockInfoBean implements SolrInfoBean, SolrMetricProducer {
       map.put("String","testing");
       map.put("Object", new Object());
     });
-    solrMetricsContext.gauge(metricsMap, true, getClass().getSimpleName(), getCategory().toString(), scope);
+    solrMetricsContext.gauge(metricsMap, true, getClass().getSimpleName(), getCategory().toString());
   }
 }
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/MBeansHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/admin/MBeansHandlerTest.java
index 5ec4b61..a8e45a2 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/MBeansHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/MBeansHandlerTest.java
@@ -149,7 +149,7 @@ public class MBeansHandlerTest extends SolrTestCaseJ4 {
 
       @Override
       public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-        this.solrMetricsContext = parentContext.getChildContext(this);
+        this.solrMetricsContext = parentContext.getChildContext(this, scope);
       }
 
       @Override
diff --git a/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java b/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
index 4f2fbd8..ebb9129 100644
--- a/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
+++ b/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
@@ -41,7 +41,7 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
   }
 
   public static class TestComponent implements MockManagedComponent {
-    ManagedContext context = new ManagedContext();
+    ManagedContext context;
     ManagedComponentId id;
     int foo, bar, baz;
 
@@ -77,6 +77,11 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
     }
 
     @Override
+    public void initializeManagedComponent(ResourceManager resourceManager, String poolName, String... otherPools) {
+      context = new ManagedContext(resourceManager, this, poolName, otherPools);
+    }
+
+    @Override
     public ManagedContext getManagedContext() {
       return context;
     }
@@ -138,8 +143,8 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
       }
       manageStartLatch.countDown();
       log.info("-- managing");
-      pool.getCurrentValues();
-      Map<String, Object> totalValues = pool.getTotalValues();
+      Map<String, Map<String, Object>> currentValues = pool.getCurrentValues();
+      Map<String, Object> totalValues = pool.getResourceManagerPlugin().aggregateTotalValues(currentValues);
       Map<String, Object> poolLimits = pool.getPoolLimits();
       if (poolLimits.containsKey("foo")) {
         // manage
@@ -199,8 +204,8 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
     }
     ResourceManagerPool pool = resourceManager.getPool("test");
     assertEquals(10, pool.getComponents().size());
-    pool.getCurrentValues();
-    Map<String, Object> totalValues = pool.getTotalValues();
+    Map<String, Map<String, Object>> currentValues = pool.getCurrentValues();
+    Map<String, Object> totalValues = pool.getResourceManagerPlugin().aggregateTotalValues(currentValues);
     assertNotNull(totalValues.get("bar"));
     assertEquals(55, ((Number)totalValues.get("bar")).intValue());
     assertNotNull(totalValues.get("baz"));
@@ -222,8 +227,8 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
     manageStartLatch = new CountDownLatch(1);
     boolean await = manageFinishLatch.await(30000 / SPEED, TimeUnit.MILLISECONDS);
     assertTrue("did not finish in time", await);
-    pool.getCurrentValues();
-    totalValues = pool.getTotalValues();
+    currentValues = pool.getCurrentValues();
+    totalValues = pool.getResourceManagerPlugin().aggregateTotalValues(currentValues);
     assertNotNull(totalValues.get("bar"));
     assertEquals(46, ((Number)totalValues.get("bar")).intValue());
     assertNotNull(totalValues.get("baz"));
diff --git a/solr/core/src/test/org/apache/solr/metrics/SolrMetricTestUtils.java b/solr/core/src/test/org/apache/solr/metrics/SolrMetricTestUtils.java
index 1f5f614..519cf04 100644
--- a/solr/core/src/test/org/apache/solr/metrics/SolrMetricTestUtils.java
+++ b/solr/core/src/test/org/apache/solr/metrics/SolrMetricTestUtils.java
@@ -80,7 +80,7 @@ public final class SolrMetricTestUtils {
       SolrMetricsContext solrMetricsContext;
       @Override
       public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-        this.solrMetricsContext = parentContext.getChildContext(this);
+        this.solrMetricsContext = parentContext.getChildContext(this, scope);
         if (category == null) {
           throw new IllegalArgumentException("null category");
         }
diff --git a/solr/core/src/test/org/apache/solr/search/TestSolrCachePerf.java b/solr/core/src/test/org/apache/solr/search/TestSolrCachePerf.java
index cc9cf73..0210588 100644
--- a/solr/core/src/test/org/apache/solr/search/TestSolrCachePerf.java
+++ b/solr/core/src/test/org/apache/solr/search/TestSolrCachePerf.java
@@ -94,7 +94,7 @@ public class TestSolrCachePerf extends SolrTestCaseJ4 {
       CacheRegenerator cr = new NoOpRegenerator();
       Object o = cache.init(params, null, cr);
       cache.setState(SolrCache.State.LIVE);
-      cache.initializeMetrics(new SolrMetricsContext(metricManager, "foo", "bar"), "foo");
+      cache.initializeMetrics(new SolrMetricsContext(metricManager, "foo", "foo", "bar"), "foo");
       AtomicBoolean stop = new AtomicBoolean();
       SummaryStatistics perImplRatio = ratioStats.computeIfAbsent(clazz.getSimpleName(), c -> new SummaryStatistics());
       SummaryStatistics perImplTime = timeStats.computeIfAbsent(clazz.getSimpleName(), c -> new SummaryStatistics());
diff --git a/solr/core/src/test/org/apache/solr/search/TestSolrFieldCacheBean.java b/solr/core/src/test/org/apache/solr/search/TestSolrFieldCacheBean.java
index 49b754f..cbfc9ae 100644
--- a/solr/core/src/test/org/apache/solr/search/TestSolrFieldCacheBean.java
+++ b/solr/core/src/test/org/apache/solr/search/TestSolrFieldCacheBean.java
@@ -75,7 +75,7 @@ public class TestSolrFieldCacheBean extends SolrTestCaseJ4 {
     Random r = random();
     String registryName = TestUtil.randomSimpleString(r, 1, 10);
     SolrMetricManager metricManager = h.getCoreContainer().getMetricManager();
-    SolrMetricsContext solrMetricsContext = new SolrMetricsContext(metricManager, registryName, "foo");
+    SolrMetricsContext solrMetricsContext = new SolrMetricsContext(metricManager, registryName, "foo", "foo");
     mbean.initializeMetrics(solrMetricsContext, null);
     MetricsMap metricsMap = (MetricsMap)((SolrMetricManager.GaugeWrapper)metricManager.registry(registryName).getMetrics().get("CACHE.fieldCache")).getGauge();
     Map<String, Object> metrics = checkJmx ? metricsMap.getValue(true) : metricsMap.getValue();
@@ -89,7 +89,7 @@ public class TestSolrFieldCacheBean extends SolrTestCaseJ4 {
     Random r = random();
     String registryName = TestUtil.randomSimpleString(r, 1, 10);
     SolrMetricManager metricManager = h.getCoreContainer().getMetricManager();
-    SolrMetricsContext solrMetricsContext = new SolrMetricsContext(metricManager, registryName, "foo");
+    SolrMetricsContext solrMetricsContext = new SolrMetricsContext(metricManager, registryName, "foo", "foo");
     mbean.initializeMetrics(solrMetricsContext, null);
     MetricsMap metricsMap = (MetricsMap)((SolrMetricManager.GaugeWrapper)metricManager.registry(registryName).getMetrics().get("CACHE.fieldCache")).getGauge();
     Map<String, Object> metrics = checkJmx ? metricsMap.getValue(true) : metricsMap.getValue();