-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Querier/Sidecar/StoreGW: Implement Info service and add --endpoint
flag in Querier
#4282
Conversation
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.
Great work so far; some ideas from our weekly 1-1
pkg/query/storeset.go
Outdated
type InfoSpec interface { | ||
// Addr returns InofAPI Address for the info spec. It is used as its ID. | ||
Addr() string | ||
// Metadata returns current labels, min/max ranges for StoreAPI and ExemplarAPI |
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.
Let's start with the smaller abstraction and add this later if we see we need to generalize it to all Info types only if they all need it really. Otherwise, we can keep it in the StoreSpec
8c653cb
to
b688deb
Compare
b688deb
to
a46c007
Compare
Is it rdy for review? (: |
a46c007
to
3a09ce5
Compare
I have to add e2e tests. Apart from that, PR is ready for review 🚀 |
cmd/thanos/store.go
Outdated
MaxTime: maxt, | ||
} | ||
}, | ||
func() *infopb.ExemplarsInfo { return nil }, |
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.
Can we use nil
here? What's the difference between nil and a function returning nil?
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.
Sorry missed it. Yes, we can pass nil
as we are doing with other parameters. We are allowing to pass nil
for convenience. #4282 (comment)
return &infopb.ExemplarsInfo{ | ||
MinTime: time.Unix(math.MinInt64/1000+62135596801, 0).UTC().Unix(), | ||
MaxTime: time.Unix(math.MaxInt64/1000-62135596801, 999999999).UTC().Unix(), | ||
} |
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.
We can use global variable for the two values to avoid calculating them each time.
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.
@hitanshu-mehta We are still calling .Unix()
every time. Can't we just initialize v1.MinTime
and v1.MaxTime
as int64? Are they used anywhere else?
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.
Currently, they are not being used anywhere else. Agree, I should've used int64. I'll correct it. Thank you!
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.
The thing is we can have kind of constants somewhere in global level. Can we do that? It's still to be imp[roved?
85f6075
to
803e7b1
Compare
I had to rename messages |
--endpoint
flag in Querier--endpoint
flag in Querier
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.
Just some comments/suggestions but overall LGTM 💪 nice work!
pkg/query/storeset.go
Outdated
@@ -312,6 +329,21 @@ func (s *storeRef) Update(labelSets []labels.Labels, minTime int64, maxTime int6 | |||
s.exemplar = exemplar | |||
} | |||
|
|||
func (s *storeRef) UpdateWithStore(labelSets []labels.Labels, minTime int64, maxTime int64, storeType component.StoreAPI, store storepb.StoreClient, rule rulespb.RulesClient, target targetspb.TargetsClient, metadata metadatapb.MetadataClient, exemplar exemplarspb.ExemplarsClient) { |
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.
Nit: maybe this could be folded into Update
and then we could simply add:
if store != nil {
s.StoreClient = store
}
This would save a bit of code duplication.
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 it store at this point? sounds really like just endpointRef
.
Also the amount of arguments sounds like code smell. I wonder if we hide those behind better abstractions
Maybe let's call them |
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 am wondering how would this API work with routing only receivers? IMO routing only receivers shouldn't expose any store API. Can you add a test case for this? cc @yashrsharma44 @hitanshu-mehta
Edit: Sorry, this pr doesn't deal with receiver part.
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.
Amazing work everyone!
I wonder only - what's the deprecation plan and how to not add complexity to storeset if it has to be removed at some point and instead focus on endpointset
that supports old StoreAPI and new separate info
@@ -379,6 +382,25 @@ func runStore( | |||
cancel() | |||
}) | |||
} | |||
|
|||
infoSrv := info.NewInfoServer( |
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's the deprecation plan for ths old Info methods? Can we unify implementation somehow at least?
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.
ping
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.
Really sorry for delay.
Here is the deprecation plan I had in mind.
- Remove old flags (i.e.
--store
,--rule
,--metadata
,--exemplar
,--target
) and all the boilerplate code we have for all commands. ( eg. duplication check, dnsProviders ...) - Remove
storeset.go
file ( I am working on to move new endpoint flow in new file as discussed here ) and all dependencies of this file from the code base. - Remove Info rpc from proto file of Store API and all its corresponding implementations. ( to be specific there 5 different implementations we have of StoreClient -
BucketStore
,MultiTSDBStore
,PrometheusStore
,ProxyStore
andTSDBStore
)
All these steps will be done in single PR. I think this plan should work .
Please let me know if im missing something :)
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.
Can we unify implementation somehow at least?
Why do we need to unify old info methods?
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.
- When we want to change flag we usually deprecate flag first (add in help that it will be removed after next 2 releases). Then add new flags that works simultaneously. Fail if both new and old way is used. Map old flags to new one really before starting the program.
- Agree
- Generally makes sense, but we need to make sure that e.g old Querier having a client against old StoreAPI will work with new InfoAPI. Probably we will need to leave old Info Method (add deprecated comment) in old APIs. In the same time the new Querier should work with old APIs.
- Potential flow: 1. Try (reflect)? InfoAPI end endpoint. If gRPC server does not support it we fallback to store, if store does it work then ruler ..... only for first call / error.
- e2e test
- IMPORTANT: This does not mean we need to implement separate info method for every server. We can implement one Info method and use the same one for both InfoAPI and e.g StoreAPI.
pkg/info/infopb/rpc.proto
Outdated
@@ -23,12 +23,12 @@ option (gogoproto.goproto_sizecache_all) = false; | |||
/// Info represents the API that is responsible for gathering metadata about the all APIs supported by the component. | |||
service Info { | |||
/// Info returns the metadata (Eg. LabelSets, Min/Max time) about all the APIs the component supports. | |||
rpc Info(InfoRequest) returns (InfoResponse); | |||
rpc Info(InfoReq) returns (InfoResp); |
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.
First time I see this practice. While it helps with shorter name it violates coding style guide + consistency. Do we think it's worth it?
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.
If I don't rename it then a warning message will also be printed in our documentations as I mentioned here. I was not able to find a way to remove them. @GiedriusS has suggested better names InfoAPIRequest
and InfoAPIResponse
.
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 is because our pacakge is thanos
. Do you mind changing this to thanos.info
?
pkg/query/storeset.go
Outdated
@@ -312,6 +329,21 @@ func (s *storeRef) Update(labelSets []labels.Labels, minTime int64, maxTime int6 | |||
s.exemplar = exemplar | |||
} | |||
|
|||
func (s *storeRef) UpdateWithStore(labelSets []labels.Labels, minTime int64, maxTime int64, storeType component.StoreAPI, store storepb.StoreClient, rule rulespb.RulesClient, target targetspb.TargetsClient, metadata metadatapb.MetadataClient, exemplar exemplarspb.ExemplarsClient) { |
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 it store at this point? sounds really like just endpointRef
.
Also the amount of arguments sounds like code smell. I wonder if we hide those behind better abstractions
pkg/query/storeset.go
Outdated
@@ -597,6 +630,105 @@ func (s *StoreSet) getActiveStores(ctx context.Context, stores map[string]*store | |||
level.Warn(s.logger).Log("msg", "ignored rule store", "address", ruleAddr) | |||
} | |||
} | |||
|
|||
// Gather healthy stores map concurrently using info addresses. Build new store if does not exist already. | |||
for _, infoSpec := range s.infoSpec() { |
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.
All of this is baked in storeset
but I would see it really part of endpoints
I would really just copy and add a new endpoint flow - it will be easier to main new thing than to try to understand later what to remove from mixed thing.
Then if someone wants to use endpoints store flag should be empty. WDYT?
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.
Agree! I will refactor this code and maybe create a new flow in a different endpointset.go
file. WDYT ?
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.
SGTM
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.
Still minor nits, but looks really close to be done!
return &infopb.ExemplarsInfo{ | ||
MinTime: time.Unix(math.MinInt64/1000+62135596801, 0).UTC().Unix(), | ||
MaxTime: time.Unix(math.MaxInt64/1000-62135596801, 999999999).UTC().Unix(), | ||
} |
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.
The thing is we can have kind of constants somewhere in global level. Can we do that? It's still to be imp[roved?
@@ -379,6 +382,25 @@ func runStore( | |||
cancel() | |||
}) | |||
} | |||
|
|||
infoSrv := info.NewInfoServer( |
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.
ping
pkg/info/infopb/rpc.proto
Outdated
@@ -23,12 +23,12 @@ option (gogoproto.goproto_sizecache_all) = false; | |||
/// Info represents the API that is responsible for gathering metadata about the all APIs supported by the component. | |||
service Info { | |||
/// Info returns the metadata (Eg. LabelSets, Min/Max time) about all the APIs the component supports. | |||
rpc Info(InfoRequest) returns (InfoResponse); | |||
rpc Info(InfoReq) returns (InfoResp); |
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 is because our pacakge is thanos
. Do you mind changing this to thanos.info
?
8ffaa2a
to
03baf00
Compare
Quick question about this and our usecase. We have a central thanos query and multiple edge thanos sidecars. If I use |
@yeya24 Currently there isn't any way to disable specific api queries like metadata, targets etc. |
Signed-off-by: Hitanshu Mehta <[email protected]>
Signed-off-by: Hitanshu Mehta <[email protected]>
Signed-off-by: Hitanshu Mehta <[email protected]>
Signed-off-by: Hitanshu Mehta <[email protected]>
Signed-off-by: Hitanshu Mehta <[email protected]>
Signed-off-by: Hitanshu Mehta <[email protected]>
Signed-off-by: Hitanshu Mehta <[email protected]>
Signed-off-by: Hitanshu Mehta <[email protected]>
Signed-off-by: Hitanshu Mehta <[email protected]>
Signed-off-by: Hitanshu Mehta <[email protected]>
Signed-off-by: Hitanshu Mehta <[email protected]>
Signed-off-by: Hitanshu Mehta <[email protected]>
Signed-off-by: Hitanshu Mehta <[email protected]>
Signed-off-by: Hitanshu Mehta <[email protected]>
9b9b68c
5a894b5
to
9b9b68c
Compare
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.
Last three suggestions before merging 👍 Also, please, please, please avoid force-pushing and overriding previous commits because when this happens the reviewers need to look through the whole code again to see whether it is still the same. That's why there was this big delay before I got to this again 👍
@GiedriusS Really sorry for the trouble. I will avoid force pushing from now on :) |
Signed-off-by: Hitanshu Mehta <[email protected]>
CI failure seems related (: |
Signed-off-by: Hitanshu Mehta <[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.
💪 next steps are to actually use the new InfoServer & add tests for it? Plus, we should probably also add --endpoint-strict
? Finally, remove the old flags? (: And that feature to ignore certain service(-s) would be nice too.
Note to others that --endpoint
with this PR is semantically equivalent to all of the other flags since we prefill the expected APIs (we don't check the InfoServer, yet) so it is completely safe to merge this!
With thanos-io#4282 merged, it is time to unhide these very useful pages from the navigation bar. 🎉 Signed-off-by: Giedrius Statkevičius <[email protected]>
With #4282 merged, it is time to unhide these very useful pages from the navigation bar. 🎉 Signed-off-by: Giedrius Statkevičius <[email protected]>
With thanos-io#4282 merged, it is time to unhide these very useful pages from the navigation bar. 🎉 Signed-off-by: Giedrius Statkevičius <[email protected]>
This PR implements a Unified Endpoint Proposal. Open for reviews :)
Changes
--endpoint
flag in querier.Modified storeset tests to verify discovery usingCompletely removedendpoint
flag.storeset
and addedendpointset
query: add endpointset flow #4421Verification
Modified storeset tests to verify discovery using endpoint flag.TODO
E2E tests.