DAOS引擎心跳健康检测-cart_swim(可扩展的弱一致性-感染式过程-组成员协议)

本文主要是介绍DAOS引擎心跳健康检测-cart_swim(可扩展的弱一致性-感染式过程-组成员协议),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

DAOS引擎心跳健康检测-cart_swim(可扩展的弱一致性-感染式过程-组成员协议)

术语

swim: Scalable Weakly-consistent Infection-style process group Membership Protocol, 可扩展的弱一致性-感染式过程-组成员协议

round-trip: 往返

简介

SWIM是DAOS引擎(rank)间的网络健康检测机制, 属于通信组件cart下的代码模块, SWIM是通过Gossip实现的Membership保持协议,也就是维护分布式系统节点的状态

DAOS 引擎在系统内通过称为 SWIM 的基于 gossip 的协议进行监控,该协议提供准确、高效和可扩展的故障检测。附加到每个 DAOS 目标的存储通过定期本地健康评估进行监控。每当本地存储 I/O 错误返回到 DAOS 服务器时,将自动调用内部健康检查过程。此过程将通过分析 IO 错误代码和设备 SMART/Health 数据来进行整体健康评估。如果结果是否定的,目标将被标记为有故障,并且此目标的进一步 I/O 将被拒绝并重新路由

特点:

  • 可伸缩性
  • 弱一致性
  • 感染性

SWIM 是一个成员协议,它帮助我们知道那些结点在集群中,帮助我们维护一个不断更新的健康结点列表

它将成员问题分成两个部分:失效检测 和 信息传播

失效检测 随机地向结点发送 ping 消息,并期待收到 ack 消息;如果没有收到 ack ,将向 k 个结点发送 ping-req 消息,借助他们来间接的进行探测。

失效检测 的一个优化是,首先是标记结点“有嫌疑”,在超时后再标记为“挂了”。

对于 信息传播 的优化是,让失效检测消息( ping、ping-req 和 ack)捎带上 成员变化 信息,而不是使用 IP广播 机制。

对于失效检测时间的优化是,采用轮流(round-robin)选择结点的方式,而不是随机选择。

因此,SWIM 协议具备如下优势:

可伸缩性:失效发现时间、误报率以及每个成员所需的消息收发负载与集群大小无关。成员状态变更信息的传播与集群大小呈对数关系(log n)

健壮性:协议是完全区中心化的,对于结点故障或网络分区具有容错能力。

易于部署和维护:新成员联络任何一个现有成员即可加入集群;而成员离开时,无需任何特别措施即可维持集群健康。

实现的简单性:协议中只定义了为数不多的状态和消息类型。而且点对点的结构,无需进行初始配置或在成员变更时进行维护。

成员协议, ping, ping-req, ack等捎带成员更新消息, 失效检测: 探测间隔 * 结点数

几个分布式对等应用程序需要所有参与进程的进程组成员信息的弱一致知识。SWIM 是一个通用软件模块,为大型流程组提供此服务。SWIM 努力的动机是传统心跳协议的不可扩展性,这些协议要么施加随组大小二次增长的网络负载,要么在检测过程崩溃时牺牲响应时间或误报频率。本文报告了 SWIM 子系统在大型商用 PC 集群上的设计、实施和性能。与传统的心跳协议不同,SWIM 将成员协议的故障检测和成员更新分发功能分开。通过有效的对等定期随机探测协议监控流程。首次检测到每个进程故障的预期时间和每个成员的预期消息负载都不会随组大小而变化。有关成员资格更改的信息,例如进程加入、退出和失败,通过 ping 消息和确认的捎带传播。这导致了强大而快速的感染方式(也是流行或八卦方式)的传播。通过修改协议以允许组成员在将进程声明为失败之前对其进行怀疑,从而降低了 SWIM 系统中的错误故障检测率——这允许系统发现并纠正错误的故障检测。最后,该协议保证了检测故障的确定性时间限制。展示了 SWIM 原型的实验结果。我们讨论了设计在 WAN 范围内的可扩展性

心跳:

传统的诸如heartbeats这种membership protocols,每个node周期性地向网络中的所有其他节点发送heartbeat来表示自己是alive的,如果peer超过指定interval没有收到node的heartbeart则该node被认定为dead。这种方式适用于小型网络,其发送的heartbeart数量为O(n^2),当网络中有成千上万的node时则会造成巨大的网络负担;SWIM采用Infection-Style dissemination感染型传播来解决这个问题

假设您要求构建一个类似于Cassandra的分布式数据库。您的存储系统将存储和处理在大量商品服务器上运行的大量数据。换句话说,您的系统将依靠 100 多个节点的力量来管理数据。

在这个规模上,失败将是常态,而不是例外。即使我们假设一个节点持续 1000 天(大约 3 年),在 500 个节点的集群中,每 2 天就会出现一次故障。

为了处理这种情况,您需要一个故障检测服务,它除了检测故障节点外,还使所有非故障进程与处于活动状态的进程保持同步。在这篇博文中,我们将介绍一种称为 SWIM 的协议并了解其内部工作原理。

swim成员协议为组中的每个进程提供了一个本地维护的列表,称为成员列表,该列表包含组中的其他非故障进程。

因此,该协议执行两项重要任务 -

  • 检测失败,即如何识别哪个进程失败以及
  • 传播信息,即如何将这些故障通知系统中的其他进程。

不言而喻,成员协议在检测故障方面应该是可扩展的、可靠的和快速的。成员协议的可扩展性和效率主要由以下属性决定

  • 完整性:每个失败的进程最终都会被检测到吗?
  • 故障检测速度:故障与非故障进程检测到的平均时间间隔是多少?
  • 准确性:流程被归类为失败的频率,实际上是非故障的(称为误报率)?
  • 消息负载:每个节点产生多少网络负载,是否均匀分布?

理想情况下,人们会想要一个完全 100% 准确的协议,这意味着检测到每个错误的过程,没有误报。然而,与分布式系统中的其他权衡一样,存在一个不可能的结果,即无法通过异步网络保证 100% 的完整性和准确性。因此,大多数成员协议(包括 SWIM)以准确性换取完整性,并试图将误报率保持在尽可能低的水平。

SWIM 故障检测器

SWIM 故障检测器使用两个参数——一个协议周期T和一个整数k,它是故障检测子组的大小。

在这里插入图片描述

SWIM 故障检测

上图显示了协议的工作原理。在每个T时间单位之后,进程 M i从其成员列表中选择一个随机进程 - 比如说 M j - 并向它发送一个ping。然后它等待来自 M j的ack。如果在预先指定的超时时间内没有收到确认,M i通过随机选择目标间接探测 M j并使用它们向M j发送ping。然后,这些目标中的每一个都代表 M i向 M j发送一个ping ,并在收到一个ack时k``k通知 M i。如果由于某种原因,这些进程都没有收到ack,则 M i将 M j声明为失败并将更新移交给传播组件(如下所述)。

SWIM 与其他心跳/八卦协议之间的关键区别因素是 SWIM 如何使用其他目标到达 M j以避免在 M i和 M j之间的网络路径上出现任何拥塞。

SWIM 传播组件

传播组件只是将故障更新多播到组的其余部分。所有收到此消息的成员都将 M j从其本地成员列表中删除。关于新成员或自愿离开的信息以类似的方式被多播成员。新加入成员或自愿离开成员的信息以类似方式多播。

改进

感染式传播——在更健壮的 SWIM 版本中,传播组件不依赖于不可靠和低效的多播,而是在故障检测器协议发送的pingack消息上捎带成员资格更新。这种方法被称为感染式(因为这类似于八卦或人群中的流行病)的传播,其优点是具有较低的数据包丢失和更好的延迟。

怀疑机制- 尽管 SWIM 协议通过 pingk节点来防止两个节点之间出现拥塞的情况,但仍然有可能完全健康的进程 M j变得缓慢(高负载)或由于周围的网络分区而暂时不可用本身,因此被协议标记为失败。

每当基本 SWIM 检测到故障时,SWIM 通过运行称为 Suspicion 子协议的子协议来缓解这种情况。在该协议中,当 M i发现 M j没有响应(直接和间接)时,它将 M j标记为嫌疑人,而不是将其标记为失败。然后它使用传播组件将此消息 M j :发送suspect到其他节点(感染式)。任何后来发现 M j响应ping的进程都会取消标记怀疑并用 M j :alive消息感染系统。

有时间限制的完整性——基本的 SWIM 协议在平均恒定数量的协议周期内检测故障。虽然保证最终检测到每个故障进程,但由于目标节点的随机选择,在将 ping 发送到故障节点之前可能会有相当大的延迟。

SWIM 建议的一个简单改进是通过维护一组已知成员并以循环方式选择*ping目标。*数组完全遍历后,随机打乱,继续处理。这为同一目标的连续选择之间的时间单位提供了有限的上限。

结论

SWIM 协议已在许多分布式系统中使用。一个使用 SWIM 的流行开源系统是Serf,它是Hashicorp为集群成员提供的分散式解决方案。该文档对底层架构进行了相当清晰的演练。Hashicorp 的好心人也在Github上开源了他们的实现。对于那些通过阅读代码可以更好地理解的人,请务必检查一下。

最后,这篇博文特意保留了数学以使高级思想变得简单,但如果您有兴趣深入研究,请务必阅读本文以更好地了解误报率的上限、检测故障的平均时间和网络负载

流程图

状态机:

在这里插入图片描述

源码流程图

在这里插入图片描述

源码分析

版本: daos 2.0.1, 新版本对swim改动较大

swim使用tag1:

tag 0 is used by the metadata service handling pool and container operations.
tag 1 is used for cross-server monitoring (SWIM).
tags 2 to [#targets + 1] is used by DAOS targets (one tag per target].
tags [#targets + 2] to [#targets + #helpers + 1] is used by helper service threads.

源码位置:

src\include\cart\swim.h
src\cart\swim\swim.c

在这里插入图片描述

  • swim初始化中(swim_init(SWIM_ID_INVALID, &crt_swim_ops, NULL))添加rank成员, crt_swim_rank_add

  • 在处理回调函数中执行状态机处理: crt_swim_progress_cb -> swim_progress, 发送PING包, 更新质疑状态, 更新PING状态等

  • 每秒检测一次, 如果PING不通(900毫秒), 先提出质疑(8秒), 请第三方间接PING, 最后标记为DEAD状态

  • 参考日志

    swim_prot_period_len:1000,swim_suspect_timeout:8000,swim_ping_timeout:900,sc_next_tick_time:2037074
    

其他参考流程

故障流程 心跳 swim swim_progress
c -> s
kill s
swim ping timeout
swim suspect
swim suspect timeout
swim confirm dead swim_member_dead
notify dead swim_updates_notify -> crt_swim_notify_rank_state
group_map_update to leader
group_map update bcast
making Excluded

参考

IEEE: https://ieeexplore.ieee.org/document/1028914

论文: https://github.com/ssbandjl/distributed-computing/blob/master/dsn02-swim.pdf

swim增加状态: https://daosio.atlassian.net/browse/DAOS-11274, https://github.com/daos-stack/daos/pull/10435

添加新的状态机状态 SCS_IPINGED,用于等待间接 ping 截止时间

晓兵

博客: https://logread.cn | https://blog.csdn.net/ssbandjl

weixin: ssbandjl

公众号: 云原生云

DAOS IO全路径详解(视频)
DAOS 项目简介(视频)
欢迎对DAOS, SPDK, RDMA等高性能技术感兴趣的朋友加入[DAOS技术交流(群)]

这篇关于DAOS引擎心跳健康检测-cart_swim(可扩展的弱一致性-感染式过程-组成员协议)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/418844

相关文章

Spring配置扩展之JavaConfig的使用小结

《Spring配置扩展之JavaConfig的使用小结》JavaConfig是Spring框架中基于纯Java代码的配置方式,用于替代传统的XML配置,通过注解(如@Bean)定义Spring容器的组... 目录JavaConfig 的概念什么是JavaConfig?为什么使用 JavaConfig?Jav

JAVA SpringBoot集成Jasypt进行加密、解密的详细过程

《JAVASpringBoot集成Jasypt进行加密、解密的详细过程》文章详细介绍了如何在SpringBoot项目中集成Jasypt进行加密和解密,包括Jasypt简介、如何添加依赖、配置加密密钥... 目录Java (SpringBoot) 集成 Jasypt 进行加密、解密 - 详细教程一、Jasyp

Java通过ServerSocket与Socket实现通信过程

《Java通过ServerSocket与Socket实现通信过程》本文介绍了Java中的ServerSocket和Socket类,详细讲解了它们的构造方法和使用场景,并通过一个简单的通信示例展示了如何... 目录1 ServerSocket2 Socket3 服务器端4 客户端5 运行结果6 设置超时总结1

MongoDB搭建过程及单机版部署方法

《MongoDB搭建过程及单机版部署方法》MongoDB是一个灵活、高性能的NoSQL数据库,特别适合快速开发和大规模分布式系统,本文给大家介绍MongoDB搭建过程及单机版部署方法,感兴趣的朋友跟随... 目录前言1️⃣ 核心特点1、文档存储2、无模式(Schema-less)3、高性能4、水平扩展(Sh

MySQL中存储过程(procedure)的使用及说明

《MySQL中存储过程(procedure)的使用及说明》存储过程是预先定义的SQL语句集合,可在数据库中重复调用,它们提供事务性、高效性和安全性,MySQL和Java中均可创建和调用存储过程,示例展... 目录概念示例1示例2总结概念存储过程:在数据库中预先定义好一组SQL语句,可以被程序反复调用。

MySQL存储过程实践(in、out、inout)

《MySQL存储过程实践(in、out、inout)》文章介绍了数据库中的存储过程,包括其定义、优缺点、性能调校与撰写,以及创建和调用方法,还详细说明了存储过程的参数类型,包括IN、OUT和INOUT... 目录简述存储过程存储过程的优缺点优点缺点存储过程的创建和调用mysql 存储过程中的关键语法案例存储

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Redis中Set结构使用过程与原理说明

《Redis中Set结构使用过程与原理说明》本文解析了RedisSet数据结构,涵盖其基本操作(如添加、查找)、集合运算(交并差)、底层实现(intset与hashtable自动切换机制)、典型应用场... 目录开篇:从购物车到Redis Set一、Redis Set的基本操作1.1 编程常用命令1.2 集

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

k8s中实现mysql主备过程详解

《k8s中实现mysql主备过程详解》文章讲解了在K8s中使用StatefulSet部署MySQL主备架构,包含NFS安装、storageClass配置、MySQL部署及同步检查步骤,确保主备数据一致... 目录一、k8s中实现mysql主备1.1 环境信息1.2 部署nfs-provisioner1.2.