这篇blog讨论了etcd选举机制的实现细节,以及应该如何利用etcd选举来避免脑裂。 如果仅仅是需要知道自己是否主节点,那么只需要Campaign指令,当Campaign返回时,自己便成为主节点。 在一个分布式系统中,是没有同时这个概念的,假设Campaign指令的返回tcp包因丢包多次重试,晚了1分钟才到达Campaigner,那么Campaign返回的同时,这个...
// If the context is 'context.TODO()/context.Background()', the Campaign // will continue to be blocked for other keys to be deleted, unless server // returns a non-recoverable error (e.g. ErrCompacted). // Otherwise, until the context is not cancelled or timed-out, Campaign will ...
SIGTERM或session过期而退出* https://github.com/etcd-io/etcd/blob/master/etcdctl/ctlv3/command/elect_command.go*/funccampaign(c *clientv3.Client, electionstring, propstring)error{//NewSession函数中创建了一个lease,默认是60s TTL,并会调用KeepAlive,永久为这个lease自...
Campaign 方法是 ETCD client 封装的一个选主方法,如果竞选成为主节点成功则正常返回,如果不成功则会阻塞在这个方法里面,等待前面的主节点失效删除key-value,然后自己成功才从方法退出。 func (e *Election) Campaign(ctx context.Context, val string) error { s := e.session client := e.session.Client() ...
核心是利用`Campaign`API[2], 这里面有etcd的事务,源码值得一看, 对应到原始的etcdctl操作:etcdctl put ‐‐lease=41ce93a9f806a53b /merc/leader/41ce93a9f806a53b 127.0.0.1:8686注意:key= /merc/leader/41ce93a9f806a53b, value= 127.0.0.1:8686, 租约是41ce93a9f806a53b(持续保活的租约) ...
我们可以继续来分析campaign方法的具体实现,下面就是删去预选举相关逻辑后的代码: // https://sourcegraph.com/github.com/etcd-io/etcd@1cab49e/-/blob/raft/raft.go#L730-766 func (r *raft) campaign(t CampaignType) { r.becomeCandidate()
e1 := concurrency.NewElection(s1,"my-election")gofunc(){// 参与选举,如果选举成功,会定时续期iferr := e1.Campaign(context.Background(), *serverName); err !=nil{ fmt.Println(err) } }() masterName :=""gofunc(){ ctx, cancel := context.WithCancel(context.TODO())defercancel() ...
* 未当选leader前,会一直阻塞在Campaign调用 * 当选leader后,等待SIGINT、SIGTERM或session过期而退出 * https://github.com/etcd-io/etcd/blob/master/etcdctl/ctlv3/command/elect_command.go */funccampaign(c*clientv3.Client,electionstring,propstring)error{//NewSession函数中创建了一个lease,默认是60s TTL,...
func campaign(c *clientv3.Client, election string, prop string) { for { //gets the leased session for a client s, err := concurrency.NewSession(c, concurrency.WithTTL(15)) if err != nil { log.Println(err) continue } //returns a new election on a given key prefix e := concurrenc...
tickElection的处理逻辑是给自己发送一个MsgHup的内部消息,Step函数看到这个消息后会调用campaign函数,进入竞选状态。// tickElection is run by followers and candidates after r.electionTimeout.func (r *raft) tickElection() { r.electionElapsed++ if r.promotable() && r.pastElectionTimeout() { ...