1、背景
对于超大规模 Hadoop 集群运维,统一的监控告警平台是必不可少的。但是当线上节点达到一定量级后,如超过 2 万节点后,告警平台会出现一些性能上的问题。本文将介绍在预计存储告警数据量达到数十亿条的情况下,超大规模跨域集群的统一告警平台的设计和实践经验。
2、技术简介
在上层统一监控使用 Prometheus 作为监控方案的情况下,由于 Prometheus 和 Alertmanager 为同一套体系下的监控框架,所以在告警方面,自然地选择 Alertmanager 作为告警组件。
Prometheus 监控系统是一套开源的系统监控报警框架,采集和告警是分离的,Prometheus Server 拉取各种类别的监控指标数据,其数据可来自各类开源的 Exporter,Prometheus Exporter 社区就提供了超过 120 种常见开源组件的 Exporter,同时也支持自定义 Exporter。Prometheus 在设置规则后,达到告警条件后就会将告警转发给独立的组件 Alertmanager,由 Alertmanager 经过统一的处理后发送给指定的用户。
3、Alertmanager 特性及优势
Alertmanager 处理由 Prometheus 服务器等客户端应用程序发送的告警。它负责对告警进行重复数据删除、分组,并将它们路由到正确的接收器集成,它还负责警报的静默和抑制。
•Grouping
分组,将性质类似的告警归属到同一条告警通知中,在短时间内避免告警同质化的发生,便于用户准确判定受影响的部分。同时根据路由配置,用户可专注于特定目标的告警。
使用场景:
1.告警量:系统同时发生故障导致瞬时产生规模较大的告警。2.接收者:告警接收者复杂,每种告警由特定的人员处理,告警需指定接收人。3.其他告警相似度大,告警根因相似,接收者不同的告警场景。
•Inhibition
抑制,当一种告警触发后,alertmanager 作出配置,停止发送由此告警引发的其他告警,从而避免其他无意义的告警或者与实际问题无关的告警。
使用场景:
1.整体:告警显示整个集群不可用,内部与集群相关的服务类的其他告警可抑制。2.关联:系统强关联,调用链路上存在多个应用单元,一个环节出现问题,关联的多个其他业务的告警都会被引发。存在重复告警,根因无法定位的情况。3.其他需要抑制的整体或者关联强的告警场景。
•Silences
静默,指在一段时间内,对告警信息进行排除,接收到的告警如果符合静默的配置,alertmanager 则不会发送此类告警。
使用场景:
1.排除:对于一些无意义或者不关注的告警进行排除,减少告警量。2.维护:在服务发布或者停服时,无需关注相应的告警。3.其他原因引发的告警无意义的场景。
Alertmanager 提供上述特性,提供了用户在告警设计上对场景自行调整的能力,将场景进行合并、分析,易于异常排错,根因定位,流量削峰等场景的使用。
4、Alertmanager 在多集群下的实践
4.1 原理
1.Prometheus server 存储所有指标信息,基于 PromQL 对指标制定告警策略 Rules。2.指标达到告警阈值一定时间后,Prometheus server 转发告警至 Alertmanager。3.Alertmanger 配置 Router 路由,按照指定 label 进行分组,设置对应的 Receiver,发送告警。4.告警接收方包括但不限于 webhook,email,wechat 等。
4.2 多集群下的告警实践
1.集群监控数据来自于 node exporter,jmx exporter,kafka exporter 等,根据集群节点的规模,将 exporter 动态均衡分配至不同的 prometheus 实例中。其中 prometheus-1-a 实例,prometheus-1-b 实例互为高可用,其他节点实例类似。2.dispather 服务根据集群 exporter 分布,动态分发 Rules 至 prometheus,分发 Routes 至 Alertmanger,实现增减策略的即时生效,完成告警分发的动态调度。3.Alertmanager 集群根据 Routes 配置实现接收服务的负载均衡。
架构如下图所示:
集群告警规则 rules 下发
Prometheus 服务实例与集群实例绑定,dispather 服务动态分发 rules 至指定的 Prometheus 实例。
按需组装 rule,生成 rule 配置文件,如下。
hive 堆内存使用量 rule 实例:
alert: HIVE_堆内存使用量_aatest_WARNexpr: Hadoop_hiveserver2_memory_heap_used> 90for: 1mlabels:level: WARNstrategy_id: 21066dd7cc2d41939d544a450afad512strategy_name: HIVE_堆内存使用量_aatestannotations:description: 'instance: {{$labels.instance}}, cluster: {{ $labels.monitor_cluster}},host: {{ $labels.monitor_host }}: 堆内存使用量 > 90 (current value is: {{ $value}})'alert: YARN_ResourceManager堆内存使用率_Yarn告警策略_MAJOR
yarn resourcemanager 堆内存使用率 rule 实例:
alert: YARN_ResourceManager堆内存使用率_Yarn告警策略_MAJORexpr: 100* (Hadoop_ResourceManager_MemHeapUsedM / Hadoop_ResourceManager_MemMaxM) > 20for: 1mlabels:level: MAJORstrategy_id: 3eb56fd4c7454c5a88ce9fc17c8f5a72strategy_name: YARN_ResourceManager堆内存使用率_Yarn告警策略annotations:description: 'instance: {{$labels.instance}}, cluster: {{ $labels.monitor_cluster}},host: {{ $labels.monitor_host }}: ResourceManager堆内存使用率 > 20 (current valueis: {{ $value }})'
调用 Prometheus 的 managerment api 进行 rules 热加载:
POST /-/reloadrules 进行不停服加载后,在 Prometheus 中即时生效,如下图:
Alertmanager route 下发
Alertmanger 适配了多种数据接收方式,dispather 服务按照业务分类,按照策略分发 Route 至指定的 Alertmanager,并指定不同的接收者。
按照策略分组,根据策略配置不同的接收服务。
global:resolve_timeout: 5mhttp_config: {}smtp_hello: localhostsmtp_require_tls: truepagerduty_url: https://events.pagerduty.com/v2/enqueueopsgenie_api_url: https://api.opsgenie.com/wechat_api_url: https://qyapi.weixin.qq.com/cgi-bin/victorops_api_url: https://alert.victorops.com/integrations/generic/20131114/alert/route:receiver: defaultgroup_by:- strategy_idroutes:- receiver: HIVE_堆内存使用量_aatestmatch:strategy_name: HIVE_堆内存使用量_aatest- receiver: YARN_ResourceManager堆内存使用率_Yarn告警策略match:strategy_name: YARN_ResourceManager堆内存使用率_Yarn告警策略- receiver: HBASE_BLOCKED线程数量_HBASE策略类型match:strategy_name: HBASE_BLOCKED线程数量_HBASE策略类型- receiver: HIVE_堆内存使用量_HIVE策略名称match:strategy_name: HIVE_堆内存使用量_HIVE策略名称- receiver: HDFS_HDFS已使用存储空间_HDFS告警策略match:strategy_name: HDFS_HDFS已使用存储空间_HDFS告警策略group_wait: 30sgroup_interval: 30srepeat_interval: 30sreceivers:- name: HIVE_堆内存使用量_aatestwebhook_configs:- send_resolved: truehttp_config: {}url: http://192.168.0.1:3000/alarm/v2/info/receivemax_alerts: 0- name: YARN_ResourceManager堆内存使用率_Yarn告警策略webhook_configs:- send_resolved: truehttp_config: {}url: http://192.168.0.2:3000/alarm/v2/info/receivemax_alerts: 0- name: HBASE_BLOCKED线程数量_HBASE策略类型webhook_configs:- send_resolved: truehttp_config: {}url: http://192.168.0.3:3000/alarm/v2/info/receivemax_alerts: 0- name: HIVE_堆内存使用量_HIVE策略名称webhook_configs:- send_resolved: truehttp_config: {}url: http://192.168.0.4:3000/alarm/v2/info/receivemax_alerts: 0- name: HDFS_HDFS已使用存储空间_HDFS告警策略webhook_configs:- send_resolved: truehttp_config: {}url: http://192.168.0.5:3000/alarm/v2/info/receivemax_alerts: 0- name: defaultwebhook_configs:- send_resolved: truehttp_config: {}url: http://192.168.0.6:3000/alarm/v2/info/receivemax_alerts: 0templates: []
调用 Alertmanager 的 managerment api 进行 Router 热加载:
POST /-/reloadRouter 加载后,当 Prometheus 转发告警后,Alertmanager 会根据 Router 对告警按照 Receiver 进行定点发送。如下图所示:
1.通过分组实现接收服务的负载均衡,在多集群情况下,可以针对集群在规模大小上的差异化,对接收服务进行动态调度,同时给后期的横向扩展提供适配。2.dispather 服务提供告警策略的调度,根据 prometheus 和 alertmanager 的原生 api 进行策略热加载,完成动态下发或删除策略的动作。
Gossip 机制
Alertmanager 中利用 Gossip 机制实现了消息传递机制。保证了即使多个 Alertmanager 接收到相同的告警,也只有一条告警通知会发送给 Receiver。在多集群背景,告警会按照一定的规则下发至指定的 Prometheus。而由于 Prometheus 是高可用的,则 Alertmanager 中不可避免会存在相同告警的情况,虽然 Gossip 不能保证所有实例上的数据时刻保持一致,但是实现了 CAP 理论中的 AP 系统,即可用性和分区容错性。
Gossip 机制是用于消息的传播和扩散,当节点 A 完成某项工作,它会随机向其他节点发送该项消息,后续其他节点向其余节点进行相同的传播并完成工作,直到完成所有节点的传播。Alertmanager 中,在一个实例发送告警后,会利用 Gossip 机制告知其他实例该告警已发送的信号,其他实例标记该告警,并停止发送相关告警。
性能调优方向:
•Alertmanager 参数调优Alertmanage 配置控制着告警发送的频率,形式,主要有以下重点参数:
•resolve_timeout:定义了当 alertmanager 持续多长时间未接收到告警后标记告警状态为 resolved。•group_wait:等待时间,当在等待时间内,又收到相同类型的告警,则会自动合并告警后发送。•group_interval:group 间隔时间,相同的 group 发送告警时的时间间隔。•repeat_interval:告警重新发送的间隔时间,即告警下发后,下一次相同告警的发送间隔。
以上参数根据集群的大小和接收服务的规模进行调整,其中 resolve_timeout 由于涉及状态的变化,需设置业务可容忍的最小反馈时间。当前默认值为 5m。上述参数可在根源控制数据发送量,能有效控制告警瞬时爆发的情况。
•状态过滤及合并
告警状态有三种状态:Inactive、Pending、Firing。
1.Inactive:非活动状态,表示正在监控,但是还未达到告警策略设置的阈值,尚未触发告警。2.Pending:表示指标数值已经达到告警阈值,但是还未达到告警策略设置的持续告警时间,暂不能发送告警,处于等待发送的状态。3.Firing:表示告警已处于激活状态,已满足所有告警条件,当前告警持续发送至 Alertmanager。
上述内容由 Prometheus 控制,只有 Firing 状态的信息可发送。
Alertmanager 发送告警时存在 2 种状态,Firing 和 Resolved(已解决)。同时告警策略中设置告警级别,此处为“严重”,“重要”和“警告”。接收服务针对告警状态及告警级别进行分类处理,如下表。
| 状态 | 上一次告警级别 | 当前告警级别 | 规则 |
| Firing | 严重/重要/警告 | 与上一次告警相同 | 告警合并,更新持续时间 |
| 与上一次告警不同 | 产生新告警,更新产生时间 | ||
| Resolved | 与上一次告警相同 | 告警结束,更新持续时间 | |
| 与上一次告警不同 | 告警结束,更新持续时间 |
以“Resolved”状态为结束标记进行流程终止控制,“Firing”状态的告警按照告警级别进行告警合并或者新告警生成。上述操作可减少重复数据的存储和展示,同时记录每次告警变化的情况。
•Clickhouse 告警存储及业务优化
放弃 mysql 等关系型数据库,使用 clickhouse 这种完全列式的分布式数据库管理系统。clickhouse 优势主要有以下几点:
1.支持一种基于 SQL 的声明式查询语言,便于集成开发;2.在相同的情况下,ClickHouse 可以在单个服务器上每秒处理数百个查询;3.写入性能极佳,当使用 tab-separated 格式将一份数据写入到 MergeTree 表中时,写入速度大约为 50 到 200MB/s。如果行更小,那么写入速度将更高。
但是同时,clickhouse 也有如下缺点:
1.不支持高频率、低延迟地进行更新和删除操作。2.不支持小数据量的数据写入,一般不可低于 1000 条数据。
特此,针对实际业务场景存在的少字段更新,批量告警插入,海量数据分页查询的情况,特别作出如下优化:
1.规避更新 clickhouse 中数据的情况,数据字段的更新转化为新数据的插入,即将更新转换为批量插入-删除操作,旧数据进行定期删除,新数据分组合并展示。2.将 mysql 作为告警信息的临时存储介质,当数据量达到规定值再同步至 clickhouse,规避小数据量的频繁写入。3.指标分区,设置主键排序,建立索引。
经过测试,告警信息达到 30 亿级别时,查询效率保持在几十毫秒水平。
5、总结
1.构建 prometheus,alertamanager 配置动态加载体系,提高告警策略扩展性。2.通过分组配置实现接收服务的负载均衡,完成接收服务数据及种类上的动态扩展。3.把控数据源,建立数据合并及过滤机制,优化长效处理机制。4.利用非关系型数据库作为存储介质,充分发挥性能优势,从业务上规避劣势。
6、展望
Alertmanager 提供了广泛的上下游技术支撑,其可以从多种数据源接收告警,并以多种方式对接接收者。可根据该方案对接来自更多产品的告警信息。将运维中静态的查看转变为动态的反馈只是作为告警管理的第一步。后续可应用到故障根因分析、故障恢复等实际场景,作为智能化运维中的一环。
7、参考链接
•https://prometheus.io/docs/alerting/latest/alertmanager/
•https://blog.51cto.com/u_15064632/4562297
•https://www.jianshu.com/p/54eab117e6ae
•https://clickhouse.com/docs/zh/introduction/performance




