跳转到: 导航, 搜索

Ceilometer/blueprints/event-triggers

简介

触发器旨在简化对一段时间内发生的事件数据的聚合。OpenStack 中的许多进程将在其进行过程中创建通知,这些通知将在 Ceilometer 中表示为事件。这些过程可能需要很长时间,可能需要几个小时,并且通知可能从许多不同的 OpenStack 节点甚至 OpenStack 内部的不同系统(例如 Compute 或 Image 存储)发出。它们可能由 Ceilometer 安装中的多个不同的 Collector 节点处理,并且由于 AMQP 中可靠消息传递的权衡,可能不会按顺序接收。

为了正确地从这些事件集中聚合统计信息,我们需要收集一段时间内我们感兴趣的事件集,一旦我们获得了所需的事件,我们需要按其时间戳对它们进行排序,并将其作为批处理进行处理。如果我们从未收到我们所需的所有事件,例如在尝试收集信息的过程中发生故障时,我们需要使我们收集的列表过期,并可能执行替代处理,例如更新故障统计信息。

触发器可以实现这一点。它们允许在一段时间内收集相关事件列表,检测到我们拥有所需的所有事件时,正确地对其进行排序,然后使用事件管道(如事件管道蓝图中所定义:https://blueprints.launchpad.net/ceilometer/+spec/notification-pipelines)对其进行处理。它们还允许在如果在适当的时间内未能收集到我们所需的所有事件,则通过替代事件管道处理我们可能收集到的事件。


术语

触发器定义

用于触发器类别的配置。定义充当创建触发器实例的模板。它定义了名称、distinguished_by 特征、管道、过期时间、匹配标准等。

触发器实例

触发器的一个特定实例,持久存储在数据存储中,并包含一个事件列表。它具有

  • first_event:事件列表中最早事件的时间戳。
  • last_event:事件列表中最新事件的时间戳。当匹配到新事件时,此时间戳会更新。
  • expire_timestamp:此触发器实例将到期的实际时间。它源自定义中过期字段设置的时间表达式,基于 first_event 时间戳或 last_event 时间戳。如果基于的时间戳发生更改,则会更新它。
  • fire_timestamp:触发器将触发的实际时间。如果触发器的触发标准得到满足,则基于当前时间加上任何 fire_delay 设置。
  • name:来自其定义的触发器名称。
  • state:触发器可以处于 ACTIVEREADY_TO_FIREREADY_TO_EXPIREFIRINGEXPIRINGERROREXPIRE_ERROR 状态。
  • 以及 distinguished_by 特征和值的列表。

时间表达式

一种简单的 DSL,类似于时间比较的正则表达式。时间表达式可以是绝对的,例如 first@00:00(表示第一个事件当天的午夜),也可以是相对的,例如 last+3h(在最后一个事件之后 3 小时)。它们可以基于最后一个事件的时间戳或第一个事件的时间戳。这些可用于设置触发器过期时间,或日期时间特征的匹配值。对于匹配,可以使用单个时间表达式来匹配特定的时间戳,或时间范围(只是用“to”分隔的两个时间表达式,例如“first@00:00 to last+2h”)。

标准

描述用于与事件匹配的模式。基本上是一个哈希,包括:event_type,可以使用通配符,timestamp,可以使用时间表达式匹配,以及特征名称和值的列表,可以与常量或表达式进行比较。触发标准还可以具有 number,这是触发器的事件列表中必须存在多少个匹配给定标准的事件才能触发。标准用于:match_criteria,确定要收集哪些事件,fire_criteria,确定何时拥有需要触发的事件,以及 load_criteria,描述我们可能需要从数据存储加载的历史事件。

事件管道

用于处理事件的管道(请参阅 https://blueprints.launchpad.net/ceilometer/+spec/notification-pipelines)。一旦我们拥有所需的事件,事件管道就会执行实际的处理。触发器可以将事件发送到列为 fire_pipeline 的管道,当触发器的触发标准匹配时,或者可选地,发送到 expire_pipeline,如果触发器在未触发的情况下过期。


定义触发器

触发器定义具有以下字段

  • name:用于标识触发器的唯一名称
  • distinguished_by:区分此触发器的特征列表。为每个唯一的区分特征组合创建一个唯一的触发器实例(具有自己的事件列表)。如果触发器“instance_create”由 instance_id 区分,则将为事件中匹配触发器标准的每个唯一的 instance_id 创建一个单独的“instance_create”触发器实例。
  • expiration:时间表达式,设置触发器何时过期。可以相对于事件列表中第一个(最早)事件或最后一个(最新)事件指定。例如,如果过期时间设置为“first+4h”,则在接收到匹配其匹配标准的第一个事件后的 4 小时后,触发器将过期。如果设置为“last+2h”,则触发器将在接收到匹配其标准的最后一个事件后的 2 小时后过期(并且每次接收到事件时都会重置其过期时钟)。
  • fire_delay:触发器准备好触发后等待触发的秒数。(这允许收集任何乱序的“滞留”事件。)默认为 0
  • match_criteria:事件匹配的标准列表。每个匹配的事件将放置在触发器的事件列表中。如果事件匹配任何一个标准,则匹配成功。每个标准包括
  • event_type:要匹配的事件类型。可以使用类似 glob 的通配符。
  • timestamp:要匹配的事件时间戳范围
  • traits:要匹配的特征哈希。哈希是 trait_name: value。值可以是常量或表达式,例如
  • "> 10"
  • "< 1"
  • "is NULL"(事件不具有该特征)
  • "is not NULL"(事件具有该特征,无论值如何)
  • 时间表达式(对于日期时间特征)
  • 时间范围(也适用于日期时间特征)
    触发器的 distinguished_by 特征会自动添加到每个标准的 traits 中。要匹配给定的标准,必须匹配所有指定的 traits。
  • fire_criteria:描述必须存在于触发器的事件列表中才能触发触发器的事件。类似于匹配标准,但触发标准有一个额外的选项
  • number:必须至少有这么多个事件匹配此标准才能触发触发器。默认为 1。
  • load_criteria:在触发器运行其事件管道(无论是触发还是过期)之前,可能会从数据存储加载额外的、历史事件。语法与 match_criteria 相同。这些事件将在运行管道之前添加到触发器的事件列表中
  • fire_pipeline:当触发器触发时,将事件发送到事件管道的名称。事件列表按时间戳排序,最早到最新,并发送到该事件管道
  • expire_pipeline:一个可选的管道名称,如果触发器过期,事件将发送到该管道。如果列出了这样一个管道,则当触发器的过期时间过去时,事件将发送到该管道。

触发器流程

触发器系统有四个主要过程:处理传入事件、基于时间的触发器触发和过期执行、运行触发触发器的 fire 管道以及运行过期触发器的 expire 管道。


传入事件

事件进入系统,来自转换后的通知,或来自可能生成事件的其他系统(例如警报)。它传递给调度器,DB 调度器将事件持久存储到数据存储中(沿途通过 message_id 拒绝重复项)。然后它传递给触发器管理器。触发器管理器检查事件与触发器定义列表,以查看事件是否与任何触发器匹配。对于匹配的每个定义,触发器管理器确定该事件的区分特征值的集合,并检查数据存储以查看是否存在匹配的 ACTIVE 状态的现有、未过期的触发器实例。如果不存在现有的触发器实例,则将在 ACTIVE 状态下创建一个,并将其持久存储到数据存储中,其区分特征值和第一个事件时间戳来自事件。无论哪种情况,事件的 id 都会添加到该触发器实例的事件列表中,并且触发器实例的 last_event 时间戳会设置为事件的时间戳。触发器实例的 expire_timestamp 然后将根据其 first_event 或 last_event 时间戳(如下所示)重新计算。


之后,由事件创建/更改的任何触发器实例(尚未设置其 fire_timestamp 的触发器实例),都会检查其触发标准是否已满足。对于已满足其触发标准的触发器,触发器实例的 fire_timestamp 设置为当前时间加上任何 fire_delay 时间段。触发器的触发是通过时间戳完成的,以便允许延迟触发以收集任何乱序事件。


基于时间的触发器触发/过期

fire/expire 作业作为 Collector 中的后台线程运行。(或者它可以是一个单独的进程)。它在一个循环中无限期地执行两项任务。


首先,它会触发 fire_timestamp 已经过去的触发器。从数据存储加载一批状态为 ACTIVE 且 fire_timestamp 小于当前时间的有限大小的触发器。以随机顺序迭代触发器列表,每个触发器设置为 READY_TO_FIRE 状态,并向 collector 的 fire_trigger 方法发出 rpc 投递,其中包含触发器的 id。使用 rpc 投递以跨多个工作者传播工作。


类似地,它然后会过期其过期时间已经过去的触发器。加载一批状态为 ACTIVE 且过期时间已经过去(并且 fire_timestamp 为 null)的触发器,并以随机顺序迭代。每个触发器设置为 READY_TO_EXPIRE 状态,并向 expire_trigger 发出 rpc 投递,其中包含触发器的 id。


如果作业的两个任务都没有要处理的内容,它将休眠一小段时间(一秒左右)。该作业的设计允许同时运行多个作业,以便进行扩展。由于触发器状态使用一种机制在工作者之间同步(请参阅触发器状态),因此作业不会相互干扰。此外,通过 rpc 调用调用的方法被故意设计为对同一触发器多次调用 expire 或 fire 不会多次运行其 fire 或过期。


触发触发器

收到 rpc 请求以触发给定的触发器实例。从数据存储加载触发器实例,并检查它是否处于 READY_TO_FIRE 状态。(如果不是,则忽略该请求)。将触发器实例设置为 FIRING 状态。加载触发器事件列表中的所有事件从数据存储。如果有任何 load criteria,则 criteria 用于构造查询到数据存储以加载其他事件。将组合的事件列表按时间戳排序,从最早到最新,并删除任何重复项。通过事件管道管理器加载 firing 管道,并将组合的事件列表发送到该管道。一旦事件通过管道成功完成处理,触发器实例将被删除。如果管道在处理时抛出错误,则记录该错误,并将触发器实例设置为 ERROR 状态。(管道中的错误可能是由于代码错误造成的,应调查并提交错误报告。)


过期触发器

收到 rpc 请求以过期给定的触发器实例。从数据存储加载触发器实例,并检查它是否处于 READY_TO_EXPIRE 状态。(如果不是,则忽略该请求)。将触发器设置为 EXPIRING 状态。如果存在 expire 管道,则从事件列表和任何 load_criteria 加载事件。事件加载过程与触发时相同,并将事件发送到 expire 管道。如果发生错误,触发器将设置为 EXPIRE_ERROR 状态。如果触发器未处于错误状态,则将其删除。


注意:触发器状态

触发器实例的状态是同步的,以防止多个工作者相互干扰。这可以通过数据存储中的简单乐观锁协议或如果可用合适的协议,则通过某种形式的外部原子状态机来完成。