-
Notifications
You must be signed in to change notification settings - Fork 4.1k
feat: LID for query splitting #16958
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
Changes from all commits
902d864
b1bc171
beac6d3
3b74ead
dcd6a0f
74ade1a
873f26d
a8aff24
a52e702
5760aa6
d2f2b98
0fd5d30
5ffb1d5
a07ae5f
66382ee
cc4313f
819637e
972694c
6e1fdbc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| --- | ||
| title: "0006: Expose Split Logic in API" | ||
| description: "0006: Expose Split Logic in API" | ||
| --- | ||
|
|
||
| # 0006: Expose Split Logic in API | ||
|
|
||
| **Author:** Karsten Jeschkies (karsten.jeschkies@grafana.com) | ||
|
|
||
| **Date:** 03/2025 | ||
|
|
||
| **Sponsor(s):** @trevorwhitney | ||
|
|
||
| **Type:** API | ||
|
|
||
| **Status:** Review | ||
|
|
||
| **Related issues/PRs:** N/A | ||
|
|
||
| **Thread from [mailing list](https://groups.google.com/forum/#!forum/lokiproject):** N/A | ||
|
|
||
| --- | ||
|
|
||
| ## Background | ||
|
|
||
| Loki has an internal logic to split and shard log and metric queries by time into multiple queries. However, this logic is not | ||
| accessible outside of the code base. This proposal intends to create an API for clients to split queries by exposing the | ||
| internal split logic. | ||
|
|
||
| A split query is divided by time. The results of a split query can be concatenated in order to form the final | ||
| result. | ||
|
|
||
| A sharded query is divided by label values. The results of a sharded cannot always be concatenated but require some | ||
| extra logic to form the final result. Some queries, such as `topk` cannot be sharded at all. | ||
|
|
||
| ## Problem Statement | ||
|
|
||
| Loki clients such as the Grafana Loki datasource or the [Trino Loki | ||
| connector](https://github.com/trinodb/trino/tree/master/plugin/trino-loki) benefit from splitting LogQL queries into multiple sub-queries either to process | ||
| smaller chunks or to distribute work on query results. | ||
|
|
||
| Splitting a query requires parsing the LogQL query first but there are no parsers for other languages except Go and | ||
| JavaScript. | ||
|
|
||
| ## Goals | ||
|
|
||
| The intended goal is to enable any client to split a query into multiple sub-queries that can be either executed | ||
| sequentially or in parallel. The joined result of the sub-queries must be the same as executing the same query. | ||
|
|
||
| ## Non-Goals | ||
|
|
||
| This proposal does not aim to provide pagination for query results. | ||
|
|
||
| ## Proposals | ||
|
|
||
| ### Proposal 0: Do nothing | ||
|
|
||
| Without an API each client will have to use a LogQL parser. | ||
|
|
||
| *Pros* | ||
| - The split logic in Loki can be changed at will without breaking client behavior. | ||
| - There is no maintanence overhead for an API. | ||
|
|
||
| *Cons* | ||
| - Currently, the LogQL grammar is specific to Go. It is not easy to port it and the parser to other languages. | ||
| - Any changes to the splitting logic must be implemented for each client/platform. | ||
|
|
||
| ### Proposal 1: Expose Splitting in an API | ||
|
|
||
| A new endpoint `GET /loki/api/v1/split_query` is introduced that takes a `splits` parameter and the same parameters as the [/loki/api/v1/query_range](https://grafana.com/docs/loki/latest/reference/loki-http-api/#query-logs-within-a-range-of-time) endpoint. The new endoint returns sub-queries split by time. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
will this endpoint determine optimal splits? currently the split-by is hardcoded in the loki config per tenant, in which case it seems pretty trivial for a client to be able to arbitrarily create the same splits. is it a goal of this project that this endpoint would be capable of more intelligent splitting rather than just applying the tenant's split-by config?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It kind of depends what we mean by optimal 🙂 I think the internal sharding layer tries some optimal sharding. Anyhow, we need something to hang on to. Either number of splits, interval or max response size. |
||
|
|
||
| The `splits` parameter optionally defines the number of desired splits. The API is allowed to return fewer splits than requested. | ||
|
|
||
| The `limit` parameter has extended semantics. Setting it to `0` for a log stream query indicates to query all logs. | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The parameters I would pass to this endpoint are:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about the step? I'm wondering if that is important for splitting. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Coming back to the limit, it's a bit more complicated. For metric queries there's no expected limit, as you expect the data for the requested interval. For querying logs it's a different story, because you might hit the limit with the first request. For example, let's say you want 5000 logs from the last 3 days, split in 3/6/12/etc. You can easily hit that limit on the first day, so maybe the endpoint should just return a single split.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In my case I often want all logs. So I'll allow
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just to clarify here, is
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Many users have the issue that they want to query all logs in a time range but do not know how large the log line limit should be. It defaults to 100. There should be a way to tell the split endpoint that I want to get all log lines. |
||
| The response body is JSON encoded: | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. some thoughts on the response. is it important to the user to differentiate between a single split that just happens to be a single split because it was optimal, and a single split because the query could not be split? certain metric queries will not be able to be split in a way they can be re-combined in the client to produce the same result, so should we add a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That would be sharding. E.g. for certain metric queries. I should specify in the doc that
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, I think those are good distinctions to call out and align with our language elsewhere |
||
|
|
||
| ```json | ||
| { | ||
| "resultType": "matrix" | "streams" | "vector", | ||
| "subqueries": [ | ||
| { | ||
| start: <timestamp nanoseconds>, | ||
| end: <timestamp nanoseconds>, | ||
| limit: <number>, | ||
| query: <query string> | ||
| }, | ||
| { | ||
| start: <timestamp nanoseconds>, | ||
| end: <timestamp nanoseconds>, | ||
| limit: <number>, | ||
| query: <query string> | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| *Pros* | ||
| - Clients can split queries independent on the implemation language and platform. | ||
| - Split logic is controlled by Loki and not the client. This means it can be improved, for example, by introducing sharding | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is the strongest argument for doing this work IMO. being able to improve split logic to produce optimal splits, as well as centralize what can and can't be split. |
||
| labels. | ||
|
|
||
| *Cons* | ||
| - A new API endpoint increases the compatiblity surface area and thus maintanence overhead for Loki maintainers. | ||
|
|
||
| ### Proposal 2: Support Apache Arrow Flight RPC | ||
|
|
||
| Loki could support Apache [Arrow Flight RPC](https://arrow.apache.org/docs/format/Flight.html) which is designed to | ||
| exchange large data sets in shards between services. | ||
|
|
||
| *Pros* | ||
| - Supporting an open standard comes with support for other non-Loki clients. | ||
|
|
||
| *Cons* | ||
| - Loki would have to support Apache Arrow which make the implementation more complicated. | ||
| - Arrow Flight RPC assumes the data is being queried on the first request. Which means all shards are available at the | ||
| same time. However, the intent of this document is that shards can be queried independently. | ||
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.
worth at least calling out there's a JS implementation as well, but I acknowledge it is largely a copy and paste and has a maintenance burden