-
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
store: take initialization out to the background goroutine #538
Conversation
Initialization is a lingering process and can take minutes to sync meta and index files. Move it to background goroutine to allow metrics/debug handlers be ready right after application is start. It provides admins set up liveness and readindess probes at the k8s. Recommendations: use http port for liveness and grpc for readyness Fixed thanos-io#532
But you are aware that by this PR allows to compactor being completely NOT ready to work when you respond 200 on readiness probe? (: I guess this is ok for compactor, since it is not a web service - it just starting it's job to operata on storage.. so maybe it's fine. |
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 quite wrong.
The title states about compact but it is actually store gateway. You confused me ;p
This is wrong, as store gateway is NOT ready to take request before initial request, so that will break any rolling update in kubernetes, so we cannot mark it ready in readiness probe.
ahh, the deep night work affects ...
don't understand you, what's wrong? Rolling updates don't work properly. You can see here https://github.com/improbable-eng/thanos/pull/538/files#diff-0f89c5ba9c5a93c3de701595df39ecdaR125 that grpc will be ready as soon as initialization is done, so the same behaviour as before, the only difference here, is to start http server to serve metrics request immediately after store is run to allow k8s use them as liveness endpoint. |
Yes, and exactly this is the point.
(https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) Currently the /metrics page is recommended way to test for readiness. And we cannot be ready before this init step. Unless we change internal logic and enabling StoreAPI without the cached filled (store not being aware of all blocks), but this is wrong, as the multi replica rollout would be broken:
Of course for 1 replica it does not matter (: So options here: I would rather focus on making init faster not removing init itself (: Thoughts? |
May be this was unclear, but my suggestion is to use GRPC port as a readiness endpoint, and only when initialization is done, grpc will start and k8s will know it's ready. Having readiness on http for StoreAPI is useless, IMHO |
Yea, sorry my bad misunderstood that part maybe. Sure, but what is the goal/use case here? (: Do you want to have metric endpoint earlier? Why? Adhoc debug? Prometheus will not scrape this one anyway (am I wrong?) Is it is just for clarity? |
I use /metics as a liveness probe, as I mentioned earlier ;) It's also handful to see, what's happening right during the initialization
|
Regarding to having both probes, from the link above:
So the main point to use both is to be sure your container is started and do some job to be ready. I.e. if you forgot specify proper network policy (ingress in that case), you will know while running, that k8s doesn't see the container is alive (still not ready). Liveness controls the restart, readiness - the traffic proxy |
I was about to submit a similar PR and I found this. Can we get some movement here? I use tcpProbes on the http port as liveness checks on all thanos components. I didn't notice the problem with store until my bucket grew sufficiently large and the stores started crash looping (failed readiness checks) after being rescheduled. It also causes Prometheus to think the job is down. |
defer runutil.CloseWithLogOnErr(logger, bkt, "bucket client") | ||
|
||
// Ready to start Grpc server. | ||
readyToServe <- struct{}{} |
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's usually better to just close the channel. That way you won't have to know how many other goroutines depend on being ready (and need to send a signal for each).
If you change it, you can drop the channel buffer too.
@@ -148,6 +152,7 @@ func runStore( | |||
storepb.RegisterStoreServer(s, bs) | |||
|
|||
g.Add(func() error { | |||
<-readyToServe |
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 the initial sync fails, this will block forever.
select {
case <-readyToServe:
case <-ctx.Done():
return ctx.Err()
}
I think it is just a matter of increase timeout on failed readiness probes -> Store needs some time for initialization |
The liveness and readiness probes serve different purposes. If a container passes liveness, it will not be restarted. If a container passes readiness, it will be included in service endpoints. The time it takes for the store to become ready is a function of the size of its dataset. Requiring users to manually tune their liveness probes based on this moving target isn't a good solution. It should pass liveness tests as soon as possible, whether or not it's ready to serve queries. |
I'm with @abursavich on this one. Also linking this #656 |
Thanks @abursavich that makes sense - sure, we can set liveness |
should we close this PR then? |
Initialization is a lingering process and can take minutes to sync meta and index files. Move it to background goroutine to allow metrics/debug handlers be ready right after application is start. It provides admins set up liveness and readindess probes at the k8s.
Recommendations: use http port for liveness and grpc for readyness
Fixes #532
@bwplotka
Verification
Run thanos store and check for
thanos-store-host:port/metrics
uri is giving you metrics