-
Notifications
You must be signed in to change notification settings - Fork 9.8k
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
Remove the dependency on grpc-go's experimental API (e.g. resolver & balancer) #15145
Comments
grpc-go TL here. I'm happy to work with you to find / provide a stable solution, but I would first need to know more about your use cases & requirements. |
just to randomly add what I've found in #14501 - once we reconsider the balancer/resolver, we should also add some circuit breaking. There were some ideas by Easwar in grpc/grpc-go#5672. |
Sorry for the late response. The use cases & requirement seems to be simple. Users may specify multiple endpoints on the client side (see example below), and etcd clientv3 needs to support client side load balancing.
Currently the target used when calling grpc.DialContext is a string in format Some historical background:
Based on https://github.com/grpc/grpc/blob/master/doc/naming.md, it seems the gRPC resolver plugin (although the API is still experimental) is still the right direction? If not, could you please advise the correct approach? cc @dfawley |
@dfawley could you advise how to replace the experimental API mentioned above? |
One more dependency on experimental API: grpcServer.ServeHTTP |
Also sorry for the late rely
For this you could instead create (N) gRPC clients, one for each address, and do round robin dispatch to them by wrapping them in another object that implements its own What would be your concerns with such an approach? |
Thanks for the response. The only concern is what (etcd or gRPC?) is the best place to implement it. It looks like a generic client side load balancer solution, does it make more sense to get it wrapped in grpc/grpc-go instead of etcd? Also some APIs (such as resolver.Resolve, balancer.Balancer , etc) were added as experimental APIs about 6 years ago, they are still experimental APIs today. Have you considered to graduate them to stable APIs or deprecate/remove them and provide alternative solution/APIs? cc @mitake @ptabor @serathius @spzala @liggitt @wojtek-t @lavalamp for opinions. |
I was just digging around and saw that C-core has the following name resolver (https://github.com/grpc/grpc/blob/master/doc/naming.md#name-syntax):
We could also explore making this a first-class name resolver. Would that take care of all of your need for |
My immediate feeling is it looks good. Could you please provide a rough draft API and usage, so that I can evaluate the change & effort in etcd side? |
One aspect to be aware of is also support for DNS resolution: I think that currently such connection works:
And in case of problems the DNS name get's re-resolved to IP. Fallback to Alternative is to build in within an etcd client a local xDS policy supplier. |
Yeah I was digging a little deeper and it seems you need more than multiple IP address support; you also need DNS names and multiple unix sockets, and mixed versions of all these things. We have one project on the horizon that is going to require changes to the resolver API, and then I think we will be able to stabilize it. Unfortunately, that will first require a breaking change, which is unavoidable no matter what. In the meantime, I think the only real option would be to maintain a pool of channels, which I agree isn't trivial but also isn't something we probably would put in the main grpc-go repo, and we don't have time to implement for now. You can find another minimal implementation here: https://github.com/googleapis/google-api-go-client/blob/3f4d679d4dae5de7ce124a7db68ef5147c9a3fa2/transport/grpc/pool.go. Ideally it would keep track of the state of the ClientConns and skip the non-READY ones, but that may not be a strict requirement for you either. |
Thanks @dfawley for the feedback.
Could you provide the rough timeline on when the resolve API can be stabilized, and which grpc-go version?
I think we need to do some investigation & PoC firstly. I do not have time to dig into it for now. So labelled this issue with "help wanted". |
Hi @ahrtr I am interested in this and will provide a minimal working example/POC soon. After that, I think we can go through some any necessary processes like design, collect must to have / nice to have requirements, test verification as success criteria before the implementation, production readiness check etc before the actual migration. For example: Must to have
Nice to have
|
Thanks @chaochn47 . Assigned to you. |
2023-06-08 update: I took a little deeper look today and found out that the generated gRPC API is outdated most likely because of #14533 etcd/api/etcdserverpb/rpc.pb.go Lines 6509 to 6520 in b4f49a5
NewKVClient(cc grpc.ClientConn) could have been written with NewKVClient(cc grpc.ClientConnInterface) so that the proposed ConnPool interface and its implementation roundRobinConnPool can be passed into it for customization.
This latter So I can start looking into |
Just discovered etcd/client/v3/credentials/credentials.go Line 37 in 9e1abba
|
The breaking changes are upcoming (within ~6 months?), but I'm pretty sure we can find a way to enable a migration path that doesn't break suddenly in a single version, and provide a couple releases of overlap. Full details haven't been planned, but some changes are already underway (pending PRs: grpc/grpc-go#6471 and grpc/grpc-go#6481) |
We need to bump both protobuf and grpc go plugin eventually. But is this task blocked by it? EDIT: just noticed that your following comment(pasted below). Indeed, the outdated grpc go plugin has some impact on this task. But it isn't a big problem, we can also change grpc.ClientConnInterface to
|
Thanks @dfawley for the feedback. It seems that the already planed items in grpc/grpc-go#6472 will not impact etcd at all. But as you mentioned But etcd's use of the grpc-go's resolver package is really very simple and basic, the golang source file has just dozens of lines of code. Please also see #15145 (comment). Each time when there is any change (e.g. adding or removing server, or update server's address) on the backend servers, etcd client will construct a new resolver.State object which contains the latest list of server addresses, and then call (*Resolver) UpdateState. Do you still think grpc/grpc-go#6472 might break it in future?
It's non-trivial effort. If we follow this approach, then we might want to create a separate small project something like Also reference: |
Good catch. Just raised a PR to remove it. #16358 |
Agreed with @ahrtr's point. I think the essential etcd usage of this experimental resolver API is built on top of manual resolver. It's quite simple. gRPC-go should be able to support in my humble opinion. (Even though it is marked as experimental indicating it's subject to change in the future). There might be other experimental usages like |
No, I am just hesitant if we go down in this route proposed in #15145 (comment) as I am implementing, it is essentially re-invent what gRPC-go implements between ClientConn and SubConn about state synchronization, health checking, etc.. |
Since the gRPC resolver package is still experimental, so we don't need to rush to make the change for now. |
Hi @ahrtr Based on recent PoC of gRPC LB health check and outlier detection balancer integration with etcd client, I propose not to remove the usage of gRPC resolver & balancer.
I favor to keep the opportunity of improving etcd client with better availability while keeping an eye on the gRPC API changes. Note there is an ongoing project in gRPC-go to Promote Resolver/Balancer API to Stable |
Yes, just as I mentioned in #15145 (comment), etcd's usege of the grpc-go's resolver package is really very simple and basic; and it's non-trivial effort to re-invent the wheel. So there is no plan to remove the gRPC resolver & balancer. But we need to followup the grpc's change, and may need to make change something like #15145 (comment) |
+100 Totally agree |
Another deprecated API usage.
|
Also consider that you shouldn't use "insecure" credentials at all. Tests should be okay, though they should also be OK to use local credentials. Production code should probably also prefer local credentials (or TLS/etc), which verifies that the address is local and not over a network: https://pkg.go.dev/google.golang.org/[email protected]/credentials/local#NewCredentials Yes, this is unfortunately also experimental. I believe we can promote it to stable, as I'm not aware of any issues. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 21 days if no further activity occurs. Thank you for your contributions. |
This is still very relevant for us and for your users. |
What would you like to be added?
etcd is depending on some experimental APIs of grpc-go, such as resolver. Once these APIs change in future, it might break etcd. So we should try to remove the dependency on any experimental APIs; instead, let's try to use stable APIs.
References:
Why is this needed?
Improve stability
The text was updated successfully, but these errors were encountered: