引擎架构
从需求的角度来看告警主要解决数据采集、数据解析、告警计算、数据存储。
- Kafka队列负责指标传输,指标已经存储为解析好的指标,把它定义为整个告警引擎的生产者
- 消费者有两个
- 一部分直接存储到OpenTSDB
- 另一部分进入告警引擎进行实时消费
因此可以看出,告警类型可以分为两种:历史警告、活动警告。一种用于对历史指标的校验,另外一种偏向实时。 - 告警引擎是一个分布式的消费系统,其中分布式和HA是设计的重点。
- 每一个worker负责具体的规则检查,触发报警操作(Operator),并将告警信息传递给外部API
分布式
- 扩展性
由于前端生产者大量产生数据,有可能导致报警系统生产者过剩问题,消费引擎必须是可扩展的分布式系统 - 一致性
由于分布式运行,导致worker在获取历史参考值时未能计算其它worker中的数据,导致告警临界值产生异常,因此必须要保持一个分布式锁来进行临界值一致性保障- 分布式锁
用于解决对同一个topic(指标下)的并发一致问题
- 分布式锁
- 原子性
保障对历史参考值的获取/更新是一个原子性操作,避免引起并发读取的不一致性 - 高可用
系统必须保证worker部分宕机的情况下仍然处于工作状态,通过多个worker分布在不同的服务器下可以解决该问题 - 缓存
由于告警基于滑动窗口进行计算,对历史数据的频繁查找会引起大量的系统开销,必须使用缓存 - 缓存策略
如何进行秒级别的告警,基于滑动窗口的历史参考值该如何存储
Controller
- 任务
- 读取规则
- 获取参考值
- 获取消费数据
- 根据操作符进行对比,从缓存中获取并更新数据
- 触发告警操作
- 心跳监测
- 监测Controller是否正常运行,并提供心跳检查接口
接下来我们看一下工作流程:
- Controller收到一条数据
- Controller根据规则创建相应Worker
- Controller加载告警规则,如果没有,则向规则引擎发起请求,规则引擎负责规则的读取、更新、发布和通知
- Controller根据则向参考值引擎发起校验(读取并更新)请求,参考值引擎负责从存储读取、缓存
- Controller向操作引擎发送告警信息,操作引擎执行相应的操作
其中主要组件包括:
- Controller:负责校验的主体部分,主控制(Controller)
- Rule Engine:负责新建规则、读取规则、更新规则、发布规则和规则变更通知。规则引擎自身负责缓存策略。
- Ref Engine:参照值引擎负责解决参照值的读取(从TSDB中),缓存策略,一致性保障,分布式锁和参照值更新问题
- Operator Engine: 负责接收操作命令,执行相应操作
- Worker:负责按照规则进行规则检查
一个Controller中运行多个Worker
核心设计
- Ref Engine缓存策略
非常复杂,需要根据具体缓存的结构以及应用场景进行设计 - Ref Engine原子锁
有两种方案: - 分布式锁组件(例如zookeeper)
- (分布式)数据库锁,例如redis
- 监控规则设计
支持的形式相关,例如:时间窗口支持、历史参照值、滑动时间依赖等等 - 监控算法设计
根据规则进行判断 - Controller状态监控
假设可以进行心跳消息传递,正常处理后反馈结果
Another option Reference - https://www.ibm.com/developerworks/community/blogs/c914709e-8097-4537-92ef-8982fc416138/entry/大数据监控告警系统的实现?lang=es
Nagios