perseus: a fail-slow detection framework for cloud storage systems
摘要
最近新出现的 fail-slow 问题困扰着硬件和软件系统,其特点是受影响的组件虽然仍然在运行,但性能已经明显下降。为了解决这个问题,文本提出 perseus,一个实践中的‘fail-slow’存储设备探测框架。perseus创新性的采用了基于轻量级回归分析的模型,能够在驱动器粒度上快速定位并分析慢速故障。在 10 个月的时间内,perseus监控了 24 万块盘,发现了 304 个 fail-slow 的问题。隔离这些设备可以把节点级别的4 个 9 尾延时响应时间减少减少 48%。我们基于生产环境数据构建了大规模慢数据故障集(包含 4 万个正常盘和 315 个验证的 fail-slow 盘),并据此对慢故障盘展开了根因分析,涵盖调度算法缺陷、硬件设计瑕疵及环境因素等多类成因。我们已经公开了这个数据集。
1 介绍
大规模的存储系统容易受到各种故障的影响。学术界和工业界已在故障识别,检测和修复领域取得显著进展,涵盖停机故障,局部故障以及拜占庭故障等多种类型。
近来,fail-slow故障,也被称为 gray-failure 或者 limpware,正受到越来越多的关注。在 fail-slow故障里,软件或硬件组件的实际性能会低于预期。随着硬件性能的提升(Optane SSD,ZNS SSD)和软件栈(用户态驱动)的优化,fail-slow故障正在变得越来越容易检测和识别。最近的研究表明,fail-slow故障的发生率和 fail-stop 的几率相当。
准确的探测fail-slow故障是很有挑战的。性能差异有可能是内部因素引起的(SSD盘内的 GC)或者是外部的因素(负载的突发)都会有跟 fail-slow故障相似的症状。和 fail-stop 故障有明确的标准(软件 crash,数据丢失)不同,确定 fail-slow故障一般都靠经验。此外,fail-slow往往都是暂时的,很难让工程师去分辨,更不用说复现和解析根因了。
尽管已经有人在探测 fail-slow故障上做了一些工作,这些工作在大范围的云环境下就显得比较不够实用和比较低效。首先,这些方法需要访问源代码或者需要软件适配,但云厂商并不会碰用户代码。即使是内部的基础设施,插入一些代码片段也是相当耗费时间的,这些系统有可能跑了非常不同软件栈的服务。其次,现有的这些技术只能探测到节点级别,仍然需要人工才能定位到最后的原因。
本文我们分享了一个实用的,细粒度且通用的fail-slow检测框架,该框架广泛用于阿里巴巴云数据中心的各类服务和设备(仅需少量调整或无需调整)。首先我们分析了fail-slow在设备集群中的特征表现。随后我们探索了三种在实际场景中识别fail-slow的尝试,包括:
采用经验阈值
基于peer评估
IASO系统的重构
从之前的工作中吸取经验,我们设计和实现了 PERSEUS,一种非侵入式的fail-slow检测框架。通过映射关系,PERSEUS 能够自动为每个节点衍生出一个精确的和自适应的阈值,在监控中判断慢速条目。进而,基于慢速条目,PERSEUS 构建了相应的fail-slow事件和利用一个记分板的机制去评估这些事件的严重程度。
PERSEUS已经部署在云环境中超过 10 个月了,监控了高速增长的硬盘数达到了 30w片。PERSEUS 已经发现了超过 300 个fail-slow盘。通过隔离或者替换发现的fail-slow盘,我们显著的降低了节点的尾延时。95 分位,99 分位,9999 分位写延时分别下降了 31% 46% 48%。
我们对比了 PERSEUS和之前的一些 fail-slow检测方法。并发布了一个来自于生产环境的数据集,包含了 315 个确认的 fail-slow故障和大约 41k个集群上其他的盘,并构建了一个测试的 benchmark。benchmark评估显示 PERSEUS 使用了前面的方法,得到了准确率 99,召回率 100。我们也评估了 PERSEUS中组件的有效性和参数的敏感程度。结果显示,PERSEUS可以作为一个非侵入式的(基于监控日志),细粒度的(盘粒度),通用的(一组参数适用于所有场景)和准确的(高准确率和召回率)云计算存储系统的fail-slow检测框架。
我们对 fail-slow的成因进行了深入分析,发现其根本原因呈现多样化特征,主要包括以下几类:
调度机制缺陷:资源争用等非必要调度问题
硬件固有缺陷:以磁盘坏道为代表的物理层故障
环境干扰因素:温度波动和电力供应异常
本文做了以下的工作:
我们分享了在大规模数据中心做 fail-slow检测的三种失败的尝试
提出了 PERSEUS的设计,一个非侵入式的,细粒度的,通用的 fail-slow检测框架
我们组装了一个大规模的 fail-slow数据集,构建了一个 fail-slow测试 benchmark
我们提供了一个 fail-slow多个角度的深入根因分析
2 背景
2.1 系统架构
在本文,我们探索了在 alibaba 数据中心 做fail-slow的检测方法。这些 IDC 遍布于全球,每个IDC都包含了多个存储集群。在每个集群上都部署了一套分布式文件系统,用于支持一些特定的服务(比如块存储,NoSQL 或者大数据分析等)。每个集群都包含了技术个 rack ,最多有 200 个,每个 rack 包含几十个节点(最多 48 个)。有三种类型的存储节点:
全闪:一个节点包含 12 个 NVMe SSD
混合:一个节点包含 60-120 个 HDD用于数据存储,2 个 SSD作为写 cache
HDD:节点包含 70-80 个 HDD用于存储数据
默认每个节点上的盘是同一个型号的。每个节点上最多可以有 3 个盘被同一时间下掉修复。表一列了基础的信息和盘的分布。我们把盘的 model 用厂商-model来明明,比如,I-A意味着I厂商的 A model。


2.2 数据集描述
在我们的数据中心,每个节点上都部署了一个监控守护进程,用于收集运营数据,主要是盘的延时和吞吐。守护进程会计算 15 秒的平均延时然后把他们用时序数据的形式记录下来。守护进程每天跑3 个小时(9PM到 12AM)。每个盘每天产生 720 个 entry。总计,我们收集了 100 billion entry的数据,表 2 列举了日常的 9 种云服务的分布。
2.3 fail-slow故障的影响
fail-slow故障,特别是很短暂的那种,经常会被忽略或者误认为是性能的抖动。此外,存储栈通常有多层(软件,固件,硬件)的容错,比如重试和荣誉,静默了这些 fail-slow错误。然后在实际生产环境中,此类慢速故障对于 i/o 性能影响往往更为显著。接下来,我们会使用一个来自于对象存储有代表性的例子来说明fail-slow故障的影响和做 fail-slow故障探测的重要性。


上图显示了fail-slow hdd和其他 同节点 hdd的延时对比。垂直的线代表 fail-slow盘的隔离。fail-slow的盘有更高的读写时延(写2.06~3.65倍,读 1.01~1.50 倍),它的其他指标,比如 IOPS,相对稳定。
相比于时延,利用率更容易让我们找到 fail-slow故障。我们的监控系统发现受伤害的节点处理的写请求比其他节点要少很多。日志分析进一步表明,分布式对象存储系统的负载均衡器倾向于避免将写入请求分配给故障节点,这是由于该节点因尾部延迟过高而导致的异常重试太多。表二描述了p50 p90 p95 p99 p9999 的故障节点在剔除 fail-slow 盘之前和之后的百分位延时。隔离前 p9999 尾延时是隔离后中位数的 2.43 ~ 3.29倍。
这个例子,和其他相似的例子,都说明 fail-slow 的故障影响不只是有问题的盘,还影响了整个节点很长时间。这催促我们去探索在云环境下有效检测 fail-slow故障的方法。
3 不太成功的尝试和教训
本节我们描述了检测框架的设计目标和之前的几次不成功的尝试。
3.1 设计目标
从我们的角度,一个实用的fail-slow检测框架应该有这些属性:
非侵入式的,作为云服务商,我们既不能修改用户代码也不能让用户跑指定的软件版本或者软件栈。所以我们只能依靠外部的性能统计
细粒度的,fail-slow的根因诊断往往需要很久(几天或者几周),我们期望检测框架能够精确的定位到故障源头
精确度,框架需要具备足够的精确度和召回率,以避免在误诊的情况下进行不必要的诊断
通用,框架可以部署到 ssd 和 hdd 集群,以及很简单的修改就可以应用到对象存储块存储等服务中。
3.1 尝试1:分级阈值
方法:直观的,我们可以基于 SLO 对盘的访问延时设置一个硬的时间阈值。为了避免因 ssd 盘内部的 gc等原因导致的误判,我们进一步规定:只有当可疑驱动器的性能下降持续达到最小时间跨度(minimum slowdown span),才会被判定为慢故障驱动器。
局限:对设备延迟实施硬性阈值约束,显然具备非侵入性与细粒度管控特性。然而,基于阈值识别的慢故障检测准确率较低,因为延迟时间极易受工作负载影响。此处我们以块存储服务中某NVMe SSD的延迟与吞吐量追踪数据为例进行说明。
图 3 左边说明盘上延时的变化,水平线是阈值(45us)。右边是相应的吞吐。我们可以看到三个延时的尖峰。通过对比延时和吞吐,就可以明确得出就是工作负载引起了延时的抖动。
因此,这就面临了一个进退两难的困境,设置宽松的阈值容易将正常性能波动误判为 fail-slow事件,而严格的阈值又会导致大量的fail-slow故障案例无法被检测到。此外,如我们实验所示,由于延时波动程度和磁盘的型号以及工作负载密切相关,通过为不同场景精细调校多组阈值可能相当浪费人力。在实际应用中,我们将基于阈值的检测机制作为类似超时的最后防线来使用。
3.3 尝试 2:同级评估
方法:第一种方法的问题是没有自适应的探测阈值。为了解决这个问题,我们探索了peer evaluation的方法。这个做法背后的根因是,工作复杂在分布式存储系统上是均衡的,磁盘在一个节点上应该会是类似的负载压力。由于 fail-slow故障相对来说是比较罕见的,一个节点上大部分盘应该是正常的,所以我们可以通过比较同一个节点上其他盘的性能来定义 fail-slow。
具体流程如下:我们首先以 15 秒为间隔,在每个采样时间点计算节点级别的延时中位数,随后评估在监控事件窗口内是否存在持续表现异常(延时超过中位数两倍)的盘(异常事件占比超过 50%)。当检测到此类情况时,框架将 触发fail-slow故障告警,并滑动监控窗口开启下一轮评估。

图 4 提供了一个 peer evaluation检测的例子,红线是 fail-slow的盘,蓝色线是自适应的阈值(2 倍的中位数),灰色线是正常盘。三个阴影区域表示盘正处于 fail-slow 故障的三个监控窗口。
局限:peer evaluation 可以获取一个自适应的阈值,但是它需要更依赖经验的参数,比如慢的程度和监控窗口的大小。尽管可以在一些集群上为了特定的存储服务很好的调优了这些参数,但是如果将这种评估机制扩展到其他服务的不同盘的型号,工作量会变得极其庞大。举个例子,他需要工程师 2 个小时的试衣间去调整一个 300 个节点的集群,然后这些参数在另外一个集群同样的服务深圳同样的盘也会失败。
3.4 尝试 3:基于IASO的模型
方法:IASO是一个聚焦于慢速节点的 fail-slow 检测框架。IASO的设计原则是将软件超时机制转化为可量化的指标,以此建立 fail-slow的基准评估体系。然而直接用 IASO对我们来说并不合适。首先,IASO需要修改代码,通过捕捉软件层面的超时时间来试写 fail-slow 事件。其次,IASO是节点级别的探测,而我们需要的是设备级别。尽管如此,我们尽力对 IASO进行了重构,为了避免修改软件,我们复用了基于peer evaluation的 fail-slow故障事件上报机制。
局限:基于 IASO的模型在我们的 benchmark 测试中表现欠佳,准确率只有 48%。我们怀疑主要原因是用 fails-slow事件上报去替换软件的超时时间是不够有效的。所以 IASO 重构也没有达到我们的目标。
3.5 PERSEUS 的指导原则
上述方法要么需要大量人工调参,要么在实际生产环境中效果不佳。本节我们用了一系列研究问题作为下一代 fail-slow 故障探测机制的指导原则。
RQ1: 我们应该用什么指标?
在早期研发阶段,我们主要聚焦于写入性能(即写入操作的延迟/吞吐量)的优化,这主要基于两方面的考虑:首先,在已经验证的 fail-slow案例中,超过 50% 的案例仅对写入操作产生显著影响,其余的,对于读性能的影响也是要远远小于写的影响。其次,fail-slow 故障对于写有更严重的影响。在我们的存储系统中,大部分集群需要写请求返回 3 个副本都成功。同时,读请求只要一个副本成功即可返回给用户。在这种场景下,fail-slow故障对于写来说影响更为频繁,单个 fail-slow写操作在大多数情况下都会导致写入请求延迟,而仅 1/3的概率会影响读取请求。需要注意的是,写入重分配机制无法修复fail-slow写入请求,因为重分配需要等待超时触发(该超时阈值往往远超fail-slow故障的事件)。尽管如此,我们仍基于读性能对于 fail-slow故障检测进行了评估,结果正式了上述假设。
RQ2: 怎样对模型的 workload 进行建模?
只简单依赖延时去检测 fail-slow 是不现实。我们之前的探索表明工作负载的压力可以显著的影响着盘的时延。而且,为深入理解延迟波动特性,我们进一步探索了其他用于建模工作负载压力的指标。
分析表格 3a和 3b激发了我们用盘的吞吐或者 IOPS 去建模的可能性。现在,盘的吞吐,iops和盘的延时一样被储存了起来。在表 6 中,我们在三种有代表性的服务中用 SRCC 衡量了盘的平均延时和吞吐以及 iops的相关性。一个更高的 SRCC 的值表明了一个更强的相关性。我们可以看到延时和吞吐的相关性比 iops 更高。此外,在一些服务里,延时和 iops 甚至有负相关性(数据库和块存储)。所以,我们决定用吞吐来对工作负载建模。
RQ3: 如何获得自适应性的阈值?
在尝试 2 种,我们发现尽管 peer-evaluation可以提供自适应的阈值,这种方案仍需要针对服务类型和盘的类型对于参数进行调优。现在,用基于吞吐的负载模型,我们可以构建 latency-vs-throughput (LvT)分布。然后,我们可通过回归分析定义统计学意义上的正常盘的基准,并将上限作为适用于多种环境的自适应阈值。
为了构建回归模型,我们需要明确纳入 LvT分布分析的磁盘范围。需要权衡的是,纳入更多的样本虽然能够提升统计的置信度,但会导致数据分布过度分散,从而难以得出清晰的上线阈值。所以我们在图 5 上描绘了三种分布,接下来会讨论他们的长处和短处。

service-wise:5a中显示了数据库服务中 3 个集群的 LvT分布。首先,我们可以观察到同一个服务中的不同集群在 LvT分布上可以有巨大的不同。比如,红色集群的样本几乎全部在黄色样本以下。这说明用服务中的全部硬盘来构建分布是不恰当的。
cluser-wise:在 5a中,我们发现即使是一个集群中的样本也有这明显区分的分布特征。通过统计学的分析,我们发现此类分布差异现象普遍存在。为了更清晰,在 5b中,我们描绘了在统计群两个不同节点上的 LvT分布。这种巨大的分布差异说明我们不能依赖于集群级别的 peer evaluation。
node-wise:最后,在 5c中,我们描绘了一个全闪节点(12 SSD)上的 LvT分布。每个盘代表了一个颜色。我们可以看到颜色聚集在一起,说明一个节点上的盘有相似的 LvT分布。我们也检查了其他服务的节点,确认了这种行为存在于很种节点的配置(全闪或者混存)和服务(块存储或者对象存储)。所以,我们决定用node-wise的样本去构建 LvT的分布。
RQ4:怎么在没有标准的情况下定义 fail-slow
和 fail-stop故障不同,在探测 fail-slow 故障时没有明确的标准。首先,设备(SSD)和软件对于运维工程师都是黑盒子。其次,fail-slow 故障可能呈现时变性特征,其症状表现存在动态波动。更多的,fail-slow 故障的根因可能非常难以定位。所以,我们无法完全排除 fail-slow故障的可能性。
所以,我们重新思考了对于 fail-slow探测的策略。与其依赖框架输出一个二元判定结果,探测工具更应该输出硬盘成为fail-slow的潜在概率。通过足够的精准度,运维工程师可以聚焦于最最有问题的盘。尽管这种做法可能导致部分fail-slow盘没有被检测到,但由于其表现与正常性能波动相似,所以这种情况时可以接受的。
4 PERSEUS
基于先前尝试的经验教训,我们剔除了 PERSEUS,一种非侵入式的,细粒度且通用的 fail-slow 检测框架。PERSEUS 的核心思想是基于节点级别的 LvT 分布构建多项式回归模型,从而为每个节点自动生成自适应阈值。本章节中,我们将首先介绍高层级工作流程,随后详细阐述每个步骤的设计方案。
我们的数据集可以看成是一个时间序列的数据集,每个 entry 有 5 个字段(avg_latency, avg_throughput, drive_id, node_id, timestamp)。每天,监控进程会从每个盘上收集超过 720 entry(180 min * 4 entries / min),并把他们发送到 PERSEUS 中进行一个四步的探测过程。
4.1 工作流
异常检测,对于每个节点,PERSEUS 首先收集所有的 entry。然后我们用一个 PCA 和 DBSCAN 联合的方法去发现和丢弃异常值。
构建回归模型,基于干净的数据集,PERSEUS 执行多项式回归,并把预测上限作为 fail-slow的探测阈值。然后 PERSEUS 把这个模型应用于原始的数据集去辨别out-of-bound entries 然后把他们标记为慢 entry。
确认fail-slow事件,PERSEUS 采用滑动窗口和慢速比例结合的方法,通过识别连续慢操作的 entry,进而精确定义对应的fail-slow故障事件。
评估风险,基于故障分的机制,PERSEUS 预测 fail-slow 的持续时间和影响程度,并为每个盘基于日常采集 的 fail-slow 事件定义一个故障分。值班的工程师就可以根据故障严重程度分级排查相关案例。
4.2 异常检测
在应用任何回归模型之前,必须先去掉噪声样本。LvT的样本数据一般都是一个节点聚集在一起,来自 fail-slow盘的日志或者是正常盘的性能波动仍有显著变差。所以在构建多项式回归模型之前,需要先进行异常值筛选。
使用 DBSCAN。基于密度的聚类算法(通过测量空间距离)是识别潜在差异化群体的有效方法。起初,我们使用 DBSCAN 来标记异常值。
简而言之,DBSCAN算法通过空间密度聚类将数据点分组,其核心逻辑是:当数据点之间的空间距离小于设定阈值(ε)时,这些点将被归为同一簇群。需要特别注意的是,来自长期或永久性故障慢速驱动器(fail-slow drives)的<延迟,吞吐量>数据对可能会形成独立于主集群的孤立簇群。因此,在后续建模过程中,我们仅保留数据点数量最多的主簇群。

加入 PCA。遗憾的是,直接对原始数据集应用DBSCAN算法进行筛选的效果有限。我们选择一个已确认存在故障慢速驱动器(fail-slow drive)的样本节点来说明该局限性。如图8a所示,在对该节点每日原始数据集应用调优后的DBSCAN算法(红色散点为识别出的异常值)后,将剩余数据(灰色散点)拟合为多项式回归模型(蓝色曲线为拟合结果,绿色虚线表示99.9%预测上限)。本案例中,DBSCAN算法仅识别出63.83%的慢速操作记录。
根本原因在于吞吐量与延迟存在正相关性,导致样本(即<延迟,吞吐量>数据对)在特征空间中呈现定向偏斜分布。这种特性使得异常值(来自故障慢速驱动器的样本)可能被误判为正常数据(如图8a中黑色圆圈所示)。为此,我们采用主成分分析(PCA)进行坐标变换,沿数据偏斜方向的垂直维度增强异常值惩罚权重,从而显著降低误标率。经实验验证,结合PCA的DBSCAN算法可实现92.55%的慢速操作检出率(见图8b)。
异常值的使用。回顾研究问题RQ4中的讨论,我们发现仅使用二元检测无法准确反映性能劣化程度。因此,我们摒弃了直接将异常检测结果二值化的常规做法(例如简单地将异常点标记为慢速操作而跳过§4.3节流程,或直接判定为故障慢速事件而跳过§4.3-§4.4节分析)。相反,我们通过排除异常样本构建高精度回归模型,以此量化每个操作记录的劣化程度。
4.3 回归模型
由于一个节点内正常的盘一般都有类似的 lvt分布,我们可以使用一个回归模型来解释这种正常盘的行为和划定性能波动的边界来进行fail-slow的探测。经典回归模型主要包含以下三大类,线性回归,多项式回归,kernel 回归。我们没有使用线性回归,因为延时和吞吐的关系明显是非线性的。由于延时和吞吐明显存在单调递增关系,所以使用kernel回归等复杂模型存在过拟合风险。多项式回归因其在保留模型简洁性的同时能有效处理非线性关系而成为更优选择——即用最少的参数实现理想的拟合优度。
4.4 辨认 fail-slow 事件
区分慢速日志。在建立回归模型后,可通过计算预测值上限来识别慢速操作记录,并据此检测故障慢速驱动器事件。例如,99.9%的预测上限意味着99.9%的波动范围被视为正常值。实际应用中,我们采用宽松(95%)与严格(99.9%)双上限组合策略,在避免过拟合的同时最大化故障驱动器的识别率。

创建事件。接下来,我们通过真实案例与模拟数据相结合的方式,演示如何准确定义故障慢速事件。如图 9a所示,灰色曲线表示盘的实际延时,蓝色曲线为模型拟合值,绿色曲线则是 99.9% 预测上限。通过将每个数据点的盘时延除以对应时刻的上限制,即可得到劣化比率(Slowdown ratio, SR)。例如:某盘在 1 分钟内的延时序列为15,20,25,10,5 毫秒,对应上限值为5,5,5,5,5 毫秒,则计算得到的 SR序列为 3 4 5 2 1。图 9b展示了候选盘的SR时序变化情况。
接下来,我们使用滑动窗口的机制来定义一个fail-slow事件(和尝试 2 类似)。滑动窗口有一个固定的长度,从第一个 entry 起始。在检测窗口内,当劣化比率序列的中位数超过设定阈值时,PERSEUS 将判定该盘在此时间段内发生了 fail-slow 事件,并根据后续数据点动态评估是否延长事件持续事件。
上面的例子(SR 序列 3 4 5 2 1),我们把最小的时间 span 是 1 分钟,比例阈值为 50%,SR 中位数阈值时 1 时,前四个 entry 会产生一个 fail-slow 事件,因为超过了 50% 的 SR 比阈值(1)有一个更高的中位值(3.5)。因为同样的原因,这个 fail-slow事件因该包含第五个 entry 。
实际上,我们把最小的 span 设为 5 分钟,比例是 50%,阈值是 1,意味着事件肯定是比上限要慢的。我们的逻辑是,仅当出现持续性的劣化记录序列时才判定为 fail-slow 事件,而短暂突发的性能波动则视为可接受的正常变化。在 9b 中 1 和 2 都有很高的SR值,但只有 2 会被当成 fail-slow事件。
4.5 Risk Score
如我们在研究问题RQ4中所讨论的,我们并不单纯依赖故障慢速事件的存在性来判定驱动器为"故障慢速"状态。事实上,如果我们出现一次 fail-slow 事件就标记的话,那一天我们可以得到 6000 个 fail-slow 案例。

因此,我们采用性能回归测试中的风险评分机制理念,构建了一套动态量化评估体系。在表 3 里,slowdown的持续时间和严重程度被分成多个危险级别。比如,在我们的场景里,根据慢的时间长度,fail-slow被分为临时(30-60 分钟),中度(60-120 分钟),重度(120-180 分钟)。而且,基于一天内平均的慢盘比例,fail-slow的严重程度被分为轻度(1 < SR < 2),重度(2 <= SR < 5),重度(SR > 5)
为了检测 fail-slow,每个盘的故障分计算根据危险程度用不同的权重计算:
如果一个盘的故障分超过了在最近 N天内都超过了最小值,盘会被建议立即进行隔离进行硬件检测。而且在我们的表格里,ssd 和 ssd使用同样的打分机制。
5 效果评估
5.1 Fail-slow benchmark
我们测试 fail-slow 检测框架最大的挑战是缺少 benchmark。已存在的 fail-slow数据集只记录了高级的fail-slow信息,不能用来进行模型的评估。所以,我们基于已经验证的 fail-slow 盘和生产环境的trace数据构建和发布了一个大规模的 fail-slow检测 benchmark。

benchmark规模,表 4总结展示了我们benchmark测试的结果。具体而言,我们的数据集包含来自于 25 个存储集群中 41000 块硬盘(包括固态盘和机械盘)连续 15 天生成的 8.86 亿条运行轨迹数据。其中 315 块硬盘(237 块 ssd 和 78 块 hdd)被确认存在fail-slow现场并标记为阳性样本,其余为同集群的正常对照硬盘。在这些已验证的故障案例中,有 304例是通过 PERSEUS智能检测系统成功识别的。所有的fail-slow硬盘均经过现场工程师或者制造商的严格验证,其根本原因可归纳为三大类:软件调度缺陷,硬件设计故障和运行环境因素。
工作负载异构性,benchmark覆盖了 9 种核心服务,这些服务表现出显著的差异化的 I/O 访问模式,并由此形成多模态的 LvT分布特征。
benchmark配置,在我们数据集里,252 个 fail-slow的盘是由于软件调度引起的。为避免PERSEUS检测系统可能对阿里云技术栈存在特异性依赖的潜在争议,我们设立了两类测试范围:
完成的测试数据集
排除所有存在软件诱发型fail-slow数据集
5.2 测试对比
我们基于早期探索的三种模型(阈值过滤法、对等评估法及基于 IASO的改进模型)与 PERSEUS进行对比,本节将详细说明这些模型的实现与配置方案。
5.2.1 阈值过滤法
我们同时采用了统计阈值和经验阈值两种判定标准。
统计学边界。我们从下面的统计学指标衍生出了上限:
75 到 99 的分位数
四分位距阈值:计算IQR(第三四分位数 - 第一四分位数)的3倍范围,当盘在持续三小时的监控周期内,延迟中位数超过预设的性能上限阈值时,即呗判定为 fail-slow
经验边界。我们手动为每个服务的每个节点基于 SLO或者是值班工程师的建议(块存储全闪 300 us)设置了延时的上限。
5.2.2 同级评估
如果一个盘的延时是节点其他盘中位数的 X 倍至少 N 分钟就被认为是 fail-slow 盘。为了得到最佳性能,我们测试了多组参数(X从 1.5 到 3,时间从 0 到 150 分钟)
5.2.3 IASO模型
我们严格按照 IASO模型的设计做实现,只修改了必须修改的部分。由于 IASO 在节点的基础上探测 fail-slow 盘,如果节点含有一个 fail-slow盘我们就把结果标记为真阳性。下面列举了重要的实现细节:
Epoch. 每个 epoch的大小由 5 秒调整为 15 秒
timeout. 超时信号转为了节点的慢盘数量。在每个 epoch 里,慢盘是指那些:要不就是延时超过了经验阈值,要不就是超过了同节点延时中位数的两倍。
dbscan 配置,IASO记录了同级的分数,并仅保留得分最高的一个异常节点进入后续缓解流程。在本次评估中,由于仅针对 IASO的检测模块进行验证,我们保留 DBSCAN 算法分类的所有异常节点,并通过设置不同的评分阈值对 IASO进行精细化调优。
5.2.4 PERSEUS
PERSEUS 负责了异常的探测,用了两种预测的上限(95% 99.9%)来确认 fail-slow 事件。监控周期为 15 天,告警分数为经验阈值是90分,中位数延时是 40 分。PERSEUS在不同介质(全闪,混存)和不同业务(块,对象,大数据)的节点上使用了统一的一组参数。
5.3 评测指标
我们采用了三种评测指标:准确率,召回率,MCC(马修斯系数)
TP(true positive),真阳性, 被诊断为故障盘且真的是故障盘
TN(true negetive),真阴性,被诊断为非故障盘实际也是非故障盘
FP(false positive),假阳性,被诊断为故障盘但并不是故障盘
FN (false negetive),假阴性,被诊断为非故障盘实际也不是故障盘
准确率,通过某种方法识别出的故障盘中,确实是故障盘的真实比例
召回率,通过某种方法识别出的真实故障盘占所有故障盘的比例
由于我们的测试数据集极度不平衡(阳性和阴性的比例为 1:137),我们选择采用马修斯相关系数,因为该指标能够更公正评估不平衡数据集上的二分类模型,且相较于准确率和f1等广泛使用的指标,它能够提供的信息更全面,说服力更强。
5.4 评估结果

表 5 总结了表现结果。对于之前的一些尝试,我们选择了最佳的表现结果。对于 PERSEUS 我们使用了部署的版本。上半部分包含了全部数据集的测试结果,下半部分去掉了调度引起的故障。
阈值版本,我们可以看到,不管在全集和子集,准确率都可以达到 100%。然而召回率表现欠佳,特别是经验阈值。这种现象可以解释为:严格的阈值设定虽然能有效识别出速度极慢的磁盘(这类情况极可能由慢速故障引发),但另一方面也会导致仅表现出轻微故障症状的磁盘无法被检测到。
同级评估,用这种方法也是高准确率但是低召回率,原因是它使用了一个自适应的阈值来定义 fail-slow,但是它也面临着同样的基于阈值的问题
IASO模型,尽管我们尝试了各种努力去重构和优化 IASO,他的表现令人失望。MCC分只有 0.32,甚至比不上一个简单的统计学阈值或者用同级评估。我们认为有两方面的原因。首先,IASO非常依赖软件的超时不能简单的用节点级别的慢盘来替代。其次,它的算法被设计用来做节点级别的探测,一个简单的 fail-slow时间可能不会引起足够的重视。
PERSEUS,表 5显示 PERSUES表现的比其他方法都好。高精确率和召回率说明 PERSEUS 可以成功的探测所有的 fail-slow 盘,但不会误判正常盘。因此,我们得出结论:PERSEUS 框架实现了设计目标,其具备细粒度(驱动器级检测)、非侵入性(无需代码修改)、通用性(同一参数适配不同配置)和高准确性(高精确度与召回率)的慢故障检测能力。
5.5 PERSEUS 设计有效性
现在,我们将深入分析PERSEUS系统中各项程序的有效性及参数的敏感性。表 6 中,我们列举了 PERSEUS 主要的选项或者是参数的配置区间。接下来,我们将通过启用或禁用特定功能模块来讨论PERSEUS系统的有效性,并探索不同参数组合的影响。评估结果详见表7。需注意的是,实际部署版本采用了p95与p999上限值的组合策略


异常值检测,通过关闭异常值检测,我们可以看到精度仍然保持,但是召回率暴跌到0.51。这说明,没有异常值检测,PERSEUS不能有效的分别 fail-slow 的样本,从而导致召回率偏低。
PCA,令人惊讶的是,如果我们启用了异常值探测但是关闭了 PCA,我们发现效果比没有异常值探测还差。这说明了 PCA的重要性。
预测上限,我们指定了从 p95 到 p999的不通的阈值上限。在完整数据集上,p95上限是最佳选择,其准确率和召回率均达到 0.99,几乎完美。对于子数据集,由于子数据集中出现fail-slow通常伴随着严重的性能下降,因此更严格的p999上限是首选。在实际应用中,我们部署的版本结合使用了p95和p999上限,以便在两个基准测试之间取得更好的平衡。
故障分机制,图 10 评估了该评分机制,随着 min_score 和 N 值的增大,精确率(precision)通常会提高,而召回率(recall)则会下降。这是因为,当 N 值变大时,哪些只是偶尔出现轻微降速的磁盘,可能会因为统计了更多天数的分数而被错误地识别。
评估读性能,fail-slow故障影响写性能比读性能更严重。在 315起fail-slow案例里,49个案例同时影响了读和写,而 233起只影响了写。不幸的是,我们没有剩余 43起的 fails-slow读性能的 trace
运行时开销,在一台配备 16GB 内存、2.5GHz 的英特尔至强(Intel Xeon)8 核 CPU 上,PERSEUS 在每个节点上的执行时间经测量为 秒。凭借其低开销的特性,PERSEUS 每天仅用单台机器便能检测数万个节点中的“fail-slow”(慢故障)硬盘。
5.6 部署收益
部署 PERSEUS 最直接的好处是降低尾延迟,通过隔离 fail-slow 节点,节点级别的p95 p99 p9999百分位写入延迟分别降低了 30.67% 46.39% 48.05%
6 根因分析
我们进一步分析了测试数据集中 315个 fail-slow 的根因。
软件故障,其中 216 块 ssd 和 36 块 hdd,收到软件调度不良的影响,这表明优化或重新评估调度算法可以显著减少这些磁盘上 fail-slow 慢盘的产生
硬件相关故障,其余 42块hdd和 21块ssd 经过现场工程师验证为硬件相关的故障慢盘,已送回供应商进行详细分析
供应商诊断更新,由于诊断过程耗时较长,我们目前仅获得了其中 15 块硬盘的根本原因,随着供应商提供更多诊断结果,预计将获得进一步的分析洞察。
6.1 不好的调度器
6.1.1 案例 1:Open-Channel ssd 集群
症状,在两个集群中,PERSEUS 总共识别出 216 个持续表现出异常性能的故障慢盘,这很不寻常,因为硬件相关的故障慢盘通常很少见且是独立的,进一步调查显示,所有检测到的故障慢盘都具有相同的逻辑id,即disk1 disk2。检查每个节点的延迟时间序列后,我们发现这些节点中单个硬盘的延迟水平与其逻辑id成正相关,即延迟水平:disk1 > disk2 >...>disk12。换句话说,在这些节点中,disk1总是最慢的,其次是 disk2...
根因,这两个集群中出现的 216 块慢盘持续性fail-slow现象,其核心问题在于操作系统调度器存在缺陷。
每个节点都配备了 12 块 OC SSD,这些 SSD的 ftl由 host 管理。对于每个节点,host分配了 12 个 cpu core来分别管理这 12 块 oc ssd,core0-core11分别对应 ssd0-ssd11。
根本原因在于 os调度器将系统任务分配到 cpu core的方式。调度器按domain进行操作,每个 domain 包含 6 个 cpu core。当接收到一个新的系统任务时,调度器首先检查当前core和上次选择的core是否空闲。如果都不空闲,他就会从该domain的第一个 core开始,按顺序遍历所有的core,并尝试抢占一个core来进行该任务。
这种按照顺序抢占的策略直接影响了 oc ssd的性能。逻辑id较小的盘,他们所对应的 cpu core在各自domain内的迭代顺序中更靠前,因此,这些core更容易被传入的系统任务抢占。这种反复的抢占会中断相应oc ssd ftl,从而导致观察到的 fail-slow现象,disk1是最慢的,依次是disk2...
修复方案,我们修改了调度器,使其不再强制爱分配给 oc ssd的 cpu core,修复后,这些集群中的 oc ssd不再出现 fail-slow现象。
6.1.2 案例 2:在所有的 hdd集群中
症状,在一个集群中,PERSEUS 系统识别出了 36块 fail-slow hdd,该集群采用全 hdd 配置,每个节点包含 76 块 hdd,关于该集群中的 fail-slow hdd分布,我们发现了三个有趣的现象:
fail-slow总是固定的配对组合出现,例如如果一个节点中有两块故障慢的 HDD,它们总是 disk0 和 disk75。如果存在六块故障慢的 HDD,它们则会是 disk0-2 和 disk73-75。
所有的 fails-slow hdd都经历了相似程度的性能下降,这表明他们可能收到了相同的根因相应,而非随机的独立故障
在每个节点中,fail-slow盘的数量总是离线硬盘的两倍,这一发现按时了 fail-slow故障与硬盘离线之间存在直接关联,可能意味着某种机制导致了一部分硬盘离线,同时影响了另一部分磁盘的性能。
根因,在这个集群的每个节点中,操作系统为每块 hdd 分配一个线程来管理其I/O。这种分配遵循一个简单的算法:
thread id = diskid % 磁盘数量
因此,由于每个节点通常有 76 块 HDD,所以线程 0 通常管理 disk0,以此类推。
然而,当一块硬盘离线时,硬盘总数会发生变化,线程分配也会随之调整。 例如,假设 disk20 崩溃,硬盘总数变为 75。那么,disk0 和 disk75 将会共享线程 0(因为 ),从而由于 I/O 争用而出现故障慢。
类似地,如果两块或三块硬盘崩溃,也会导致相应的两到三对硬盘出现故障慢现象。
修复方案,我们修改了分配策略,只允许一个 hdd 一个线程,这样避免了fail-slow的发生。
6.2 硬件缺陷
坏扇区(Bad sector)。坏扇区通常是物理损伤的产物(例如制造缺陷或读写头划伤)[40]。为应对此类问题,磁盘固件会维护一组备用扇区,用于重新分配坏扇区上的原始数据。此外,固件会将坏扇区的逻辑地址重新映射到备用扇区的物理地址。当主机请求访问未标记的坏扇区时,磁盘将因长时间寻道(即数据重分配耗时)而性能下降。根据现场事件记录,有三块硬盘因存在大量坏扇区,导致反复重映射与数据重分配,最终引发明显的故障缓变(fail-slow)失效。需注意的是,仅凭此类错误的发生无法直接推断根本原因,因为硬件缺陷通常既非故障缓变的必要条件,也非充分条件。
转子偏心 (Rotor eccentricity) 是导致硬盘出现故障慢的物理原因之一。硬盘的马达以高速(例如,消费级 HDD 通常为 7200 RPM)驱动盘片旋转。如果主轴马达中的转子在旋转时出现偏心,会导致严重的噪音和振动。对于这类硬盘,读写磁头将频繁地无法精准定位到目标位置,从而导致显著的 I/O 延迟。在我们的现场事件中,有两块故障慢的 HDD 被报告证实是由于轻微的转子偏心所致。
坏电容(Bad capacitors) 是导致固态硬盘 (SSD) 性能严重下降的一个重要原因。SSD 内部通常会使用少量 DRAM 作为写回缓存,以显著提升读写性能。然而,如果这些 DRAM 的电容出现故障,SSD 将被迫停止使用该缓存。这是因为 DRAM 是易失性存储器(即断电后数据会丢失),如果电容损坏,缓存中的数据将无法得到可靠的保存。一旦停止使用 DRAM 缓存,SSD 的工作方式就会改变:它不再在数据写入缓存后立即确认(ACK)写入完成,而是只有在数据被直接且成功地写入到 NAND 闪存后,才会发送确认信号。这种直接写入 NAND 的操作会产生更长的写入延迟,从而导致整体性能严重下降。总计,我们发现有 四块 SSD 存在电容损坏的问题。
只读模式(Read-only mode) 是一种当硬盘遇到严重错误(例如,出现过多坏扇区)时所采取的保护机制,旨在防止进一步的数据丢失。在这种模式下,硬盘会被重置为(临时)只读状态,并被阻止执行任何写入命令。这意味着所有写入操作都将被拒绝。结果,我们发现有 两块 SSD 由于类似的原因而陷入了只读模式。
6.3 环境
温度和电源是导致故障慢事件的常见原因,这一点在相关研究中也有提及 [19, 48]。
根据现场事件报告:
一块故障慢的 HDD 是由于环境温度过高导致了温度节流。这意味着硬盘为了防止过热而主动降低了性能。
另有三块 HDD 的故障慢则与供电不足事件有关。不稳定的或低于标准的电源供应会直接影响硬盘的正常运行,导致性能下降。
7 局限
并发多起 fail-slow 故障,PERSEUS利用了一个重要的前提条件,在实际应用中,fail-slow 故障应该是函件的。然而,如果关键数据路径上的一个核心组件(比如 HBA卡)发生故障,所有硬盘都会收到影响,并导致严重的延迟。在这种情况下,由于所有硬盘的 lvt 都可能出现偏差,PERSEUS 可能无法检测到性能异常。目前,我们正在研究执行节点间 LvT 分布的可能性,以增强 PERSEUS 在同一节点内发现多个 fail-slow故障的能力
普适性,使用 LvT 分布来识别 fail-slow 故障的硬盘还取决于一个事实:即节点内的所有硬盘都具有相同的型号和相似的工作负载。在我们的存储系统中,硬盘配置相同,并且多层负载均衡确保了同一节点内每块硬盘的工作负载相似。虽然这对于大规模存储系统来说是一种常见的做法,但对于小型服务器可能并非如此,在这些服务器中,同一节点内的硬盘可能具有截然不同的工作负载和配置。在这种情况下,PERSEUS 的准确性可能会收到影响。
可理解性,PERSEUS 目前使用每天晚上 9 点到午夜 12 点之间的跟踪数据来减少干扰,但一些 fail-slow的故障可能只在特定的时间窗口或在更高负载下才会触发。我们正在努力设计一个更高效的守护程序,以便在繁忙时段收集跟踪数据供 PERSEUS 使用。此外,我们正在探索其他设备级指标,以丰富 PERSEUS 的关键输入。
8 相关工作
fail-slow 故障的研究和诊断,作为一个新兴的故障模式,fail-slow 故障已受到学术界和工业界的日益关注。早期的文献主要侧重于将 fail-slow 故障诊断为一种被忽视的故障模式。例如,huang 等人通过一个抽象模型定义了云中的灰度故障。do等人测量了由跛行软件带来的系统级性能下降,并提出了开发容忍跛行软件的系统必要性。gunawi等人对来自不同机构的 101 份硬件事件报告进行了定性分析,揭示了各种类型硬件中潜在的 fail-slow根本原因。我们在第 2.3 节中的动机性研究,则专门评估了 fail-slow故障对磁盘性能的影响。此外,我们的工作为存储设备中的 fail-slow提供了更全面的根因分析。
fail-slow故障探测,有一些研究致力于 fail-slow故障的检测和定位,例如,panda等人将软件层面的超时信号转换为 fail-slow的指标,并采用peer-evaluation来检测 fail-slow的节点。huang等人设计了 panorama,通过提高内部可观察性来检测生产环境中的故障。与上述方法不同,PERSEUS 专门用于检测存储设备中的 fail-slow,并且仅基于性能指标进行检测。
9 结论
在本文中,我们首先分享了我们在为大规模存储系统开发稳健且非侵入式的fail-slow检测方法时,所经历的失败尝试。随后我们介绍了 PERSEUS 的设计,它利用经典的机器学习技术和评分机制来实现有效的 fail-slow 检测,自部署以来,PERSEUS 已覆盖约 25 万块磁盘,并成功识别了 304 块 fail-slow 盘。
最后更新于