您当前的位置:首页 >>  头条 >  >> 
使用etcd实现Master的选举功能-世界快看
来源: 博客园      时间:2023-04-20 19:20:35


(相关资料图)

背景

说起master选举,最开始想到的可能就是zookeeper,但有些场景zookeeper的使用过于繁重和复杂,又由于etcd是基于Raft的分布式K/V存储,强一致性的K/V读写是核心。所以造就了etcd可以用于master的选举的场景。

原理

etcd clientv3 concurrency对选举进行了封装

import github.com/coreos/etcd/clientv3/concurrency

上篇文章介绍了etcd使用txn实现分布式锁,而节点选举也要依靠Txn进行创建key的CAS操作zookeeper是利用创建临时有序节点的方式,etcd也同样的是在prefix path下创建相应的key,并且key的revision也是有序。同样也是通过watch机制进行通知。

应用

//封装type etcdLeader struct {sess *concurrency.Session    //会话 客户端的租约会话,会做KeepAliveelec *concurrency.Election    //选举}func Campaign(ctx context.Context, client *clientv3.Client, prefix, value string) (*etcdLeader, error) {if value == "" {value = fmt.Sprintf("%s-%d", MyHostName, timestampMs())}s, err := concurrency.NewSession(client)if err != nil {return nil, fmt.Errorf("failed to generate session: %v", err)}prefix = "/openresty/" + "-concurrency/" + strings.TrimPrefix(prefix, "/")elec := concurrency.NewElection(s, prefix)return &etcdLeader{sess: s,elec: elec,}, elec.Campaign(ctx, value) // blocked until elected}//elec.Campaign 会参加选举,直到它被选中、发生错误或上下文被取消// 调用elec.Proclaim 常用来检测当前主节点是否生效func (l *etcdLeader) Proclaim(ctx context.Context, value string) error {if l.elec == nil {return fmt.Errorf("already closed")}if value == "" {value = fmt.Sprintf("%s-%d", MyHostName, timestampMs())}return l.elec.Proclaim(ctx, value)}//调用elec.Resign 退出masterfunc (l *etcdLeader) Resign(ctx context.Context) error {if l.elec == nil {return nil}defer l.sess.Close()defer func() {l.elec = nill.sess = nil}()return l.elec.Resign(ctx)}

测试

//模拟进程处理func process(processID string) {cli, err := getEtcdCli("open")  //获得cliif err != nil {fmt.Println(err)panic(processID)}ctx := context.Background()maintainer, err := Campaign(context.Background(), cli, "process", "")  //会阻塞,直到该节点选为masterif err != nil {fmt.Println("process " + processID + " Campaign err" + err.Error())return}fmt.Println(processID + "is maintainer")ticker := time.NewTicker(time.Second)count := 0defer ticker.Stop()for {select {case <-ctx.Done():err = maintainer.Resign(context.Background())  //超时退出if err != nil {fmt.Printf("error occured when resign lfe_sync: %v", err)}returncase <-ticker.C:err = maintainer.Proclaim(ctx, "") if err != nil {fmt.Printf("error occured when proclaim lfe_sync: %v", err)maintainer.Resign(ctx)return}count++//do sthfmt.Println("processID ", processID+" ", count)if count == 5 {      //主动退出err = maintainer.Resign(context.Background())if err != nil {fmt.Printf("error occured when resign lfe_sync: %v", err)}return}}}}

总结与思考

如果从Campaign源码可以看出,比起上一篇利用txn实现分布式锁的实现,选主增加watch机制,减少轮训获取锁的过程。在本场景中选主和分布式锁的使用并没有什么差别,只是选主减少轮训,性能更好。本次代码地址:https://github.com/zhaoshoucheng/hodgepodge/blob/main/etcd/master.go

标签:

上一篇:

下一篇:

  • “谢谢选择我做你的妈妈!” 这封信请18年后查收

      “谢谢选择我做你的妈妈!” 这封信请18年后查收  扬子晚报讯(通讯员 刘威 记者 朱鼎兆)小时候,母亲常常在家里给我们留字条,

    来源:      时间:2022-05-09
  • 跟新冠病毒“赛跑” 他要让机器人完成核酸检测

      跟新冠病毒“赛跑” 他要让机器人完成核酸检测  经常学生们还不知道我怎么想的时候,我就把自己否定了。工作中需要有自我否定的勇气

    来源:      时间:2022-05-09
  • 助力无接触配送 上海无人车“上岗”

      助力无接触配送 上海无人车“上岗”  【疫情防控新举措】  科技日报讯 (记者符晓波)眼下,上海疫情蔓延趋势得到有效控制,不少

    来源:      时间:2022-05-09
  • “态靶辨治” 帮助患者快速转阴

      “态靶辨治” 帮助患者快速转阴  近日,随着患者清零,吉林省长春市北湖奥体中心篮球馆方舱医院等多个方舱陆续“休舱”,各医疗队也

    来源:      时间:2022-05-09
  • 四省市联合医疗队为患者全方位“解忧”

      四省市联合医疗队为患者全方位“解忧”  【同心守沪抗疫】  在上海城市足迹馆定点医院的宣传墙上,各类慢性病、基础病的健康宣教手

    来源:      时间:2022-05-09
  • 周美亮: 搜寻野生荞麦的“追种人”

      周美亮: 搜寻野生荞麦的“追种人”  ◎本报记者 马爱平  一走进位于国家作物种质库新库内的中国农业科学院作物科学研究所研究员

    来源:      时间:2022-05-09
  • 防晒“神器”竟是珊瑚“杀手”

      防晒“神器”竟是珊瑚“杀手”  科技日报北京5月8日电 (实习记者张佳欣)珊瑚礁是地球上生物最丰富、最具经济价值的生态系统之一。

    来源:      时间:2022-05-09

X 关闭

X 关闭