-
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
client: add a mechanism for various endpoint selection mode #4030
Conversation
type EndpointSelectionMode int | ||
|
||
const ( | ||
// EndpointSelectionDefault: pick an endpoint in a random manner |
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.
Please make comments full sentences as EndpointSelectionDefault is to pick an endpoint in a random manner.
767491e
to
6eee6f0
Compare
@gyuho fixed the style of comments |
Thanks @mitake . I want to benchmark this function tomorrow, to double check in my side. Thanks for working on this. |
|
||
const ( | ||
// EndpointSelectionDefault is to pick an endpoint in a random manner. | ||
EndpointSelectionDefault EndpointSelectionMode = iota |
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.
EndpointSelectionRandom?
Let's fix these style issues and remove the "unnecessary" feature. Thanks a lot. |
6eee6f0
to
53dabda
Compare
@xiang90 Removed |
Yeah, I just want to confirm that I see the same performance gain as you. |
gofmt seems to be failing. |
53dabda
to
0d01926
Compare
@xiang90 oops, sorry for that. Fixed it. |
0d01926
to
7616765
Compare
updated commit message |
|
||
func (l *membersAPIActionLeader) HTTPRequest(ep url.URL) *http.Request { | ||
u := v2MembersURL(ep) | ||
req, _ := http.NewRequest("GET", u.String()+"/leader", 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.
Please follow the style of the other functions: https://github.com/coreos/etcd/blob/eaaf98348ce433ff0a8ff94552649af215754df3/client/members.go#L216
I also suggest splitting out const leaderSuffix = "leader"
.
@xiang90 @jonboulle I tested this in a simple 3-member cluster. With 100 keys of random bytes:
So current client takes longer per loop (one put request + one get request to the key from the put request). Looks good. Will wait on @mitake's fix for @jonboulle's feedback. |
7616765
to
5d78417
Compare
c716ecb
to
aa52a42
Compare
@jonboulle Can you go over @mitake's updates to your feedback? |
@@ -35,6 +35,7 @@ var ( | |||
ErrTooManyRedirects = errors.New("client: too many redirects") | |||
ErrClusterUnavailable = errors.New("client: etcd cluster is unavailable or misconfigured") | |||
errTooManyRedirectChecks = errors.New("client: too many redirect checks") |
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, please swap lines 37/38
I still feel a bit uneasy about this for long-lived clients. Maybe I'm just being overly paranoid, but it still seems like there are various opportunities for things to get into a weird state where it's not really a |
@jonboulle Like I said, I will view this as an acceptable client side optimization when choosing the initial member to talk with without any guarantees. If user does not enable auto-sync, it probably means nothing after any configuration changes. |
@jonboulle Another way is that etcd-server always piggy-back the leader addr as a hint. The client can always decide to switch to leader or not. That is what we did for etcd0 and some other systems do for reducing latency. |
Current etcd client library chooses a default destination node from every member of a cluster in a random manner. However, requests of write and read (for consistent results) need to be forwarded to the leader node as the nature of Raft algorithm. If the chosen node is a follower, additional network traffic will be caused by the forwarding from follower to leader. Mainly for reducing the forward traffic, this commit adds a new mechanism for various endpoint selection mode to the client library which can be configured with client.Config.SelectionMode. Currently, two modes are provided: - EndpointSelectionRandom: default, same to existing behavior (pick a node in a random manner) - EndpointSelectionPrioritizeLeader: prioritize leader, for the above purpose I evaluated the effectiveness of the EndpointSelectionPrioritizeLeader with 4 t1.micro instances of AWS (3 nodes for etcd cluster and 1 node for etcd client). Client executes this simple benchmark (https://github.com/mitake/etcd-things/tree/master/prioritize-leader-bench), just writes 10000 keys. When SelectionMode == EndpointSelectionRandom (default), the benchmark needed 1 min and 32.102 sec to finish. When SelectionMode == EndpointSelectionPrioritizeLeader, the benchmark needed 1 min 4.760 sec.
aa52a42
to
a46ffc6
Compare
@jonboulle fixed based on your comment, PTAL. |
@jonboulle I understand your concern about the difference between actual server configuration and view from clients. However, such inconsistency can be caused by other reasons e.g. etcd cluster membership reconfiguration. Developers of long living clients must care about the inconsistency any way. I'd like to add this point to the docs. |
OK, thanks for your patience.
This would be great, thanks |
LGTM |
client: add a mechanism for various endpoint selection mode
Thanks Jon! Sincerely,
|
@xiang90 @gyuho @jonboulle thanks a lot for detailed review! |
This commit adds a document that provides tips of how to use the go client library. Currently it describes how to use the client.SelectionMode parameter that is added in etcd-io#4030.
This commit adds a document that provides tips of how to use the go client library. Currently it describes how to use the client.SelectionMode parameter that is added in etcd-io#4030.
This commit adds a document that provides tips of how to use the go client library. Currently it describes how to use the client.SelectionMode parameter that is added in etcd-io#4030.
This commit adds a document that provides tips of how to use the go client library. Currently it describes how to use the client.SelectionMode parameter that is added in etcd-io#4030.
This commit adds a document that provides tips of how to use the go client library. Currently it describes how to use the client.SelectionMode parameter that is added in etcd-io#4030.
Current etcd client library chooses a default destination node from
every member of a cluster in a random manner. However, requests of
write and read (for consistent results) need to be forwarded to the
leader node as the nature of Raft algorithm. If the chosen node is a
follower, additional network traffic will be caused by the forwarding
from follower to leader.
Mainly for reducing the forward traffic, this commit adds a new
mechanism for various endpoint selection mode to the client library
which can be configured with client.Config.SelectionMode.
Currently, two modes are provided:
a node in a random manner)
purpose
I evaluated the effectiveness of the EndpointSelectionPrioritizeLeader
with 4 t1.micro instances of AWS (3 nodes for etcd cluster and 1 node
for etcd client). Client executes this simple benchmark
(https://github.com/mitake/etcd-things/tree/master/prioritize-leader-bench),
just writes 10000 keys. When SelectionMode == EndpointSelectionRandom
(default), the benchmark needed 1 min and 32.102 sec to finish. When
SelectionMode == EndpointSelectionPrioritizeLeader, the benchmark
needed 1 min 4.760 sec.
This PR also adds a new Leader() call to MembersAPI for the EndpointSelectionPrioritizeLeader mode.