metallb 一致性实现和故障切换 (二)

引言

上篇文章中,我描述了metallb一个项目上碰到的问题,引发我对metallb vip 如何实现的源码追溯,但是并没有去深究 metallb speaker 的一致性 memberlist 是怎么实现的,以及 gossip 协议。所以就这个问题的契机,继续往下挖。

gossip 协议

cloud.tencent.com/developer/a...

kaiyuan.me/2015/07/08/...

gossip 协议,这两篇文档讲得很好了。

gossip 的实现 memberlist 库

memberlist 是HashiCorp公司出品的go语言开发库,使用基于Gossip协议管理集群成员和成员失败检测。咱们本文的主题就是memberlist。严格说起来,memberlist是基于Gossip协议变种实现的,它的指导论文是康奈尔大学计算机科学系Abhinandan Das, Indranil Gupta, Ashish Motivala在2002年发表的《SWIM:Scalable Weakly-consistent/Infection-styleProcess Group Membership Protocol》。

create

Create 初始化:

  1. newMemberlist 会根据给定的配置创建一个新的 Memberlist 的数据结构。
  2. schedule 开启协程 probe 协程, push/pull 协程,gossip 协程,其中
  • probe 协程:进行节点探测,一个个去探测(不是随机)节点,默认探测间隔 1s ,超时时间 500ms 。
  • push/pull 协程:进行节点状态、用户数据同步,随机找到一个节点,将本地所有节点状态和对端所有节点状态互换,然后合并。因为是全量同步,占用资源大,所以频率并不高,默认 30s 一次。
  • gossip 协程:从广播队列中获取 gossip 协议的报文,随机选 nodes 进行 udp 广播,gossip 协议的报文,发送gossip 报文频率默认 200ms。

join 加入集群

用于将现有的Memberlist加入到一个集群中,通过联系所有给定的主机并执行状态同步

  1. 列出所有需要同步状态的主机,执行pushPullNode
  2. pushPullNode用于交换本节点和远程节点的状态,初始的时候 Memberlist 只包含自己的状态,因此执行此操作将使远程节点意识到自己的存在,从而有效加入集群。
  3. 返回成功联系到的主机数量,如果无法联系到任何主机则返回错误,表示该节点未能加入集群。

节点之间的交互细节

从 Create 里面创建的三个协程说起:

Probe 协程

schedule 里面开启 1s 一次的探测,

从m.nodes里面每次选取一个节点去探测,skip 掉 Dead 或者 Left 状态的节点,进入核心函数 probeNode

probeNode 流程我大致列了下:

  1. 根据健康意识调整 probe 的周期,如果侦查出现问题,会降低探测频率。
  2. 准备 ping 消息并设置 ack 处理器。
  3. 发送 ping 消息到节点,如果节点状态为 Alive, 则通过 UDP 发送 ping 消息; 否则,将 ping 消息和 suspect 消息组合成一个复合消息,通过UDP 发送。附加 supect 的原因是为了让对端尽快否认。
  4. 等待响应或者超时,如果收到 ack 消息,表示探测成功,函数返回。如果未收到,进入失败处理。
  5. 失败处理:获取一些随机的alive 节点,发送间接 ping 从这些节点到探测失败节点。 同时尝试TCP 直接和探测失败节点建立连接,等待ack 或者超时,如果收到 ack,表示探测成功,函数返回。
  6. 如果继续失败,执行suspectNode操作。suspectNode的会启动suspect 计时器,然后广播suspect消息。如果一定时间内还没等到其他节点的确认信息,可疑计时器会触发超时回调。进而进入deadNode
  7. deadNode 广播目标节点dead的消息。并触发回调NotifyLeave。

补充下,5步的 suspect 计时器有两种算法:

lua 复制代码
min := suspicionTimeout(m.config.SuspicionMult, n, m.config.ProbeInterval)
max := time.Duration(m.config.SuspicionMaxTimeoutMult) * min
    

如果 节点数大于 SuspicionMult 使用 max 计时,如果小于 SuspicionMult 使用 min计时。

push/pull 协程

交换和远程节点的节点状态,还有用户自定义信息。

gossip 协程

gossip 用来发送广播报文,上面 probeNode 流程中发送的 suspect 或者 dead 这些广播报文,并不是立刻发送的,而是先放进 broadcast 的消息队列里面,默认情况下 gossip 协程以 200ms 一次的频率调用getBroadcasts 去取这个消息,然后随机kRandomNodes选 node广播出去。

相关推荐
有意义8 分钟前
从零搭建:json-server+Bootstrap+OpenAI 全栈 AI 小项目
前端·后端·llm
汤姆yu1 小时前
基于springboot的民间救援队救助系统
java·spring boot·后端·救援队
IT_陈寒1 小时前
React性能优化实战:这5个Hooks技巧让我的应用快了40%
前端·人工智能·后端
韩立学长2 小时前
基于Springboot的智慧管网灌溉系统i1agupa7(程序、源码、数据库、调试部署方案及开发环境)系统界面展示及获取方式置于文档末尾,可供参考。
数据库·spring boot·后端
一 乐2 小时前
高校教务|教务管理|基于springboot+vue的高校教务管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·教务管理
August_._2 小时前
【MySQL】触发器、日志、锁机制 深度解析
java·大数据·数据库·人工智能·后端·mysql·青少年编程
BingoGo2 小时前
15 个 Eloquent 高级技巧,瞬间提升你的 Laravel 应用性能
后端·php
golang学习记3 小时前
用 Go + Redis + HTMX 手撸一个超快 URL 短链接服务 🚀
后端
codervibe3 小时前
Spring Boot 热启动配置实战:从手动重启到秒级反馈
spring boot·后端
skyeeeeee3 小时前
kubeadm安装k8s集群
后端·kubernetes