@fpetkovski
@mzardab
TL;DR: Introducing a new gRPC API for
/query
and/query_range
We want to be able to distinguish between gRPC Store APIs and other Queriers in the query path. Currently, Thanos Query implements the gRPC Store API and the root Querier does not distinguish between Store targets and other Queriers that are capable of processing a PromQL expression before returning the result. The new gRPC Query API will allow a querier to fan out query execution, in addition to Store API selects.
This is useful for a few reasons:
Thanos Query currently allows for query
and query_range
operations through HTTP only. Various query strategies can be implemented using the HTTP API, an analogous gRPC API would allow for a more resource efficient and expressive query execution path. The two main reasons are the streaming capabilities that come out of the box with gRPC, statically typed API spec, as well as the lower bandwidth utilization which protobuf enables.
query
for instant queries, query_range
for range queries)query
and query_range
rpc’s, these will be introduced as additional QueryStream
and QueryRangeStream
rpc’s subsequently.We propose defining the following gRPC API:
service Query {
rpc Query(QueryRequest) returns (stream QueryResponse);
rpc QueryRange(QueryRangeRequest) returns (stream QueryRangeResponse);
}
Where the QueryRequest
, QueryResponse
, QueryRangeRequest
and Query RangeResponse
are defined as follows:
message QueryRequest {
string query = 1;
int64 time_seconds = 2;
int64 timeout_seconds = 3;
int64 max_resolution_seconds = 4;
repeated string replica_labels = 5;
repeated StoreMatchers storeMatchers = 6 [(gogoproto.nullable) = false];
bool enableDedup = 7;
bool enablePartialResponse = 8;
bool enableQueryPushdown = 9;
bool skipChunks = 10;
}
message QueryResponse {
oneof result {
/// warnings are additional messages coming from the PromQL engine.
string warnings = 1;
/// timeseries is one series from the result of the executed query.
prometheus_copy.TimeSeries timeseries = 2;
}
}
message QueryRangeRequest {
string query = 1;
int64 start_time_seconds = 2;
int64 end_time_seconds = 3;
int64 interval_seconds = 4;
int64 timeout_seconds = 5;
int64 max_resolution_seconds = 6;
repeated string replica_labels = 7;
repeated StoreMatchers storeMatchers = 8 [(gogoproto.nullable) = false];
bool enableDedup = 9;
bool enablePartialResponse = 10;
bool enableQueryPushdown = 11;
bool skipChunks = 12;
}
message QueryRangeResponse {
oneof result {
/// warnings are additional messages coming from the PromQL engine.
string warnings = 1;
/// timeseries is one series from the result of the executed query.
prometheus_copy.TimeSeries timeseries = 2;
}
}
The Query
Service will be implemented by the gRPC server which is started via the thanos query
command.
The alternative to expressing a gRPC Query API would be to use the HTTP APIs and distinguish Queriers via configuration on startup. This would be suboptimal for the following reasons: