主动 RCA 故障模型

https://blueprints.launchpad.net/vitrage/+spec/proactive-rca

该蓝图提出了一种主动 RCA 的解决方案。它旨在成为所有相关蓝图的伞形方案。

问题描述

目前,Vitrage 依赖于监控事件进行根本原因分析。它可以推断虚拟资源上的告警,但始终处于已确认状态。但在现实世界中,情况可能会更复杂。假设对于故障 C,有两种可能的原因(A 或 B)。当监控到故障 C 时,怀疑 A 或 B 可能会发生并成为根本原因。我们需要一种方法在这种情况下采取行动,更主动地找到根本原因。

提议的变更

这里提出了一种具有演绎推理的故障模型来解决上述问题。

故障模型

给定上述故障模型定义的模板。

digraph G {
    // styles
    style="filled";
    color="lightgrey";

    A -> C [label="causes"];
    B -> C [label="causes"];
}

潜在的实体图可以分解为

digraph G {
    // styles

    node [style="filled", color="lightgrey"]

    // equivalences

    subgraph cluster_2 {
        label="Fault A";
        a_m -> a_v [label="eq"][dir="both"];
    }

    subgraph cluster_3 {
        label="Fault B";
        b_m -> b_v [label="eq"][dir="both"];
    }

    subgraph cluster_4 {
        c_m -> c_v [label="eq"][dir="both"];
        label="Fault C";
    }

    // expanded RCA rule

    a_m -> c_m [label="causes"];
    a_v -> c_m [label="causes"];
    a_m -> c_v [label="causes"];
    a_v -> c_v [label="causes"];
    b_m -> c_m [label="causes"];
    b_v -> c_m [label="causes"];
    b_m -> c_v [label="causes"];
    b_v -> c_v [label="causes"];
}

演绎推理

假设我们按以下顺序收到一系列事件

  1. t0: 初始状态,无故障

  2. t1: 监控到故障 C 激活

  3. t2: 从诊断操作报告,故障 A 激活且故障 B 未激活

  4. t3: 监控到故障 C 不激活

  5. t4: 从诊断操作返回,故障 A 不激活

让我们用以下图例说明演绎推理:

  • 簇:聚合故障

  • 节点:原始故障

    • 虚线:Vitrage 根据源状态推断目标状态

    • 点线:由源状态触发的诊断操作更新目标状态

  • 边框

    • 虚线:怀疑

  • 颜色

    • 浅灰色:故障处于未定义状态

    • 红色:故障处于已确认状态

  • 标签

    • Fault A:聚合

    • a_v:Vitrage 推断

    • a_m:监控

t0: 初始状态

所有故障未定义,无推理

digraph G {
    node [style="filled", color="lightgrey"]

    // fixed layout with cluster and invisible edges
    subgraph cluster_1 {label="Fault A" a_m a_v}
    subgraph cluster_2 {label="Fault B" b_m b_v}
    subgraph cluster_4 {label="Fault C" c_m c_v}
    a_m -> c_v [label="deduces" style="invis"]
    b_m -> c_v [label="deduces" style="invis"]
    c_m -> a_v [label="deduces" style="invis"]
    c_m -> b_v [label="deduces" style="invis"]
    a_v -> a_m [label="diagnose" style="invis"]
    b_v -> b_m [label="diagnose" style="invis"]
    c_v -> c_m [label="diagnose" style="invis"]
}

t1: 监控到下游故障,推断出上游故障

  1. Vitrage 推断故障 A 和故障 B 处于怀疑状态

  2. 执行诊断操作以确认怀疑状态

digraph G {
    node [style="filled" color="lightgrey"]

    // fixed layout with cluster and invisible edges
    subgraph cluster_1 {label="Fault A" color="red" graph[style="dashed"] a_m a_v}
    subgraph cluster_2 {label="Fault B" color="red" graph[style="dashed"] b_m b_v}
    subgraph cluster_4 {label="Fault C" color="red" c_m c_v}
    a_m -> c_v [label="deduces" style="invis"]
    b_m -> c_v [label="deduces" style="invis"]
    //c_m -> a_v [label="deduces" style="invis"]
    //c_m -> b_v [label="deduces" style="invis"]
    a_v -> a_m [label="diagnose" style="invis"]
    b_v -> b_m [label="diagnose" style="invis"]
    c_v -> c_m [label="diagnose" style="invis"]

    // downstream fault monitored
    c_m [color="red"];

    // upstream fault deduced, in suspect state
    c_m -> a_v [label="deduces" style="dashed"];
    a_v [color="red" style="dashed"]

    // upstream fault deduced, in suspect state
    c_m -> b_v [label="deduces" style="dashed"];
    b_v [color="red" style="dashed"]
}

t2: 执行诊断操作,确认上游故障

  1. 诊断操作更新监控状态

  2. 作为副作用,Vitrage 将推断故障 C 处于激活状态,与监控到的故障 C 并行

digraph G {
    node [style="filled", color="lightgrey"]

    // fixed layout with cluster and invisible edges
    subgraph cluster_1 {label="Fault A" color="red" a_m a_v}
    subgraph cluster_2 {label="Fault B" color="green" b_m b_v}
    subgraph cluster_4 {label="Fault C" color="red" c_m c_v}
    //a_m -> c_v [label="deduces" style="invis"]
    b_m -> c_v [label="deduces" style="invis"]
    c_m -> a_v [label="deduces" style="invis"]
    c_m -> b_v [label="deduces" style="invis"]
    //a_v -> a_m [label="diagnose" style="invis"]
    //b_v -> b_m [label="diagnose" style="invis"]
    c_v -> c_m [label="diagnose" style="invis"]

    // old status
    c_m [color="red"];
    a_v [color="red" style="dashed"]
    b_v [color="red" style="dashed"]

    // diagnose action executed
    a_v -> a_m [label="diagnose", style="dotted"]
    b_v -> b_m [label="diagnose", style="dotted"]

    // upstream fault confirmed
    a_m [color="red"]
    b_m [color="green"]

    // downstream fault deduced as a side effect
    a_m -> c_v [label="deduce", style="dashed"]
    c_v [color="red"]
}

t3: 监控到下游恢复,推断出上游恢复

  1. 从故障模型来看,我们可以推断故障 A 和故障 B 处于不激活状态

  2. 执行诊断操作以解决故障 A 推断(不激活)和监控(激活)状态之间的不一致性

digraph G {
    node [style="filled", color="lightgrey"]

    // fixed layout with cluster and invisible edges
    subgraph cluster_1 {label="Fault A" color="green" graph[style="dashed"] a_m a_v}
    subgraph cluster_2 {label="Fault B" color="green" b_m b_v}
    subgraph cluster_4 {label="Fault C" color="green" c_m c_v}
    a_m -> c_v [label="deduces" style="invis"]
    b_m -> c_v [label="deduces" style="invis"]
    //c_m -> a_v [label="deduces" style="invis"]
    //c_m -> b_v [label="deduces" style="invis"]
    a_v -> a_m [label="diagnose" style="invis"]
    b_v -> b_m [label="diagnose" style="invis"]
    c_v -> c_m [label="diagnose" style="invis"]

    // old status
    a_m [color="red"]
    b_m [color="green"]
    c_v [color="red"]

    // downstream recovery monitored
    c_m [color="green"]

    // upstream recovery deduced
    c_m -> a_v [label="deduces" style="dashed"]
    a_v [color="green"]

    // upstream recovery deduced
    c_m -> b_v [label="deduces" style="dashed"]
    b_v [color="green"]
}

t4: 确认上游恢复

digraph G {
    node [style="filled", color="lightgrey"]

    // fixed layout with cluster and invisible edges
    subgraph cluster_1 {label="Fault A" color="green" a_m a_v}
    subgraph cluster_2 {label="Fault B" color="green" b_m b_v}
    subgraph cluster_4 {label="Fault C" color="green" c_m c_v}
    //a_m -> c_v [label="deduces" style="invis"]
    b_m -> c_v [label="deduces" style="invis"]
    c_m -> a_v [label="deduces" style="invis"]
    c_m -> b_v [label="deduces" style="invis"]
    //a_v -> a_m [label="diagnose" style="invis"]
    b_v -> b_m [label="diagnose" style="invis"]
    c_v -> c_m [label="diagnose" style="invis"]

    // old status
    a_v [color="green"]
    b_v [color="green"]
    b_m [color="green"]
    c_m [color="green"]

    // upstream recovery confirmed
    a_v -> a_m [label="diagnose" style="dotted"]
    a_m [color="green"]

    // upstream recovery confirmed
    a_m -> c_v [label="deduces" style="dashed"]
    c_v [color="green"]
}

所需更改

主要更改将是允许以怀疑状态引发告警,这可用于触发诊断操作。

  • 添加对诊断操作的支持,例如

    • 从数据源立即拉取

    • 强制从数据源推送

    • 启动外部工具以获取状态并向 Vitrage API 发布事件

  • 告警的怀疑状态

    • 对于推断告警,如果来源是下游,则为怀疑状态

    • 对于聚合告警,如果检测到底层告警(推断和监控)之间存在不一致,则为怀疑状态

特别地,如果较新的监控状态与旧的怀疑推断状态不同,则不为怀疑状态。因为怀疑状态意味着它可能处于激活或不激活状态。因此,信任来自监控的最新更新是合理的。

但是,当我们引入主动 RCA 时,图形中的实体数量可能会大量增加。我们需要为每个监控告警创建推断告警,并在某些条件下设置怀疑状态。关系(边)也会增加。因此,还有一些额外的工作需要完成,以改善用户体验,例如:

  • 聚合底层实体图以简化用户视图

  • 添加用于查询聚合实体图的新 API

  • 通过定义故障模型来简化模板定义

向后兼容性

一个完全功能的主动 RCA 故障模型需要每个故障都可以使用诊断操作进行监控。但是,演绎推理过程也适用于缺少诊断操作或缺少某些故障监控的故障模型。

例如,如果对于确认故障 A 没有诊断操作,则一旦故障 A 的状态从监控被动更新,演绎推理仍将继续。

如果未对故障 A 进行监控,则它将保持在怀疑状态。这有助于用户缩小根本原因的范围,从而更容易进行手动调查。

实现

负责人

主要负责人

yujunz

其他贡献者

no

工作项

请参阅依赖蓝图。

依赖项

主动 RCA 的实现依赖于几个蓝图。一旦获得批准,它们将列出如下:

测试

请参阅依赖蓝图。

文档影响

请参阅依赖蓝图。

参考资料