[
https://issues.apache.org/jira/browse/SOLR-13579?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16892670#comment-16892670
]
Andrzej Bialecki commented on SOLR-13579:
------------------------------------------
The main scenario that prompted this development was a need to control the
aggregated cache sizes across all cores in a CoreContainer in a multi-tenant
(uncooperative) situation. However, it seemed like a similar approach would be
applicable for controlling other runtime usage of resources in a Solr node -
hence the attempt to come up with a generic framework.
A particular component may support resource management of several of its
aspects. Eg. a {{SolrIndexSearcher}} can have a "cache" RAM usage aspect,
"mergeIO" throttling aspect, "mergeThreadCount" aspect, "queryThreadCount"
aspect, etc. Each of these aspects can be managed by a different global pool
that defines total resource limits of a given type. Currently a component can
be registered only in a single pool of a given type, in order to avoid
conflicting instructions.
In the current patch the component registration and pool creation parts are
primitive - the default pools are created statically and components are forced
to register in a dedicated pool. In the future this could be configurable - eg.
components from cores belonging to different collections may belong to
different pools with different limits / priorities.
In the following stories, there are always two aspects of resource management -
control and optimization. The control aspect ensures that the specified hard
limits are observed, while the optimization aspect ensures that each component
uses resources in an optimal way. The focus of this JIRA issue is mainly on the
control aspect, with optimization to follow later.
h2. Story 1: controlling global cache RAM usage in a Solr node
{{SolrIndexSearcher}} caches are currently configured statically, using either
item count limits or {{maxRamMB}} limits. We can only specify the limit
per-cache and then we can limit the number of cores in a node to arrive at a
hard total upper limit.
However, this is not enough because it leads to keeping the heap at the upper
limit when the actual consumption by caches might be far lesser. It'd be nice
for a more active core to be able to use more heap for caches than another core
with less traffic while ensuring that total heap usage never exceeds a given
threshold (the optimization aspect). It is also required that total heap usage
of caches doesn't exceed the max threshold to ensure proper behavior of a Solr
node (the control aspect).
In order to do this we need a control mechanism that is able to adjust
individual cache sizes per core, based on the total hard limit and the actual
current "need" of a core, defined as a combination of hit ratio, QPS, and other
arbitrary quality factors / SLA. This control mechanism also needs to be able
to forcibly reduce excessive usage (evenly? prioritized by collection's SLA?)
when the aggregated heap usage exceeds the threshold.
In terms of the proposed API this scenario would work as follows:
* a global resource pool "searcherCachesPool" is created with a single hard
limit on eg. total {{maxRamMB}}.
* this pool knows how to manage components of a "cache" type - what parameters
to monitor and what parameters to use in order to control their resource usage.
This logic is encapsulated in {{CacheManagerPlugin}}.
* all searcher caches from all cores register themselves in this pool for the
purpose of managing their "cache" aspect.
* the plugin is executed periodically to check the current resource usage of
all registered caches, using eg. the aggregated value of {{ramBytesUsed}}.
* if this aggregated value exceeds the total {{maxRamMB}} limit configured for
the pool then the plugin adjusts the {{maxRamMB}} setting of each cache in
order to reduce the total RAM consumption - currently this uses a simple
proportional formula without any history (the P part of PID), with a dead-band
in order to avoid thrashing. Also, for now, this addresses only the control
aspect (exceeding a hard threshold) and not the optimization, i.e. it doesn't
proactively reduce / increase {{maxRamMB}} based on hit rate.
* as a result of this action some of the cache content will be evicted sooner
and more aggressively than initially configured, thus freeing more RAM.
* when the memory pressure decreases the {{CacheManagerPlugin}} re-adjusts the
{{maxRamMB}} settings of each cache to the initially configured values. Again,
the current implementation of this algorithm is very simple but can be easily
improved because it's cleanly separated from implementation details of each
cache.
h2. Story 2: controlling global IO usage in a Solr node.
Similarly to the scenario above, currently we can only statically configure
merge throttling (RateLimiter) per core but we can't monitor and control the
total IO rates across all cores, which may easily lead to QoS degradation of
other cores due to excessive merge rates of a particular core.
Although {{RateLimiter}} parameters can be dynamically adjusted, this
functionality is not exposed, and there's no global control mechanism to ensure
"fairness" of allocation of available IO (which is limited) between competing
cores.
In terms of the proposed API this scenario would work as follows:
* a global resource pool "mergeIOPool" is created with a single hard limit
{{maxMBPerSec}}, which is picked based on a fraction of the available hardware
capabilities that still provides acceptable performance.
* this pool knows how to manage components of a "mergeIO" type. It monitors
their current resource usage (using {{SolrIndexWriter}} metrics) and knows how
to adjust each core's {{ioThrottle}}. This logic is encapsulated in
{{MergeIOManagerPlugin}} (doesn't exist yet).
* all {{SolrIndexWriter}}-s in all cores register themselves in this pool for
the purpose of managing their "mergeIO" aspect.
The rest of the scenario is similar to the Story 1. As a result of the plugin's
adjustments the merge IO rate of some of the cores may be decreased / increased
according to the available pool of total IO.
> Create resource management API
> ------------------------------
>
> Key: SOLR-13579
> URL: https://issues.apache.org/jira/browse/SOLR-13579
> Project: Solr
> Issue Type: New Feature
> Security Level: Public(Default Security Level. Issues are Public)
> Reporter: Andrzej Bialecki
> Assignee: Andrzej Bialecki
> Priority: Major
> Attachments: SOLR-13579.patch, SOLR-13579.patch, SOLR-13579.patch,
> SOLR-13579.patch, SOLR-13579.patch
>
>
> Resource management framework API supporting the goals outlined in SOLR-13578.
--
This message was sent by Atlassian JIRA
(v7.6.14#76016)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]