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

相关推荐
九圣残炎37 分钟前
【springboot】简易模块化开发项目整合Redis
spring boot·redis·后端
.生产的驴1 小时前
Electron Vue框架环境搭建 Vue3环境搭建
java·前端·vue.js·spring boot·后端·electron·ecmascript
爱学的小涛1 小时前
【NIO基础】基于 NIO 中的组件实现对文件的操作(文件编程),FileChannel 详解
java·开发语言·笔记·后端·nio
爱学的小涛1 小时前
【NIO基础】NIO(非阻塞 I/O)和 IO(传统 I/O)的区别,以及 NIO 的三大组件详解
java·开发语言·笔记·后端·nio
北极无雪1 小时前
Spring源码学习:SpringMVC(4)DispatcherServlet请求入口分析
java·开发语言·后端·学习·spring
爱码少年1 小时前
springboot工程中使用tcp协议
spring boot·后端·tcp/ip
2401_857622669 小时前
SpringBoot框架下校园资料库的构建与优化
spring boot·后端·php
2402_857589369 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
哎呦没11 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
_.Switch11 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j