Skip to content

Commit 2ad1cca

Browse files
committed
Refactor sendGlobsAsIs
We have 3 parameters: sendGlobsAsIs: true|false alwaysSendGlobsAsIs: true|false maxBatchSize: int Their logic is convoluted sendGlobsAsIs in true is working together with maxBatchSize carbonapi is sending a find request and depending on amount of metrics returned from stores acts differently: if amount of metrics is lower than maxBatchSize it sends request as is with globs if amount of metrics is higher it uses list of metrics returned from find and query them one by one sendGlobsAsIs in false is always sending find and ignoring maxBatchSize alwaysSendGlobsAsIs is neglecting sendGlobsAsIs settings and always send a render request without 'find' This commit is deprecating sendGlobsAsIs maxBatchSize and alwaysSendGlobsAsIs in favor of resolveGlobs: int resolveGlobs: = 0 -> send render query as it is resolveGlobs: = 1 -> then send find request and send render for every metric separately resolveGlobs: > 1 -> send find query and if: count of metrics < resolveGlobs - send render as it is count of metrics > resolveGlobs - send render query for each metric returned from the find query Close #33
1 parent 590f595 commit 2ad1cca

File tree

4 files changed

+43
-43
lines changed

4 files changed

+43
-43
lines changed

app/carbonapi/http_handlers.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@ import (
55
"context"
66
"encoding/json"
77
"fmt"
8-
"github.com/bookingcom/carbonapi/pkg/handlerlog"
9-
"go.uber.org/zap/zapcore"
108
"net/http"
119
"runtime/debug"
1210
"strconv"
1311
"strings"
1412
"sync/atomic"
1513
"time"
1614

15+
"github.com/bookingcom/carbonapi/pkg/handlerlog"
16+
"go.uber.org/zap/zapcore"
17+
1718
"github.com/bookingcom/carbonapi/carbonapipb"
1819
"github.com/bookingcom/carbonapi/date"
1920
"github.com/bookingcom/carbonapi/expr"
@@ -164,7 +165,7 @@ func (app *App) renderHandler(w http.ResponseWriter, r *http.Request, logger *za
164165
}
165166
//2xx response code is treated as success
166167
if toLog.HttpCode/100 == 2 {
167-
if toLog.TotalMetricCount < int64(app.config.MaxBatchSize) {
168+
if toLog.TotalMetricCount < int64(app.config.ResolveGlobs) {
168169
app.prometheusMetrics.RenderDurationExpSimple.Observe(time.Since(t0).Seconds())
169170
app.prometheusMetrics.RenderDurationLinSimple.Observe(time.Since(t0).Seconds())
170171
} else {
@@ -700,11 +701,11 @@ func (app *App) renderWriteBody(results []*types.MetricData, form renderForm, r
700701
}
701702

702703
func (app *App) sendGlobs(glob dataTypes.Matches) bool {
703-
if app.config.AlwaysSendGlobsAsIs {
704+
if app.config.ResolveGlobs == 0 {
704705
return true
706+
} else {
707+
return len(glob.Matches) < app.config.ResolveGlobs
705708
}
706-
707-
return app.config.SendGlobsAsIs && len(glob.Matches) < app.config.MaxBatchSize
708709
}
709710

710711
func (app *App) resolveGlobsFromCache(metric string) (dataTypes.Matches, error) {
@@ -759,7 +760,7 @@ func (app *App) resolveGlobs(ctx context.Context, metric string, useCache bool,
759760

760761
func (app *App) getRenderRequests(ctx context.Context, m parser.MetricRequest, useCache bool,
761762
toLog *carbonapipb.AccessLogDetails) ([]string, error) {
762-
if app.config.AlwaysSendGlobsAsIs {
763+
if app.config.ResolveGlobs == 0 {
763764
return []string{m.Metric}, nil
764765
}
765766
if !strings.ContainsAny(m.Metric, "*{") {
@@ -813,7 +814,7 @@ func (app *App) findHandler(w http.ResponseWriter, r *http.Request, logger *zap.
813814
logLevel := zap.InfoLevel
814815
defer func() {
815816
if toLog.HttpCode/100 == 2 {
816-
if toLog.TotalMetricCount < int64(app.config.MaxBatchSize) {
817+
if toLog.TotalMetricCount < int64(app.config.ResolveGlobs) {
817818
app.prometheusMetrics.FindDurationLinSimple.Observe(time.Since(t0).Seconds())
818819
} else {
819820
app.prometheusMetrics.FindDurationLinComplex.Observe(time.Since(t0).Seconds())

cfg/api.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,7 @@ func DefaultAPIConfig() API {
6060
cfg := API{
6161
Zipper: fromCommon(DefaultCommonConfig()),
6262

63-
SendGlobsAsIs: false,
64-
AlwaysSendGlobsAsIs: false,
65-
MaxBatchSize: 100,
63+
ResolveGlobs: 100,
6664
Cache: CacheConfig{
6765
Type: "mem",
6866
DefaultTimeoutSec: 60,
@@ -86,9 +84,7 @@ type API struct {
8684

8785
// TODO (grzkv): Move backends list to a single backend here
8886

89-
SendGlobsAsIs bool `yaml:"sendGlobsAsIs"`
90-
AlwaysSendGlobsAsIs bool `yaml:"alwaysSendGlobsAsIs"`
91-
MaxBatchSize int `yaml:"maxBatchSize"`
87+
ResolveGlobs int `yaml:"resolveGlobs"`
9288
Cache CacheConfig `yaml:"cache"`
9389
TimezoneString string `yaml:"tz"`
9490
PidFile string `yaml:"pidFile"`

cfg/api_test.go

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ graphite:
3131
prefix: "carbon.api"
3232
pattern: "{prefix}.{fqdn}"
3333
34-
maxBatchSize: 100
35-
sendGlobsAsIs: true
34+
resolveGlobs: 100
35+
3636
cache:
3737
type: "memcache"
3838
size_mb: 0
@@ -87,9 +87,7 @@ loggerConfig:
8787
},
8888
},
8989

90-
SendGlobsAsIs: true,
91-
AlwaysSendGlobsAsIs: false,
92-
MaxBatchSize: 100,
90+
ResolveGlobs: 100,
9391
Cache: CacheConfig{
9492
Type: "memcache",
9593
Size: 0,
@@ -125,8 +123,7 @@ cache:
125123
- host2:1234
126124
cpus: 16
127125
tz: "UTC+1,3600"
128-
sendGlobsAsIs: true
129-
maxBatchSize: 100
126+
resolveGlobs: 100
130127
ignoreClientTimeout: true
131128
graphite:
132129
host: "localhost:3002"
@@ -190,9 +187,7 @@ loggerConfig:
190187
},
191188
},
192189

193-
SendGlobsAsIs: true,
194-
AlwaysSendGlobsAsIs: false,
195-
MaxBatchSize: 100,
190+
ResolveGlobs: 100,
196191
Cache: CacheConfig{
197192
Type: "memcache",
198193
Size: 0,

config/carbonapi.yaml

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,29 +29,37 @@ cache:
2929
- "127.0.0.1:11211"
3030
# Amount of CPUs to use. 0 - unlimited
3131
cpus: 0
32-
#graphiteWeb: "graphiteWeb.example.yaml"
32+
3333
# Timezone, default - local
3434
tz: ""
35-
# If 'true', carbonapi will send requests as is, with globs and braces
36-
# Otherwise for each request it will generate /metrics/find and then /render
37-
# individual metrics.
38-
# true --- faster, but will cause carbonzipper to consume much more RAM.
39-
#
40-
# For some backends (e.x. graphite-clickhouse) this *MUST* be set to true in order
41-
# to get reasonable performance
35+
36+
# Deprecated and removed:
37+
# sendGlobsAsIs: true|false
38+
# alwaysSendGlobsAsIs: true|false
39+
# maxBatchSize: int
40+
# Migration path
41+
# alwaysSendGlobsAsIs: true -> resolveGlobs: 0
42+
# sendGlobsAsIs: false -> resolveGlobs: 1
43+
# sendGlobsAsIs: true && maxBatchSize: int -> resolveGlobs: int
44+
45+
resolveGlobs: 100
46+
# = 0 - faster (no 'find in advance', direct render)
47+
# = 1 - slower (always 'find in advance' and every metric rendered individually)
48+
# > 1 - slower (always 'find in advance' and then render strategy depend on amount of metrics)
49+
# If resolveGlobs is = 0 (zero) then /metrics/find request won't be send and a query will be passed
50+
# to a /render as it is.
4251
#
43-
# For go-carbon --- it depends on how you use it.
44-
sendGlobsAsIs: true
45-
# If sendGlobsAsIs is set and resulting response will be larger than maxBatchSize
46-
# carbonapi will revert to old behavir. This allows you to use benifits of passing
47-
# globs as is but keep memory usage in sane limits.
52+
# If resolveGlobs is = 1 (zero) then send /metrics/find request and send /render for every metric separately
4853
#
49-
# For go-carbon you might want it to keep in some reasonable limits, 100 is good "safe" defaults
54+
# If resolveGlobs is set > 1 (one) then carbonapi will send a /metrics/find request and it will check
55+
# the resulting response if it contain more than resolveGlobs metrics
56+
# If find returns MORE metrics than resolveGlobs - carbonapi will query metrics one by one
57+
# If find returns LESS metrics than resolveGlobs - revert to the old behaviour and send the query as it is.
58+
# This allows you to use benifits of passing globs as is but keep memory usage in carbonzipper within sane limits.
5059
#
51-
# For some backends (e.x. graphite-clickhouse) you might want to set it to some insanly high value, like 100000
52-
maxBatchSize: 100
53-
54-
# alwaysSendGlobsAsIs: false
60+
# For go-carbon you might want to keep it in some reasonable limits, 100 is a good "safe" default
61+
# For some backends you might want to set it to 0
62+
# If you noticing carbonzipper OOM then this is a parameter to tune.
5563

5664
# functionsConfigs:
5765
# graphiteWeb: ./graphiteWeb.example.yaml
@@ -77,7 +85,7 @@ upstreams:
7785
# Number of 100ms buckets to track request distribution in. Used to build
7886
# 'carbon.zipper.hostname.requests_in_0ms_to_100ms' metric and friends.
7987
buckets: 10
80-
# maxBatchSize: 200
88+
# resolveGlobs: 200
8189
# concurrencyLimitPerServer: 100
8290
timeouts:
8391
# # Maximum backend request time for find requests.

0 commit comments

Comments
 (0)