Repository navigation
Keep the 1.21 query range and HA failover timeout settings working - #7919
Conversation
cortexproject#7160/cortexproject#7323 moved query_ingesters_within, query_store_after and shuffle_sharding_ingesters_lookback_period from querier to limits, and renamed their flags from -querier.* to -limits.*. cortexproject#7481 moved the ha_tracker_failover_timeout YAML field from distributor.ha_tracker to limits. Neither left the old names in place, so a 1.21 config that uses them fails at startup on 1.22. Restore the old YAML fields and flags as hidden, deprecated settings that are scheduled for removal in v1.24.0. Config.Validate copies a set old value into its limit before the limits are validated and before they become the runtime config defaults, so tenant overrides inherit it. When the old and the new name are both set to different values, startup fails rather than picking one. cortex.New logs a warning and increments deprecated_flags_inuse_total for each one used: Validate runs before the logger is initialised, so a warning logged there is lost. Also correct the -limits.query-ingesters-within help text, which said "less than or equal to" close-idle-tsdb-timeout while cortexproject#7323 rejects equal, and spell out that new startup check in the CHANGELOG. Signed-off-by: Charlie Le <charlie_le@apple.com>
Signed-off-by: Charlie Le <charlie_le@apple.com>
staticcheck (SA1019) flags every read of a field whose doc comment starts with Deprecated:, and cortex.Config reads these to apply them. Other config fields that Cortex still reads, such as MaxExemplars, do not use the marker either. Signed-off-by: Charlie Le <charlie_le@apple.com>
| * [CHANGE] Ingester: Formally deprecate `-blocks-storage.tsdb.max-exemplars`, scheduled for removal in v1.24.0. Use the per-tenant `max_exemplars` limit instead. The flag still works as the global fallback when `max_exemplars` is 0, but setting it now logs a warning and increments `deprecated_flags_inuse_total`. #7793 | ||
| * [CHANGE] Ingester: Graduate native histogram ingestion (`-blocks-storage.tsdb.enable-native-histograms`) from experimental. #7789 | ||
| * [CHANGE] Querier: Make query time range configurations per-tenant: `query_ingesters_within`, `query_store_after`, and `shuffle_sharding_ingesters_lookback_period`. Uses `model.Duration` instead of `time.Duration` to support serialization but has minimum unit of 1ms (nanoseconds/microseconds not supported). #7160 #7323 | ||
| * [CHANGE] Querier: Make query time range configurations per-tenant: `query_ingesters_within`, `query_store_after`, and `shuffle_sharding_ingesters_lookback_period`. Uses `model.Duration` instead of `time.Duration` to support serialization but has minimum unit of 1ms (nanoseconds/microseconds not supported). The settings move from the `querier` block to `limits`, and their flags from `-querier.*` to `-limits.*`. The old YAML fields and flags still work as the defaults for the new limits, but are deprecated and will be removed in v1.24.0: using them logs a warning and increments `deprecated_flags_inuse_total`. Setting an old and a new name to different values fails at startup. #7160 #7323 #7919 |
There was a problem hiding this comment.
| * [CHANGE] Querier: Make query time range configurations per-tenant: `query_ingesters_within`, `query_store_after`, and `shuffle_sharding_ingesters_lookback_period`. Uses `model.Duration` instead of `time.Duration` to support serialization but has minimum unit of 1ms (nanoseconds/microseconds not supported). The settings move from the `querier` block to `limits`, and their flags from `-querier.*` to `-limits.*`. The old YAML fields and flags still work as the defaults for the new limits, but are deprecated and will be removed in v1.24.0: using them logs a warning and increments `deprecated_flags_inuse_total`. Setting an old and a new name to different values fails at startup. #7160 #7323 #7919 | |
| * [CHANGE] Querier: Make query time range configurations per-tenant: `query_ingesters_within`, `query_store_after`, and `shuffle_sharding_ingesters_lookback_period`. Uses `model.Duration` instead of `time.Duration` to support serialization but has minimum unit of 1ms (nanoseconds/microseconds not supported). The settings move from the `querier` block to `limits`, and their flags from `-querier.*` to `-limits.*`. The old YAML fields and flags still work as the defaults for the new limits, but are deprecated and will be removed in v1.24.0: using them logs a warning and increments `deprecated_flags_inuse_total`. Setting the old field and a non-default limit to different values fails at startup. #7160 #7323 #7919 |
Setting an old name and a non-default new limit to different values fails at startup. Isn't it?
There was a problem hiding this comment.
Yes, good catch: as written it only failed when the new limit was at a non-default value. After Friedrich's review the rule changed (7245514), so I reworded the entry instead of taking the suggestion as-is: a command-line flag wins over the YAML file whichever name each uses, and the old and new name have to agree only when both are set in the same place (both in YAML, or both on the command line). The #7481 entry says the same.
| case *d.limit == d.def: | ||
| *d.limit = model.Duration(d.old) | ||
| case time.Duration(*d.limit) != d.old: | ||
| return fmt.Errorf("%s (%s) and the deprecated %s (%s) are both set: remove %s", d.newName, time.Duration(*d.limit), d.oldName, d.old, d.oldName) |
There was a problem hiding this comment.
According to docs cli flags should take precedence over configuration changes. https://cortexmetrics.io/docs/configuration/configuration-file/#:~:text=Cortex%20can%20be,YAML%20config%20file.
I tested this PR locally and I found that if I test:
distributor:
ha_tracker:
ha_tracker_failover_timeout: 45s
with -distributor.ha-tracker.failover-timeout=30s
1.21 uses 30s
while this PR makes it 45s.
There was a problem hiding this comment.
Thanks for testing it, you're right. The fallback compared values, so it couldn't tell an explicit flag at its default value (30s) from no flag at all. Fixed in 7245514: LoadConfig now records which YAML keys are set and main records which flags were passed, and a command-line flag wins over the YAML file whichever name each uses, as in 1.21. Your case is a TestFlagParsing case now. I also compared -print.config against a v1.21.0 build: with the old field at 45s and the flag unset, =30s or =1m, both give 45s / 30s / 1m. The querier settings match 1.21 too (details in the PR description).
The fallback applied a deprecated value whenever the new limit was at its
default, so it could not tell a flag passed explicitly at its default
value from one left unset. With
distributor:
ha_tracker:
ha_tracker_failover_timeout: 45s
and -distributor.ha-tracker.failover-timeout=30s, 1.21 uses 30s, because
a command-line flag overrides the YAML file, while this PR used 45s. The
same happened to an explicit -limits.query-store-after=0 next to an old
querier.query_store_after.
Record where each setting was set instead of comparing values: the YAML
keys from LoadConfig (SetYAMLKeys, next to SetYAMLRootNodeStates) and the
flags passed on the command line (SetCommandLineFlags, after parsing). A
flag on the command line now wins over the YAML file whichever name each
uses, as in 1.21, and the old and new name must agree only when both are
set in the same place. A config built in code has no recorded sources and
keeps the value-based rule.
The deprecated fields are also omitempty, so -print.config and /config
show them only when they are set.
Each case was checked against a v1.21.0 build with -print.config.
Signed-off-by: Charlie Le <charlie_le@apple.com>
friedrichg
left a comment
There was a problem hiding this comment.
Thanks for addressing the comments
…ortexproject#7919) * Keep the 1.21 query range and HA failover timeout settings working cortexproject#7160/cortexproject#7323 moved query_ingesters_within, query_store_after and shuffle_sharding_ingesters_lookback_period from querier to limits, and renamed their flags from -querier.* to -limits.*. cortexproject#7481 moved the ha_tracker_failover_timeout YAML field from distributor.ha_tracker to limits. Neither left the old names in place, so a 1.21 config that uses them fails at startup on 1.22. Restore the old YAML fields and flags as hidden, deprecated settings that are scheduled for removal in v1.24.0. Config.Validate copies a set old value into its limit before the limits are validated and before they become the runtime config defaults, so tenant overrides inherit it. When the old and the new name are both set to different values, startup fails rather than picking one. cortex.New logs a warning and increments deprecated_flags_inuse_total for each one used: Validate runs before the logger is initialised, so a warning logged there is lost. Also correct the -limits.query-ingesters-within help text, which said "less than or equal to" close-idle-tsdb-timeout while cortexproject#7323 rejects equal, and spell out that new startup check in the CHANGELOG. Signed-off-by: Charlie Le <charlie_le@apple.com> * CHANGELOG: reference cortexproject#7919 Signed-off-by: Charlie Le <charlie_le@apple.com> * Drop the Deprecated: marker from the restored config fields staticcheck (SA1019) flags every read of a field whose doc comment starts with Deprecated:, and cortex.Config reads these to apply them. Other config fields that Cortex still reads, such as MaxExemplars, do not use the marker either. Signed-off-by: Charlie Le <charlie_le@apple.com> * Give command-line flags precedence over the deprecated YAML fields The fallback applied a deprecated value whenever the new limit was at its default, so it could not tell a flag passed explicitly at its default value from one left unset. With distributor: ha_tracker: ha_tracker_failover_timeout: 45s and -distributor.ha-tracker.failover-timeout=30s, 1.21 uses 30s, because a command-line flag overrides the YAML file, while this PR used 45s. The same happened to an explicit -limits.query-store-after=0 next to an old querier.query_store_after. Record where each setting was set instead of comparing values: the YAML keys from LoadConfig (SetYAMLKeys, next to SetYAMLRootNodeStates) and the flags passed on the command line (SetCommandLineFlags, after parsing). A flag on the command line now wins over the YAML file whichever name each uses, as in 1.21, and the old and new name must agree only when both are set in the same place. A config built in code has no recorded sources and keeps the value-based rule. The deprecated fields are also omitempty, so -print.config and /config show them only when they are set. Each case was checked against a v1.21.0 build with -print.config. Signed-off-by: Charlie Le <charlie_le@apple.com> --------- Signed-off-by: Charlie Le <charlie_le@apple.com> (cherry picked from commit b6b08e7) Signed-off-by: Charlie Le <charlie_le@apple.com>
Follows review on #7918. That PR documented that 1.22 breaks 1.21 configs that set the query range or HA failover timeout settings in their old location. @friedrichg asked to keep the old stanzas working instead, since these are long-standing settings. This PR does that. It targets master, and I'll backport it to
release-1.22before v1.22.0.What breaks on 1.22 today
query_ingesters_within,query_store_afterandshuffle_sharding_ingesters_lookback_periodfromqueriertolimits, and renamed their flags from-querier.*to-limits.*. The old YAML fails withfield query_store_after not found in type querier.Config, and the old flags fail withflag provided but not defined.ha_tracker_failover_timeoutYAML field fromdistributor.ha_trackertolimits. The flag name did not change. The old YAML fails withfield ha_tracker_failover_timeout not found in type ha.HATrackerConfig.Change
-querier.*flags come back as hidden, deprecated settings (doc:"hidden"), scheduled for removal in v1.24.0.distributor.ha_tracker.ha_tracker_failover_timeoutis YAML-only, because-distributor.ha-tracker.failover-timeoutalready sets the limit.Config.Validatecopies an old value that is set into its limit. This happens before the limits are validated and before they become the runtime-config defaults (SetDefaultLimitsForYAMLUnmarshalling), so tenant overrides inherit it, and the old values go through the sameValidateQueryLimitschecks as the new ones.-distributor.ha-tracker.failover-timeout=30sbeats a deprecateddistributor.ha_tracker.ha_tracker_failover_timeout: 45s, even though 30s is the default.limits.query_store_after (6h0m0s) and the deprecated querier.query_store_after (12h0m0s) are both set: remove querier.query_store_after, or the same with the flag names.LoadConfigrecords the YAML keys that are set (SetYAMLKeys, next to the existingSetYAMLRootNodeStates), andmainrecords the flags passed on the command line (SetCommandLineFlags). AConfigbuilt in code has neither, and counts a setting as set when it is not at its default value.omitempty, so-print.configand/configshow them only when they are set.running with DEPRECATED config querier.query_store_after, use limits.query_store_after instead, it will be removed in v1.24.0and incrementsdeprecated_flags_inuse_total, as Formally deprecate -blocks-storage.tsdb.max-exemplars #7793 does for-blocks-storage.tsdb.max-exemplars. This happens incortex.New, notValidate:maincallsValidatebeforeutil_log.InitLogger, whileutil_log.Loggeris still a no-op logger, so a warning logged there is dropped.-limits.query-ingesters-withinhelp text said "less than or equal to close-idle-tsdb-timeout", while making query ingesters config per tenant #7323 rejects equal. It now says "less than".config-file-reference.mdand the JSON schema are regenerated; that string is their only change.query_ingesters_within < close_idle_tsdb_timeoutstartup check, which was approved on Backport #7919 to release-1.22 #7918 as a correctness fix.Testing
TestConfigValidation_DeprecatedLimitscovers the old YAML, the old flags, the HA field, old and new equal, old and new different (both kinds), and an old pair that failsValidateQueryLimits.go test ./pkg/cortex/ ./pkg/ha/ ./pkg/querier/andgo vetpass. Regenerated docs and schema match.TestFlagParsingrunsmain()with the HA case from review: deprecated YAML field 45s plus-distributor.ha-tracker.failover-timeout=30snow gives 30s. Reverting to the value-based rule fails it, along with the three command-line precedence unit tests.-print.configagainst av1.21.0build, with an old YAML field 45s and the flag unset,=30sor=1m: 45s, 30s, 1m on both. With a YAMLquerier.query_store_after: 12hand the flag unset,-querier.query-store-after=0or-limits.query-store-after=0: 12h, 0, 0, matching 1.21../cmd/cortexand started it with the three 1.21-style configs that fail onv1.22.0-rc.3: each now passes config validation and logs the deprecation warning. The equalclose_idle_tsdb_timeoutconfig is still rejected.golangci-lintv2.13.1, the version inbuild-image/Dockerfile, built with Go 1.27: 0 issues.