Skip to content

Fix cache key collision in Query Frontend with epoch-aware shard keys - #5

Open
laurentketterle-hub wants to merge 1 commit into
rasoolharlym8:mainfrom
laurentketterle-hub:fix/cache-key-collision-shard-epoch
Open

Fix cache key collision in Query Frontend with epoch-aware shard keys#5
laurentketterle-hub wants to merge 1 commit into
rasoolharlym8:mainfrom
laurentketterle-hub:fix/cache-key-collision-shard-epoch

Conversation

@laurentketterle-hub

Copy link
Copy Markdown

Summary

During tenant shuffle-sharding rebalance, the Query Frontend intermittently merges cached query fragments generated by different shard assignments. Because the cache key generation did not account for the active shard configuration or transition state, fragments from the old shard assignment were mixed with fragments from the new shard assignment, resulting in partial/incomplete query results returned with HTTP 200 OK.

Fix

This PR implements epoch-aware cache keys in the Query Frontend:

  1. ShardConfig and CacheKey types (pkg/queryfrontend/queryrange/types.go):

    • ShardConfig tracks a tenant's shard assignment with a version/epoch
    • ShardConfig.Hash() produces a deterministic, order-independent hash
    • CacheKey includes the shard epoch hash alongside tenant, query, time range, and step
    • ShardState tracks per-tenant configurations and transition status
  2. QueryRangeCache middleware (pkg/queryfrontend/queryrange/cache.go):

    • BuildCacheKey() generates keys that incorporate the current shard epoch
    • Get() bypasses the cache during shard transitions to guarantee data completeness
    • InvalidateStaleEpoch() proactively removes cached entries from old epochs
    • InvalidateTenant() clears all cached entries for a tenant
  3. Unit tests (pkg/queryfrontend/queryrange/cache_test.go):

    • Verifies cache keys change when shard configuration changes
    • Verifies cache is bypassed during transitions
    • Verifies stale epoch invalidation
    • Verifies hash determinism (order-independent)
    • Verifies different tenants produce different keys

How It Works

  • When a query is cached, the cache key includes a hash of the tenant's current shard configuration and version
  • When the shard assignment changes (e.g., scale-out from 3 to 5 shards), the hash changes
  • New queries generate new cache keys, old fragments are never mixed with new ones
  • During the transition window, the cache is bypassed entirely to ensure complete results
  • After transition completes, InvalidateStaleEpoch() can clean up old epoch entries

Closes #1

/claim #1

Signed-off-by: laurentketterle-hub noreply@users.noreply.github.com

During tenant shuffle-sharding rebalance, the Query Frontend's cache key
generation did not account for the active shard configuration, causing stale
cached fragments from old shard assignments to be merged with new fragments.
This resulted in partial/incomplete query results returned with HTTP 200 OK.

Changes:
- Add ShardConfig and CacheKey types with epoch-aware hashing (types.go)
- Implement QueryRangeCache middleware that incorporates shard epoch in
  cache keys, bypasses cache during transitions, and supports proactive
  stale-epoch invalidation (cache.go)
- Add comprehensive unit tests verifying key rotation, transition bypass,
  stale invalidation, and hash determinism (cache_test.go)
- Update main.go with a demo showcasing the fix

The cache key now includes a hash of the tenant's shard configuration,
ensuring that when shards change (scale-out/scale-in/rebalance), cache
keys naturally rotate and old fragments are never mixed with new ones.

Closes rasoolharlym8#1

Signed-off-by: laurentketterle-hub <noreply@users.noreply.github.com>
@opirebot

opirebot Bot commented Aug 6, 2026

Copy link
Copy Markdown

😅 Unfortunately there are no rewards left to claim in this issue!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🎯 Fix Cache Key Collision and Partial Results During Tenant Shuffle-Sharding Rebalance in Query Frontend

2 participants