Skip to content

Add projectionHint to SG Parquet mode - #7206

Open
SungJin1212 wants to merge 5 commits into
cortexproject:masterfrom
SungJin1212:Add-ProjectionHints-to-SG
Open

SungJin1212 wants to merge 5 commits into
cortexproject:masterfrom
SungJin1212:Add-ProjectionHints-to-SG

Conversation

@SungJin1212

@SungJin1212 SungJin1212 commented Jan 13, 2026 •

Copy link
Copy Markdown
Member

This PR adds -blocks-storage.bucket-store.honor-projection-hints CLI flag. If enabled, Store Gateway in Parquet mode will honor projection hints and only materialize requested labels.

The benchmark results

goos: darwin
goarch: arm64
pkg: github.com/cortexproject/cortex/pkg/storegateway
cpu: Apple M4 Max
BenchmarkParquetBucketStore_ProjectionHints
BenchmarkParquetBucketStore_ProjectionHints/series_100
BenchmarkParquetBucketStore_ProjectionHints/series_100/without_projection_hints
BenchmarkParquetBucketStore_ProjectionHints/series_100/without_projection_hints-14         	    1671	    776046 ns/op	  480315 B/op	    4336 allocs/op
BenchmarkParquetBucketStore_ProjectionHints/series_100/with_projection_hints
BenchmarkParquetBucketStore_ProjectionHints/series_100/with_projection_hints-14            	    1904	    597504 ns/op	  395957 B/op	    3969 allocs/op
BenchmarkParquetBucketStore_ProjectionHints/series_1000
BenchmarkParquetBucketStore_ProjectionHints/series_1000/without_projection_hints
BenchmarkParquetBucketStore_ProjectionHints/series_1000/without_projection_hints-14        	     585	   1745712 ns/op	 3887004 B/op	   29645 allocs/op
BenchmarkParquetBucketStore_ProjectionHints/series_1000/with_projection_hints
BenchmarkParquetBucketStore_ProjectionHints/series_1000/with_projection_hints-14           	     759	   1648167 ns/op	 2916027 B/op	   27443 allocs/op
BenchmarkParquetBucketStore_ProjectionHints/series_10000
BenchmarkParquetBucketStore_ProjectionHints/series_10000/without_projection_hints
BenchmarkParquetBucketStore_ProjectionHints/series_10000/without_projection_hints-14       	     100	  10303832 ns/op	37756795 B/op	  282501 allocs/op
BenchmarkParquetBucketStore_ProjectionHints/series_10000/with_projection_hints
BenchmarkParquetBucketStore_ProjectionHints/series_10000/with_projection_hints-14          	      97	  11581134 ns/op	28394294 B/op	  262156 allocs/op
PASS

Process finished with the exit code 0

Which issue(s) this PR fixes:
Fixes #

Checklist

  • Tests updated
  • Documentation added
  • CHANGELOG.md updated - the order of entries should be [CHANGE], [FEATURE], [ENHANCEMENT], [BUGFIX]

Comment thread pkg/storage/tsdb/config.go Outdated
f.Float64Var(&cfg.TokenBucketBytesLimiter.TouchedChunksTokenFactor, "blocks-storage.bucket-store.token-bucket-bytes-limiter.touched-chunks-token-factor", 1, "Multiplication factor used for touched chunks token")
f.IntVar(&cfg.MatchersCacheMaxItems, "blocks-storage.bucket-store.matchers-cache-max-items", 0, "Maximum number of entries in the regex matchers cache. 0 to disable.")
cfg.ParquetShardCache.RegisterFlagsWithPrefix("blocks-storage.bucket-store.", f)
f.BoolVar(&cfg.HonorProjectionHints, "blocks-storage.bucket-store.honor-projection-hints", false, "[Experimental] If enabled, Store Gateway will honor projection hints and only materialize requested labels. It is only effect when `-blocks-storage.bucket-store.bucket-store-type` is a parquet.")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is parquet Remove a.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to double check, if I want to actually use parquet store gateway projection, I need to also honor projection hints in Querier (but not enable parquet querier)?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, even if the Parquet Querier is disabled (using the standard Querier), the Parquet Store Gateway relies on these hints to perform projection pushdown (Querier send the projection hints).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems that even if we don't enable honor projection hints in querier, it still propagates projection hints to store gateway. I don't see you enable that in the integration test.

storageHints.ProjectionLabels = queryHints.ProjectionLabels

// Reset projection hints if not all parquet shard have the hash column.
if !allParquetBlocksHaveHashColumn(shards) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should only project if it is projection include. Add that check first can avoid checking all blocks of hash column when unnecessary

Comment thread integration/querier_test.go Resolved
Comment thread integration/querier_test.go Outdated
vec := aggResult.(model.Vector)
require.Len(t, vec, 1)
require.Equal(t, model.LabelValue("series_1"), vec[0].Metric["series_1"])
require.Equal(t, expectedVector1[0].Value, vec[0].Value)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to avoid adding more test cases to this test.
I think overall the test is very flaky and it keeps failing for different reasons. I would prefer separate tests for parquet store gateway mode tbh.

storageHints.ProjectionInclude = false
storageHints.ProjectionLabels = nil
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also reset the projection hints if it is not projection include. Same as what we do in querier.

if !sp.ProjectionInclude || q.distributor.UseQueryable(q.now, mint, maxt) {

If we don't do this then it can do wrong below as we only add series hash if it is projection include. In general it is hard to estimate the cost of projection not include and it can be more expensive

@SungJin1212
SungJin1212 force-pushed the Add-ProjectionHints-to-SG branch from 903d00e to d9638cc Compare January 15, 2026 07:01
@SungJin1212

Copy link
Copy Markdown
Member Author

@yeya24
I have applied the fix and added dedicated test code.

@SungJin1212
SungJin1212 requested a review from yeya24 January 22, 2026 01:47
@SungJin1212
SungJin1212 force-pushed the Add-ProjectionHints-to-SG branch 2 times, most recently from 6e47284 to 1c9539b Compare February 16, 2026 04:37
@SungJin1212
SungJin1212 force-pushed the Add-ProjectionHints-to-SG branch from 9f5b844 to d860aff Compare March 3, 2026 04:36
@SungJin1212
SungJin1212 force-pushed the Add-ProjectionHints-to-SG branch 3 times, most recently from 8b10151 to f033993 Compare April 27, 2026 08:24
@SungJin1212
SungJin1212 force-pushed the Add-ProjectionHints-to-SG branch 5 times, most recently from b20e2e2 to a2b1d29 Compare June 19, 2026 05:47
@SungJin1212
SungJin1212 force-pushed the Add-ProjectionHints-to-SG branch from b45fb3f to 30437f2 Compare October 6, 2026 11:34
@SungJin1212
SungJin1212 requested a review from a team as a code owner October 6, 2026 11:34
@SungJin1212
SungJin1212 force-pushed the Add-ProjectionHints-to-SG branch from 6792a7b to bac13d7 Compare October 12, 2026 02:14

@sandy2008 sandy2008 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. The earlier review points look addressed. I checked that the new TestQuerier_ProjectionHints* and TestParquetBucketStore_* cases fail without the querier and store-gateway changes, and that the generated config reference matches. There's one problem with how the V1 fallback works across multiple store-gateways (inline). The test (arm64) failure is an unrelated port collision in pkg/util/tls/test.

lbls := make([]string, 0, len(queryHints.ProjectionLabels)+1)
storageHints.ProjectionLabels = append(lbls, queryHints.ProjectionLabels...)

if !allParquetBlocksHaveHashColumn(shards) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fallback only sees the blocks this gateway was asked for. The querier sends the same projection hints to every store-gateway, so if one gateway holds a V1 block and another holds only V2 blocks, the first returns full label sets and the second returns the projected labels plus s_series_hash.

blocksStoreQuerier merges the responses with storage.NewMergeSeriesSet(…, storage.ChainedSeriesMerge), which only merges identical label sets. The same series therefore comes back twice, and overlapping samples (e.g. a source block and its compacted block both still in the bucket) are no longer deduplicated. I reproduced the split with buildSelectHints plus that merge: V1-only shards → no projection, V2-only → [job s_series_hash], 2 series after the merge.

The direct parquet queryable avoids this by deciding once for all selected blocks before fan-out (allParquetBlocksHaveHashColumn over the bucket-index blocks in parquet_queryable.go). queryWithConsistencyCheck already has those blocks (knownBlocks, with Parquet.Version), so the hints could be reset there when any selected block is V1.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense, I applied it to the latest commit. Thanks.

Signed-off-by: SungJin1212 <tjdwls1201@gmail.com>
Signed-off-by: SungJin1212 <tjdwls1201@gmail.com>
Signed-off-by: SungJin1212 <tjdwls1201@gmail.com>
Signed-off-by: Sungjin1212 <tjdwls1201@gmail.com>
@SungJin1212
SungJin1212 force-pushed the Add-ProjectionHints-to-SG branch from bac13d7 to 52d1f96 Compare October 30, 2026 12:01
Signed-off-by: Sungjin1212 <tjdwls1201@gmail.com>
@SungJin1212
SungJin1212 force-pushed the Add-ProjectionHints-to-SG branch from 2b82175 to 6ec078d Compare October 30, 2026 12:29

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants