Resolve Parquet shard count via bucket index to optimize storage calls#7648
Resolve Parquet shard count via bucket index to optimize storage calls#7648SungJin1212 wants to merge 5 commits into
Conversation
f7b225e to
0fdab66
Compare
| shardCounts := make(map[string]int, len(blockIDs)) | ||
|
|
||
| if p.bucketIndexEnabled { | ||
| idx, err := bucketindex.ReadIndex(ctx, p.indexBucket, p.userID, p.limits, p.logger) |
There was a problem hiding this comment.
This should be cached with some TTL instead? Or we would rather have a separate goroutine to sync bucket index periodically rather than resolving it at query time.
There was a problem hiding this comment.
If we use bucketindex.Loader it has built-in caching
6656f19 to
2f7ecc9
Compare
|
@yeya24
|
|
I wonder how this bucket index integration works with the Store gateway hybrid mode mentioned in #7140. Do we imagine the hybrid mode to be as part of TSDB bucket store, or Parquet bucket store or a new federated store. |
|
@yeya24 |
|
@yeya24 |
…e calls Signed-off-by: SungJin1212 <tjdwls1201@gmail.com>
Signed-off-by: SungJin1212 <tjdwls1201@gmail.com>
Signed-off-by: SungJin1212 <tjdwls1201@gmail.com>
2f7ecc9 to
9bddc94
Compare
| } | ||
| shardCounts[b.ID.String()] = numShards | ||
| } | ||
| return shardCounts, nil |
There was a problem hiding this comment.
Should we try to cache the shard counts result? Because every time we get the whole bucket index and iterate all its blocks to populate shard map. Even though the bucket index is cached, re-populating the map seems wasted. Especially if we only try to query few block IDs among the bucket index
There was a problem hiding this comment.
Agree, I addressed this by memoizing the shard count map instead of rebuilding it on every request.
|
|
||
| // Read converter marks and expand to per-shard (blockID, shardID) lists. | ||
| // TODO(Sungjin1212): Read the shard count from the bucket index instead of reading the converter mark for each block. | ||
| shardCounts, err := p.resolveShardCounts(ctx, blockIDs) |
There was a problem hiding this comment.
Overall I think this is fine... But for most of the usecases we only have 1 shard for the parquet file.
Signed-off-by: SungJin1212 <tjdwls1201@gmail.com>
4986a1a to
f6dbed1
Compare
| } | ||
| numShards := b.Parquet.Shards | ||
| if numShards <= 0 { | ||
| numShards = 1 |
There was a problem hiding this comment.
Imagine having 2 shards in a block, but the bucket index doesn't have it yet. That means we get 1 shard only.
I think, for cases where query_store_after is configured as zero, the default, this would cause partial queries in bucket index blocks that don't have shards in them. But then again who is using query_store_after with zero?
I think we should definitely change the default for query_store_after to be bigger than 0 and discourage very low query store after in general. Not good performance.
Then again, what about backfilling up historical blocks to object storage. Maybe we should fall back to the following instead of using 1
func (p *parquetBucketStore) shardCountFromConverterMark(ctx context.Context, blockID string) (int, error) {
uid, err := ulid.Parse(blockID)
if err != nil {
return 0, errors.Wrapf(err, "failed to parse block ID %s", blockID)
}
marker, err := cortex_parquet.ReadConverterMark(ctx, uid, p.bucket, p.logger)
if err != nil {
return 0, errors.Wrapf(err, "failed to read converter mark for block %s", blockID)
}
return marker.Shards, nil
}
We can definitely do this in a follow up PR
There was a problem hiding this comment.
Then again, what about backfilling up historical blocks to object storage. Maybe we should fall back to the following instead of using 1
Agree, we need to read the block's converter mark directly on a map miss.
I think we should definitely change the default for query_store_after to be bigger than 0 and discourage very low query store after in general. Not good performance.
Agree on discouraging very low values for performance, but query_store_after is coupled with the query_ingesters_within. So bumping the query_store_after default would also require bumping query_ingesters_within, which is a broader change affecting all users. I'd keep that as a separate discussion.
…x is stale Signed-off-by: SungJin1212 <tjdwls1201@gmail.com>
What this PR does:
This PR updates the Parquet shard resolution logic to utilize the bucket index, reducing the number of object storage calls.
Which issue(s) this PR fixes:
Fixes #
Checklist
CHANGELOG.mdupdated - the order of entries should be[CHANGE],[FEATURE],[ENHANCEMENT],[BUGFIX]docs/configuration/v1-guarantees.mdupdated if this PR introduces experimental flags