-
Notifications
You must be signed in to change notification settings - Fork 833
Add bucket index support to querier #3614
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add bucket index support to querier #3614
Conversation
Signed-off-by: Marco Pracucci <[email protected]>
Signed-off-by: Marco Pracucci <[email protected]>
Signed-off-by: Marco Pracucci <[email protected]>
Signed-off-by: Marco Pracucci <[email protected]>
Signed-off-by: Marco Pracucci <[email protected]>
Signed-off-by: Marco Pracucci <[email protected]>
Signed-off-by: Marco Pracucci <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, great job! No major problems found, logic is solid. 👏
Signed-off-by: Marco Pracucci <[email protected]>
Thanks @pstibrany for your deep review! After reading your comments I realised it was definitely a draft what I've submitted 😉 I've addressed all comments, except a couple I've commented about. |
Signed-off-by: Marco Pracucci <[email protected]>
Signed-off-by: Marco Pracucci <[email protected]>
Signed-off-by: Marco Pracucci <[email protected]>
|
||
The bucket index is a **per-tenant file containing the list of blocks and block deletion marks** in the storage. The bucket index itself is stored in the backend object storage, is periodically updated by the compactor and used by queriers to discover blocks in the storage. | ||
|
||
The bucket index usage is **optional** and can be enabled via `-blocks-storage.bucket-store.bucket-index.enabled=true` (or its respective YAML config option). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Explain why it is useful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. WDYT?
Signed-off-by: Marco Pracucci <[email protected]>
Signed-off-by: Marco Pracucci <[email protected]>
|
||
If a bucket index is unused for a long time (configurable via `-blocks-storage.bucket-store.bucket-index.idle-timeout`), e.g. because that querier instance is not receiving any query from the tenant, the querier will offload it, stopping to keep it updated at regular intervals. This is particularly for tenants which are resharded to different queriers when [shuffle sharding](../guides/shuffle-sharding.md) is enabled. | ||
|
||
Finally, the querier, at query time, checks how old is a bucket index (based on its `updated_at`) and fail a query if its age is older than `-blocks-storage.bucket-store.bucket-index.max-stale-period`. This circuit breaker is used to ensure queriers will not return any partial query results due to a stale view over the long-term storage. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have also added caching of index into caching-bucket. Is that worth mentioning as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, sure, done. WDYT?
Signed-off-by: Marco Pracucci <[email protected]>
The **[store-gateway](./store-gateway.md)** is responsible to query blocks and is used by the [querier](./querier.md) at query time. The store-gateway is required when running the blocks storage. | ||
|
||
The **[compactor](./compactor.md)** is responsible to merge and deduplicate smaller blocks into larger ones, in order to reduce the number of blocks stored in the long-term storage for a given tenant and query them more efficiently. It also keeps the bucket index updated and, for this reason, it's a required component. | ||
The **[compactor](./compactor.md)** is responsible to merge and deduplicate smaller blocks into larger ones, in order to reduce the number of blocks stored in the long-term storage for a given tenant and query them more efficiently. It also keeps the [bucket index](./bucket-index.md) updated and, for this reason, it's a required component. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this going to cause issues for users running with compactor now(not sure if there are such people)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, bucket-index.md says the bucket index is optional which seems like it contradicts this statement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this going to cause issues for users running with compactor now(not sure if there are such people)?
Did you mean "with compactor" or "without compactor"? I'm no sure I understand the question.
Also, bucket-index.md says the bucket index is optional which seems like it contradicts this statement.
The compactor always writes the bucket index. The flag to enable bucket index is whether it should be used or not in queriers (and in the store-gateway in the upcoming PR too). The point is that, before enabling the bucket index in the queriers and store-gateway, you have to rollout the compactor first, so that the bucket index for all tenants is created before you enable it in querier and store-gateway. To simplify it (at least I thought it would have simplified), I've kept it always enabled in the compactor.
docs/blocks-storage/bucket-index.md
Outdated
|
||
The [compactor](./compactor.md) periodically scans the bucket and uploads an updated bucket index to the storage. The frequency at which the bucket index is updated can be configured via `-compactor.cleanup-interval`. | ||
|
||
The bucket index is built and updated by the compactor even if `-blocks-storage.bucket-store.bucket-index.enabled` has **not** been enabled. This is intentional and the overhead introduced by keeping the bucket index is non significative. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This mostly answers my earlier question about non-optional compactor to create optional bucket index, but it still may be a bit unclear to someone new.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the doc. Is it more clear now?
|
||
If a bucket index is unused for a long time (configurable via `-blocks-storage.bucket-store.bucket-index.idle-timeout`), e.g. because that querier instance is not receiving any query from the tenant, the querier will offload it, stopping to keep it updated at regular intervals. This is particularly for tenants which are resharded to different queriers when [shuffle sharding](../guides/shuffle-sharding.md) is enabled. | ||
|
||
Finally, the querier, at query time, checks how old is a bucket index (based on its `updated_at`) and fail a query if its age is older than `-blocks-storage.bucket-store.bucket-index.max-stale-period`. This circuit breaker is used to ensure queriers will not return any partial query results due to a stale view over the long-term storage. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It isn't possible to fall back to the behavior used when the bucket index is not enabled? Or this is undesirable or some reason?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think falling back is a viable solution. The "bucket scan" logic requires a preventive bucket scanning, which we don't do when we enable the bucket index. Lazily bucket scanning would be too slow to do at query time. Moreover, fallback logic unfrequently exercised would bring further risks that fallback logic doesn't work as expected.
In my opinion, when you run Cortex with bucket index, the bucket index is an essential part of the system and it's required to be kept updated. The compactor already exports a metric with the timestamp of the last time the bucket index of each tenant has been updated, so that we can alert on it before the max-stale-period
is reached.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think?
Signed-off-by: Marco Pracucci <[email protected]>
Signed-off-by: Marco Pracucci <[email protected]>
Signed-off-by: Marco Pracucci <[email protected]>
Signed-off-by: Marco Pracucci <[email protected]>
@pstibrany @ranton256 I'm going to merge this PR, but feel free to add further comments (if any). I will promptly address post-merge comments too. |
* Introduced BucketIndexBlocksFinder Signed-off-by: Marco Pracucci <[email protected]> * Improved and tested bucket index Loader Signed-off-by: Marco Pracucci <[email protected]> * Integrated bucket index in querier and added caching support Signed-off-by: Marco Pracucci <[email protected]> * Fixed unit tests Signed-off-by: Marco Pracucci <[email protected]> * Fixed typo in comment Signed-off-by: Marco Pracucci <[email protected]> * Fail queries if bucket index is too old Signed-off-by: Marco Pracucci <[email protected]> * Fixed linter Signed-off-by: Marco Pracucci <[email protected]> * Addressed review comments Signed-off-by: Marco Pracucci <[email protected]> * Addressed more comments Signed-off-by: Marco Pracucci <[email protected]> * Updated doc Signed-off-by: Marco Pracucci <[email protected]> * Added CHANGELOG entry Signed-off-by: Marco Pracucci <[email protected]> * Added integration test Signed-off-by: Marco Pracucci <[email protected]> * Fixed integration test Signed-off-by: Marco Pracucci <[email protected]> * Replaced 1st with first Signed-off-by: Marco Pracucci <[email protected]> * Loader refactoring Signed-off-by: Marco Pracucci <[email protected]> * Clarified max size cached item Signed-off-by: Marco Pracucci <[email protected]> * Updated bucket index doc Signed-off-by: Marco Pracucci <[email protected]> * Updated doc Signed-off-by: Marco Pracucci <[email protected]>
What this PR does:
In this PR I'm adding the bucket index support to querier. Using the bucket index in the querier is optional and disabled by default (and will be until marked experimental).
Which issue(s) this PR fixes:
N/A
Checklist
CHANGELOG.md
updated - the order of entries should be[CHANGE]
,[FEATURE]
,[ENHANCEMENT]
,[BUGFIX]