关于prometheus:夜莺和prometheus告警流程对比分析pull模型远胜push模型

3次阅读

共计 2382 个字符,预计需要花费 6 分钟才能阅读完成。

夜莺和 prometheus 告警流程比照剖析

prometheus 告警流程剖析

以 sum(rate(coredns_dns_requests_total[1m])) > 100 为例

  • alert 和 record 复用大部分逻辑
  • prometheus 依据配置文件中拿到规定
  • 解析规定查问本地存储或远端存储(带触发条件),trigger 在存储端
  • 返回一组以后点后果集,返回多少个对应多少条告警
  • 依据内存中的历史数据判断告警持续时间 (for 1 min) 有没有达到
  • 发送告警 event 给 alertmanager
  • 由 alertmanager 做告警的发送、静默、分组路由、关联、回调

夜莺告警流程剖析

  • monapi 定时从 db 同步策略,judge 依据本人的 ident 拿到属于本人的策略
  • transfer 依据存活的 judge 拿到所有策略,将策略的 judge 地址填好
  • transfer 收到 agent push 的数据后,算 hash 拿到策略列表

    - 依据策略拿到 judge 地址,依据缓存拿到对应的队列,将数据塞入队列中
  • judge 收到策略后,依据策略中的 fun 做触发
  • 依据策略中配置实现 发送工夫、告警降级、回调等

两边本质区别

零碎 阈值判断 是否反对多 series 告警 触发条件 组合条件 nodata
夜莺 v4 push 代表 由 judge 接收点触发判断,查问本地数据 不反对,每个策略针对繁多 series
对应 judge 中内存列表
只能用预聚合解决
将 happen、all、any 等和聚合 avg max min 等揉在一起 需做 pull 需做 pull
prometheus pull 代表 由 promql 查问存储 promql 间接反对
查问到一个就是一条,多个就是多条
prometheus 触发条件只反对 持续时间,其余的全副为聚合 func promql and 反对 promql absent 反对

告警 push 模式的性能晋升问题

总结就是相比于性能损耗 pull 模型带来的灵活性是微小的

  • push 型的告警模式无疑会带来性能晋升
  • 因为 pull 模型须要每次查问存储,尽管是以后点,但也有些损耗
  • 然而

    - 古代的 tsdb 有倒排索引 + 布隆过滤器的加持,告警查问损耗能够降到很低
    - pull 模型带来的是非常灵活的触发表达式,从这点看,性能损耗能够疏忽不急
    - 而且当初告警触发时都须要带上一些聚合的办法,这点 push 模型做不到
    

告警 push 模式能够工作在查问存储挂掉的 case

因为 push 本地内存中有响应的数据,然而我感觉这是个伪劣势

在夜莺中引入 pull 的问题

  • 最大的能源是否是相中了 promql
  • 存储和采集不反对 promql
  • 触发和聚合混在一起

代码剖析

夜莺 v4 代码问题

  • 策略太多双层 map reinit 耗时长
  • 全局变量满天飞
  • syncStras 全副更新,耗时长,db read 高

    - 每个 judge 实例拿到的还是全局数据,而且没有抢锁设计,导致多个 judge 实例同时全表读 db
    - 除非 db 那里做分片,分 region
    
  • judge push 模型报警很难将 pull 模式融入进来

prometheus 告警代码剖析

  • update 加载配置文件,增量更新告警 / 聚合 group
  • group.Eval 计算组里的规定

    - `// Eval runs a single evaluation cycle in which all rules are evaluated sequentially.`
    - `vector, err := rule.Eval(ctx, ts, g.opts.QueryFunc, g.opts.ExternalURL)`
    - 返回的是 vector `type Vector []Sample` 代表享有对立时刻的一堆 point
    - rule.Eval 分为规定和聚合 `alert/record`
    - 调用 EngineQueryFunc,外部调 instance_query
        - `// EngineQueryFunc returns a new query function that executes instant queries against// the given engine.`
    - 如果没取到数据,证实没达到触发条件则,只解决历史的 alert,看看持续时间到了没
    -  如果 rule 是 alert 则走发送逻辑 `    if ar, ok := rule.(*AlertingRule); ok {ar.sendAlerts(ctx, ts, g.opts.ResendDelay, g.interval, g.opts.NotifyFunc)}`    
    - alert 存在 headblock 中,record 写入存储中?

夜莺 v4 告警代码 剖析

  • judge 依据本人的 ident 拿到属于本人的策略 stras := cache.StraCache.GetByNode(node)

    - 更新本地 `cache.NodataStra` 和 `cache.Strategy`
    
  • monapi 定时从 db 同步策略syncStras

    - 分设施相干 or 设施无关
    - 依据策略的 id 算哈希,生成 `strasMap [judge_ip_port][]*stra`
    - 全量更新 `cache.StraCache`
    
  • transfer 依据存活的 judge 拿到所有策略stras := cache.StraCache.GetAll(),将策略的 judge 地址填好

    - 依据所有策略的 metrics 算哈希
    - 哈希前两位作为 map 的第一层 key
    - 外部 map key 为 哈希值,value 为 策略列表
    - `straMap := make(map[string]map[string][]*models.Stra)`
    - `cache.StraMap.ReInit(straMap)`
    
  • transfer 收到 agent push 的数据后,算 hash 拿到策略列表

    - 遍历策略列表 匹配 tag
    - 依据策略拿到 judge 地址,依据缓存拿到对应的队列,将数据塞入队列中
    
  • judge rpc send 中 go judge.ToJudge(cache.HistoryBigMap[pk[0:2]], pk, item, now)
正文完
 0