From 7519b96bb7a04a78c3ca2215a6e81dd89556fc19 Mon Sep 17 00:00:00 2001 From: Anton Timofieiev Date: Thu, 22 Oct 2026 09:39:28 +0200 Subject: [PATCH] perf: enable backend and render optimizations by default --- README.md | 24 +++++++++++++++++++-- pkg/app/carbonapi/app.go | 4 ++-- pkg/backend/net/net.go | 6 +++--- pkg/backend/net/net_test.go | 31 +++++++++++++++++++++++++++ pkg/backend/net/stream_render_test.go | 10 +++++++++ 5 files changed, 68 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 521cd570..1d365f21 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,8 @@ Remove `.build/zlib-ng` (or run `make clean`) to rebuild the dependency. `make build TAGS='-tags cairo,nativegzip'` retains system-zlib decoding. `make nocairo` retains the portable Go decoder without either native dependency. -The existing `CARBONAPI_NATIVE_GZIP` and `CARBONAPI_STREAM_RENDER` startup flags -still control use of native backend decoding. +Backend streaming and native gzip decoding are enabled by default. Builds without +native gzip support use the portable Go decoder automatically. To build the binaries with debug symbols, run: @@ -61,6 +61,26 @@ interested in those. ## Run +The following performance paths are enabled by default. No environment overrides +are needed to enable them. Set an individual variable to `0` before starting the +process to use its previous path; unset, empty and `1` all leave it enabled. + +| Environment variable | Default path | Path with `0` | +| --- | --- | --- | +| `CARBONAPI_SYNC_BACKEND_HTTP` | Synchronous backend HTTP transport | Go HTTP transport | +| `CARBONAPI_STREAM_RENDER` | Stream backend render responses | Buffer responses before decoding | +| `CARBONAPI_NATIVE_GZIP` | Native backend gzip decoder, when built in | Go gzip decoder | +| `CARBONAPI_PACK_BACKEND_POINTS` | Packed backend points for replica merging | Separate values and absence arrays | +| `CARBONAPI_STABLE_RENDER_BATCH` | Stable groups when render batching is configured | Previous render batching | + +These switches retain their existing scope: native gzip requires a native-enabled +build, packed points require streaming, and stable batching follows the configured +globbing mode and batch size. Changing a switch requires a process restart. + +When removing existing `=1` overrides from a service manager, first deploy a binary +with these defaults. Restore the overrides before rolling back to an older binary +if the optimized paths should remain enabled. + Run the full stack `carbonapi` -> `zipper` -> `go-carbon` with: ``` diff --git a/pkg/app/carbonapi/app.go b/pkg/app/carbonapi/app.go index 35b202b9..33703e37 100644 --- a/pkg/app/carbonapi/app.go +++ b/pkg/app/carbonapi/app.go @@ -79,7 +79,7 @@ func New(config cfg.API, lg *zap.Logger, buildVersion string) (*App, error) { ms := newPrometheusMetrics(config) app := &App{ config: config, - stableRenderBatch: os.Getenv("CARBONAPI_STABLE_RENDER_BATCH") == "1", + stableRenderBatch: os.Getenv("CARBONAPI_STABLE_RENDER_BATCH") != "0", queryCache: cache.NullCache{}, findCache: cache.NullCache{}, defaultTimeZone: time.Local, @@ -333,7 +333,7 @@ func InitBackends(config cfg.Zipper, zms *ZipperPrometheusMetrics, ms *Prometheu KeepAlive: config.KeepAliveInterval, }).DialContext, } - if os.Getenv("CARBONAPI_SYNC_BACKEND_HTTP") == "1" { + if os.Getenv("CARBONAPI_SYNC_BACKEND_HTTP") != "0" { client.Transport = bnet.NewSyncTransport(client.Transport.(*http.Transport)) } diff --git a/pkg/backend/net/net.go b/pkg/backend/net/net.go index 64e6f78a..9c816260 100644 --- a/pkg/backend/net/net.go +++ b/pkg/backend/net/net.go @@ -128,9 +128,9 @@ func New(cfg Config) (*NetBackend, error) { b.client = http.DefaultClient } b.requestGzip = transportCompresses(b.client) - b.streamRender = os.Getenv("CARBONAPI_STREAM_RENDER") == "1" - b.nativeGzip = os.Getenv("CARBONAPI_NATIVE_GZIP") == "1" - b.packRender = os.Getenv("CARBONAPI_PACK_BACKEND_POINTS") == "1" + b.streamRender = os.Getenv("CARBONAPI_STREAM_RENDER") != "0" + b.nativeGzip = os.Getenv("CARBONAPI_NATIVE_GZIP") != "0" + b.packRender = os.Getenv("CARBONAPI_PACK_BACKEND_POINTS") != "0" b.responsesCount = cfg.Responses diff --git a/pkg/backend/net/net_test.go b/pkg/backend/net/net_test.go index 0de9bad4..39bad5fc 100644 --- a/pkg/backend/net/net_test.go +++ b/pkg/backend/net/net_test.go @@ -7,11 +7,42 @@ import ( "net/http" "net/http/httptest" "net/url" + "os" "strings" "testing" "time" ) +func TestPerformanceDefaultsAndIndependentOptOuts(t *testing.T) { + flags := []string{"CARBONAPI_STREAM_RENDER", "CARBONAPI_NATIVE_GZIP", "CARBONAPI_PACK_BACKEND_POINTS"} + for _, flag := range flags { + t.Setenv(flag, "") + if err := os.Unsetenv(flag); err != nil { + t.Fatal(err) + } + } + for _, disabled := range append([]string{""}, flags...) { + t.Run("disabled="+disabled, func(t *testing.T) { + if disabled != "" { + t.Setenv(disabled, "0") + } + b, err := New(Config{Address: "localhost:8080"}) + if err != nil { + t.Fatal(err) + } + for flag, enabled := range map[string]bool{ + flags[0]: b.streamRender, + flags[1]: b.nativeGzip, + flags[2]: b.packRender, + } { + if enabled != (flag != disabled) { + t.Errorf("%s enabled=%v with %s disabled", flag, enabled, disabled) + } + } + }) + } +} + func TestAddress(t *testing.T) { b, err := New(Config{ Address: "localhost:8080", diff --git a/pkg/backend/net/stream_render_test.go b/pkg/backend/net/stream_render_test.go index efc45f2e..6c1652b9 100644 --- a/pkg/backend/net/stream_render_test.go +++ b/pkg/backend/net/stream_render_test.go @@ -169,11 +169,21 @@ func TestStreamingRenderMatchesBuffered(t *testing.T) { if err != nil { t.Fatal(err) } + base.streamRender = false // Keep the buffered decoder as the reference. request := types.NewRenderRequest([]string{"fixture.*"}, 0, 1) want, err := base.Render(context.Background(), request) if err != nil { t.Fatal(err) } + defaults, err := New(Config{Address: srv.URL}) + if err != nil { + t.Fatal(err) + } + got, err := defaults.Render(context.Background(), request) + if err != nil { + t.Fatal(err) + } + equalStreamResults(t, got, want) for _, native := range []bool{false, true} { be, err := New(Config{Address: srv.URL}) if err != nil {