Elasticsearch version (Verified on 6.8 and 7.4.2):
Description of the problem including expected versus actual behavior :
I was exploring the FilterAllocationDecider behavior with cluster.routing.allocation.exclude setting, specially how the updates of these setting group works. I found that the behavior is not as per my expectation and think it is a bug in ES.
Let's say there are 2 attributes "attr_1" and "attr_2" for which we want to put the exclusion filter for FilterAllocationDecider to consider. FilterAllocationDecider has a consumer registered for the settings in cluster.routing.allocation.exclude group. The expectation is with each update setting request for this group, the clusterExcludeFilters in FilterAllocationDecider will be updated such that keeps all the exclusion applied so far. However, it looks like it only keeps the difference in previous and current settings for this group.
Steps to reproduce :
Case 1:
- Request 1: set the value of only "attr_1" to be "1"
- Verified
clusterExcludeFilter
inFilterAllocationDecider
has key: "attr_1" with value: "1"
- Verified
- Request 2: set the value of only "attr_2" to be "abc"
- Expectation is
clusterExcludeFilter
inFilterAllocationDecider
will have 2 keys "attr_1" and "attr_2" with value "1" and "abc" respectively. However, the second request removes the first key "attr_1" and only keep the second key "attr_2" in theclusterExcludeFilter
- Expectation is
Case 2:
- Request 1: set the value of "attr_1" to be "1" and "attr_2" to be "abc"
- Verified
clusterExcludeFilter
inFilterAllocationDecider
has key: "attr_1" with value: "1" and key "attr_2" with value: "abc"
- Verified
- Request 2: set the value of "attr_1" to be "1" and "attr_2" to be "def"
- Expectation is
clusterExcludeFilter
inFilterAllocationDecider
will have 2 keys "attr_1" and "attr_2" with value "1" and "def" respectively. However, the second request removes the first key "attr_1" and only keep the second key "attr_2" with value "def" in theclusterExcludeFilter
- Expectation is
I have created a test here for various scenarios showing the behavior:
Details:
For cluster.routing.allocation.exclude setting the FilterAllocationDecider registers a setting updater created using newAffixMapUpdater. This updater checks for the difference in settings for this group between current and previous settings and calls the consumer with the diff of the setting. There is a local result map which is populated with the changed setting and passed to the consumer here.
Proposal:
- The result map in the
newAffixMapUpdater
should be a member variable rather than local variable, so that it keeps all the changed settings so far and always return that to the consumer. -
FilterAllocationDecider
keeps adding/updating the settings as and when updated instead of reinitializing the new DiscoveryNodeFilters for each setting update