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广播出去。

相关推荐
司南-7049几秒前
Dense结构下的 大模型系统架构研究
服务器·人工智能·后端
GISer_Jing1 分钟前
AI全栈转型_TS后端学习路线
前端·人工智能·后端·学习
薪火铺子2 分钟前
Spring Security 6.x 实战指南
java·后端·spring
全栈小刘6 分钟前
Claude Code 为什么这么顺?Anthropic 最新复盘:真正撑住它的不是模型,而是缓存
后端
BING_Algorithm12 分钟前
一文搞定 AOP 所有核心知识点
spring boot·后端·spring
Cyan_RA926 分钟前
SpringMVC 请求数据绑定与参数映射 详解
java·后端·spring·mvc·springmvc·映射请求数据
GISer_Jing31 分钟前
AI全栈工程师知识体系全景:从前后端核心架构到落地项目全拆解
前端·人工智能·后端·ai编程
longxibo33 分钟前
【Flowable 7.2 源码深度解析与实战-前言】
java·后端·流程图
全栈小刘39 分钟前
ChatGPT账号打通OpenClaw?Codex又整了个“电子宠物”,开发者这下真坐不住了
后端
陈随易1 小时前
bun将会支持Bun.image,你怎么看?
前端·后端·程序员