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

夜莺和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)

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理