prometheus icon indicating copy to clipboard operation
prometheus copied to clipboard

PromQL: Dot in regexp should also match newlines (which is less surprising to most users and also allows optimising the `.* `regexp)

Open Betula-L opened this issue 5 years ago • 28 comments

What did you do?

I found that wildcard label matcher such as app=~".*" impact on query performance significantly.

Then i tried to edit benchmark BenchmarkPostingsForMatchers as followed,

image

The results is amazing!!!

The time consumption with wildcard is worser 100K times than without wildcard.

BenchmarkPostingsForMatchers/Head/n="1",i=~".*",j="foo"-16                     5         213092008 ns/op
BenchmarkPostingsForMatchers/Head/n="1",j="foo"-16                        593829              1838 ns/op

What did you expect to see?

Label matcher {n="1",i=~".*",j="foo} is equal to label matcher {n="1"j="foo}, so the evaluation cost should be similar.

Betula-L avatar Aug 27 '20 08:08 Betula-L

Thank you.

This is equivalent in TSDB but not in PromQL, so the optimization could be done in tsdb. I think it would be great.

roidelapluie avatar Aug 27 '20 08:08 roidelapluie

Waiting for a tsdb maintainer to set P3 on this if they also find this useful.

roidelapluie avatar Aug 27 '20 08:08 roidelapluie

in promql:

  • we need to send the matcher to remote reads
  • absent(foo{i=~".*",i="a"}) returns {} 1 and absent(foo{i="a"}) returns {i="a"} 1

roidelapluie avatar Aug 27 '20 08:08 roidelapluie

Yeah it would be nice to have. We could also do it for .+.

codesome avatar Aug 27 '20 09:08 codesome

Didn't @pracucci made such optimizations already?

roidelapluie avatar Aug 27 '20 09:08 roidelapluie

I have found cef4dd6fff06198c61007211be460fb83cd708c1 and 2f6bf7de4c41015a9adeeb3e544766d61ec865eb.

roidelapluie avatar Aug 27 '20 09:08 roidelapluie

That was for individual regex matchers

codesome avatar Aug 27 '20 09:08 codesome

May i pick up this issue?

I wonder that maybe i can take part into prometheus contribution.

Betula-L avatar Aug 27 '20 12:08 Betula-L

This is equivalent in TSDB but not in PromQL, so the optimization could be done in tsdb. I think it would be great.

I think we tried to do this optimisation in the past, but have been told by @brian-brazil that it's not safe to just skip it because of label values with newlines.

pracucci avatar Aug 27 '20 12:08 pracucci

Yes, this is not a safe optimisation.

brian-brazil avatar Aug 27 '20 12:08 brian-brazil

I remember now indeed :)

roidelapluie avatar Aug 27 '20 12:08 roidelapluie

It seems that we should use !="" rather use .* or .+ in the most situations now.

Betula-L avatar Aug 28 '20 03:08 Betula-L

It seems that we should use !="" rather use .* or .+ in the most situations now.

If you're currently using app=~".*" it also matches metrics without the app label at all. On the contrary, if you use app!="" it will not match metrics without the app label. The two label selectors are not the same thing.

pracucci avatar Aug 28 '20 09:08 pracucci

Hrm, we've discussed this before and even sent a PR for this: https://github.com/prometheus/prometheus/pull/6996

This is not a safe optimisation with the current model, but something to consider for Prometheus 3.0. Will add this to the dev summit agenda and report back once we discuss this further!

gouthamve avatar Aug 31 '20 14:08 gouthamve

my 2 cents on this.

There's a LOT of wasted CPU for this because a lot of people uses Grafana variables and when they want to match all they use .* or even .+ I get the point of compatibility, but I'm sure no one is relying on .* to match all but newlines.

I'm sure someone is using label values with newlines, does he expect to not matches his label when he does .* ? I'd be surprised.

Honestly if we could count for how much money wasted in total across all companies in the world this does, I'm sure you'll change your mind.

cyriltovena avatar Oct 06 '21 14:10 cyriltovena

allv It seems that grafana could change the "default auto" to be (?s:.*) and (?s:.+), then we can optimize for these in tsdb.

roidelapluie avatar Oct 06 '21 15:10 roidelapluie

Another idea would be to change the prometheus default anchor behind a feature flag and optimize for (?s:.*) and (?s:.+) in tsdb as well, but the user would still type =~".*".

roidelapluie avatar Oct 06 '21 15:10 roidelapluie

I'm really wondering how many Prometheus users are aware that .* or .+ doesn't match if the label value contains a newline. I believe the expected behaviour is that it would match "whatever" the label value is. I'm wondering if what we keep considering it a breaking change (a change to have label values with newlines matching .*) may actually be a bug fix for the final Prometheus user, and so we could treat it as such :)

pracucci avatar Oct 06 '21 16:10 pracucci

allv

It seems that grafana could change the "default auto" to be (?s:.*) and (?s:.+), then we can optimize for these in tsdb.

For sure

cyriltovena avatar Oct 06 '21 16:10 cyriltovena

As I said, I am open to change the default anchoring based on a feature flag, and optimize anyway in TSDB for the correct anchoring.

roidelapluie avatar Oct 06 '21 16:10 roidelapluie

I think this is still worth tackling. @roidelapluie which way do we prefer more:

  1. A feature flag to match .* and .+ and handle them differently when matching postings?
  2. A feature flag to change default anchor. For this option just want to double check, now we are using ^(?:)$. Do we change this to (?s:) and no need to keep ^$?

I feel option 1 is easier.

yeya24 avatar Aug 27 '23 16:08 yeya24

But only option 2 is correct.

roidelapluie avatar Aug 27 '23 17:08 roidelapluie

But only option 2 is correct.

Yes. Option 1 changes the behavior but it is something acceptable depending on the usecase. If no usecase to have new line in values then option 1 should be sufficient?

yeya24 avatar Aug 27 '23 18:08 yeya24

I think ignoring newlines matches the expectation of most users of Prometheus.

bboreham avatar Aug 27 '23 18:08 bboreham

The plan was always correctness, so I don't see an issue with option 2. What would be wrong with it?

roidelapluie avatar Aug 28 '23 05:08 roidelapluie

At some point i was playing around with the FastRegexMatcher to optimize those regex: https://github.com/alanprot/prometheus/commit/bc168724872dddee212415502d26da72401528d7#diff-c6bfdf5ae2a5edbc3df844f48f297e4d2a4f4106662f1a04c8931fbb38f1fdae

Idk if this is something we wanna pursue.

alanprot avatar Sep 05 '23 17:09 alanprot

Hello from the Bug Scrub!

I think ignoring newlines matches the expectation of most users of Prometheus.

Sounds like @gouthamve comment is still relevant. Prometheus 3.0 coordinators, was this issue discussed already? We updated title as well.

It feels 9X.X% of users would likely be OK with this optimization, so let's decide what we want for Prometheus 3.0 (personally I think we should break it explicitly)

bwplotka avatar May 14 '24 11:05 bwplotka

Note the related #8525.

beorn7 avatar May 16 '24 09:05 beorn7

@marioferh is working on this

jan--f avatar Jul 18 '24 12:07 jan--f

Yeah it would be nice to have. We could also do it for .+.

I've been trying to optimize also .+ but not sure how to do it. Any ideas?

marioferh avatar Jul 26 '24 10:07 marioferh