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

相关推荐
小_太_阳1 小时前
Scala_【1】概述
开发语言·后端·scala·intellij-idea
智慧老师1 小时前
Spring基础分析13-Spring Security框架
java·后端·spring
搬码后生仔2 小时前
asp.net core webapi项目中 在生产环境中 进不去swagger
chrome·后端·asp.net
凡人的AI工具箱2 小时前
每天40分玩转Django:Django国际化
数据库·人工智能·后端·python·django·sqlite
Lx3523 小时前
Pandas数据重命名:列名与索引为标题
后端·python·pandas
小池先生3 小时前
springboot启动不了 因一个spring-boot-starter-web底下的tomcat-embed-core依赖丢失
java·spring boot·后端
百罹鸟3 小时前
【vue高频面试题—场景篇】:实现一个实时更新的倒计时组件,如何确保倒计时在页面切换时能够正常暂停和恢复?
vue.js·后端·面试
小蜗牛慢慢爬行4 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
wm10435 小时前
java web springboot
java·spring boot·后端
龙少95437 小时前
【深入理解@EnableCaching】
java·后端·spring