Przeglądaj źródła

perf(query): Align start/end times with step

Range queries will now have their start and end times aligned with the
step. This will help metric stores take better advantage of caches for
queries. See
(https://promlabs.com/blog/2020/06/18/the-anatomy-of-a-promql-query#range-queries)
for details on range queries.

- closes #1472

Signed-off-by: pokom <mark.poko@grafana.com>
pokom 3 lat temu
rodzic
commit
ef27ef8d06
1 zmienionych plików z 16 dodań i 0 usunięć
  1. 16 0
      pkg/prom/query.go

+ 16 - 0
pkg/prom/query.go

@@ -258,9 +258,18 @@ func (ctx *Context) query(query string, t time.Time) (interface{}, v1.Warnings,
 	return toReturn, warnings, nil
 	return toReturn, warnings, nil
 }
 }
 
 
+// isRequestStepAligned will check if the start and end times are aligned with the step
+func (ctx *Context) isRequestStepAligned(start, end time.Time, step time.Duration) bool {
+	return start.Unix()%step.Milliseconds() == 0 && end.Unix()%step.Milliseconds() == 0
+}
+
 func (ctx *Context) QueryRange(query string, start, end time.Time, step time.Duration) QueryResultsChan {
 func (ctx *Context) QueryRange(query string, start, end time.Time, step time.Duration) QueryResultsChan {
 	resCh := make(QueryResultsChan)
 	resCh := make(QueryResultsChan)
 
 
+	if !ctx.isRequestStepAligned(start, end, step) {
+		start, end = ctx.alignWindow(start, end, step)
+	}
+
 	go runQueryRange(query, start, end, step, ctx, resCh, "")
 	go runQueryRange(query, start, end, step, ctx, resCh, "")
 
 
 	return resCh
 	return resCh
@@ -357,6 +366,7 @@ func (ctx *Context) RawQueryRange(query string, start, end time.Time, step time.
 
 
 func (ctx *Context) queryRange(query string, start, end time.Time, step time.Duration) (interface{}, v1.Warnings, error) {
 func (ctx *Context) queryRange(query string, start, end time.Time, step time.Duration) (interface{}, v1.Warnings, error) {
 	body, err := ctx.RawQueryRange(query, start, end, step)
 	body, err := ctx.RawQueryRange(query, start, end, step)
+
 	if err != nil {
 	if err != nil {
 		return nil, nil, err
 		return nil, nil, err
 	}
 	}
@@ -382,6 +392,12 @@ func (ctx *Context) queryRange(query string, start, end time.Time, step time.Dur
 	return toReturn, warnings, nil
 	return toReturn, warnings, nil
 }
 }
 
 
+func (ctx *Context) alignWindow(start time.Time, end time.Time, step time.Duration) (time.Time, time.Time) {
+	alignedStart := (start.Unix() / step.Milliseconds()) * start.Unix()
+	alignedEnd := (end.Unix() / step.Milliseconds()) * end.Unix()
+	return time.UnixMilli(alignedStart), time.UnixMilli(alignedEnd)
+}
+
 // Extracts the warnings from the resulting json if they exist (part of the prometheus response api).
 // Extracts the warnings from the resulting json if they exist (part of the prometheus response api).
 func warningsFrom(result interface{}) v1.Warnings {
 func warningsFrom(result interface{}) v1.Warnings {
 	var warnings v1.Warnings
 	var warnings v1.Warnings