写点什么

中间件运维之故障自愈

发布于: 2 小时前

1. 背景

1.目前中间件容器节点故障、机器资源不足(磁盘大小、内存大小、cpu)等问题时有发生,接入自动化运维后可快速的处理集群异常问题。


2.以前处理问题需要人工介入,人力成本较大,运维流程缺乏规范。

2. 目标

1. 标准化,规范运维流程,制定标准的运维流程。


2. 可视化,运维流程可视化、平台化,做到可追踪,可回溯。


3. 自动化,容器重建,进程启停,部分指标通过根因分析实现故障自愈。

3. 故障自愈架构图

故障自愈的监控数据采集模块,周期性将采集到的各实例指标数据上报给处理器,处理器通过调用元数据模块获取匹配规则、故障自愈处理流。匹配异常数据成功并生成运维事件,再经过事件收敛过滤以确保没有大批量相同属性(如同业务、机房等),最后执行对应编排的自愈处理流,运维事件恢复,发送通知,业务恢复正常。


产品架构图:



整体流程图:


4. 方案设计

4.1 故障识别

通过拉取实例监控数据、多指标聚合检测识别出异常,并触发故障自动化流程。

方案一:过滤型检测监控数据


过滤型检测匹配,只跟数据本身有关,时间窗口设定没有要求,数据来一条处理一条。达到设定的异常阈值时触发运维事件。此检测方案过于粗暴,对于一些监控数据存在瞬时突刺现象也会触发误运维,若频繁自愈会影响中间件稳定性。此方案一般用于告警触发,用作运维触发存在一定风险。

方案二:基于窗口时间检测

窗口选择分类:



固定窗口(fixed windows):设置一个固定的时间长度,实时统计窗口时间内的数据。通常情况会根据 key 做一些 Partition 划分,这样可以做一些并发处理,加速计算。


滑动窗口(sliding windows):设置一个窗口长度和滑动长度,如果滑动长度小于窗口的长度,那么就出现一部分窗口会互相覆盖,部分数据存在重复计算;如果窗口长度等于执行周期,那么就是固定窗口的模式;如果窗口长度小于执行周期,就是抽样的计算了。


会话窗口(session windows): 针对的是具体的某个事件,比如特定的人看的视频集合等。会话要等待的数据是不确定什么时候到来的,窗口永远是不规整的。


结论:周期性监控数据可以看作相对规律且无穷的数据,故而前两种窗口模式做流式计算比较适合。


窗口时间选择:


基于计算时间的窗口处理问题是非常简单的,只要关注窗口内的数据就可以了,数据完整性也不用操心。但是实际的数据里肯定带有事件时间,这个时间的数据通常在分布式系统中也是无序的,要是系统出现某些点的延迟,那么得到的结果其准确性就大大降低了。基于事件时间对于业务准确性有很明显的好处,但是也有很明显的缺点,因为数据延迟,在分布式系统很难说这段时间内,数据已经完整了。


数据完整性保障:


显然无论窗口给的多大,永远无法保证,符合窗口内事件时间的数据一定能够准时到达,利用 watermarks (水位线)可以解决什么时候认为数据结束关闭窗口进行计算的问题。如下图:



设定固定窗口 2 分钟聚合计算,得到的 4 个窗口聚合结果分别是 6、6、7、12,但在第一个窗口 12:02 聚合结束后,其实该窗口数据在 12:03 才算完整完整,故而得到的结果不准确,引入 watermark 可得到正确的聚合结果 11。这里的 watermark 表示多长时间以前的数据将不再更新,也就是说每次窗口聚合之前会进行 watermark 的计算,首先判断这次聚合窗口最大事件时间,然后加上所能忍受的延迟时间就是 watermark,当一组数据或新接收的数据事件时间大于 watermark 时,则该数据不会更新,可弹出窗口内的数据进行计算且在内存中不再维护该组数据的状态。


流式计算之固定窗口:


中间件监控数据周期性上报数据量不是很大,分布式系统中对于轻量级流可以考虑利用 redis 做实时聚合,并实现滚动窗口触发。



如上图所示,设定匹配的窗口大小为 2 分钟,允许数据最大延迟时间为 2 分钟,则 watermark = 窗口时间的最大值+2,通过往 redis 缓存实时聚合两个窗口结果即可完成窗口持续滚动,当事件时间大于 window1 窗口的 watermark threshold 时间时,立即弹出 window1 窗口给 process 处理器判断是否超过异常阈值,若超过则产生运维事件等待自愈,同时将第二个窗口 window2 的数据移动至第一个窗口 window1 中,从而实现持续滚动效果。


总结:滚动窗口占用缓存空间较少,聚合速度快,不足地方可能存在匹配不精准,如果设置窗口时间较大,聚合结果到达配置阈值的数据刚好位于两个窗口相连的数据集中,此时是不会触发运维事件的,其次多指标(一个监控指标对应一个固定窗口)匹配运维事件时,会存在多窗口到达水位线后的弹出时间对不齐的情况,可能存在永远匹配不上的情况。这个时候还需增加窗口之间匹配等待来解决该问题。基于滑动窗口方式可解决以上两个问题。


流式计算之滑动窗口:



多指标滑动窗口; DataEvent 为某个实例监控数据,每分钟上报一次或多次,数据包含 3 个指标项 metrics1、metrics2、metrics3,若配置三个指标项周期聚合结果超过设定阀值则触发运维事件,其周期窗口大小分别为 6 分钟、5 分钟、3 分钟,滑动窗口时间 1 分钟,允许最大延迟时间为 1 分钟,则在 12:08 分后同时弹出三个窗口数据进行聚合匹配运维事件规则。同时窗口向前移动,不再参与统计的数据则可不在缓存中维护,如上图带虚线的指标项数据。

4.2 事件收敛及自愈控制

事件收敛:


相同事件在短时间内多次发生,自愈事件可能会发生并行执行或在短时间内多次触发。自愈往往会涉及到容器或者服务重启,频繁自愈影响集群稳定性,对此可设置一个静默时间对事件做收敛,静默时间未过不再往自愈服务发送事件。


自愈控制:


1.同一集群下,集群事件与实例事件互斥,即保证在同一时刻只允许集群中的一个节点进行自愈行为。若集群中的实例都在自愈(如垂直扩容),则会导致集群不可用。同集群实例实现串行化自愈可通过 MQ 发送端利用集群 ID 做路由到指定队列上,消费端拉取队列按顺序消费完成。如下图所示:



2.当有新节点添加/下线时,会给节点 2 分钟的容忍时间,防止由于节点刚刚添加到集群/或下线的不稳定性导致错误自愈。


3.针对自愈解决不了的场景设置自愈次数上限,防止循环自愈,并发通知。


4.历史过期事件过滤,每个事件有过期时间,表示这个事件在发生多久后,会认为过期,事件在决策流程时会先判断是否有效,过期的事件不用再处理。

4.3 故障原因分析

运维事件触发回调进行故障分析,分析根本原因,识别误运维。拉取运维事件对应的根因分析策略,主要利用动态指标+决策树实现自愈,整个分析自愈模块可视化。指标:主要是监控项的指标,如系统负载、cpu 使用率、内存使用率、网络 I/O、磁盘使用率、系统日志、gc 日志等


e.g 决策树模型



e.g 节点离线总结结论


4.4 故障自愈

利用根因分析及异常结论总结,在元数据模块进行可视化的事件处理流程编排以及决策动作、执行动作的配置,当检测到运维事件发生后,结合事先编排的事件处理流,并执行相关的流程动作,实现服务自愈效果。


节点异常处理流编排如下:


5. 总结

通过拉取监控数据,检测匹配异常数据触发运维事件,再结合编排的事件处理流自动完成一些比较繁琐的自愈行为,整个执行流程可视化、串行化。以上仅例举节点异常事件编排,还可编排磁盘清理、扩容等运维场景,同时沉淀故障处理经验形成知识库,回溯过往发生的异常监控数据来提前发现问题,并处理潜在故障。

作者简介

Carry  OPPO 高级后端工程师


目前在 OPPO 中间件团体负责中间件自动化运维的研发,关注分布式调度、消息队列、Redis 等中间件技术。


更多精彩内容,请关注[OPPO 数智技术]公众号


发布于: 2 小时前阅读数: 3
用户头像

还未添加个人签名 2019.12.23 加入

OPPO数智技术干货及技术活动分享平台

评论

发布
暂无评论
中间件运维之故障自愈