走近华佗,解析自动化故障处理系统背后的秘密

集群医生华佗是集群自动化故障监测和处理系统,是平台和运维对接的关键系统。一方面完成飞天其他组件不擅长的OS和硬件的故障自动监测和处理,另一方面推动飞天去及时规避硬件和OS引起的故障,使得故障能够闭环运转,大幅度减少故障处理成本和造成的影响。飞天5K项目期间的规模效应凸显出自动化处理故障的必要性,大幅提升了飞天平台的稳定性,提高了运维人员的幸福感。华佗在飞天中的位置如图1所示。

由来

2011年底和2012年初,飞天系统的通信系统使用的是夸父,夸父通过Agent代理负责本机所有的网络通信,如果机器之间想要彼此通信,需要将彼此的IP加入到对方的配置文件中。由于集群变更频繁和Agent本身稳定性的原因,出了好几起和夸父配置及连通性相关的故障。夸父处于集群最底层,要保持集群的全连通,同时集群间也有通信的需求,也需要通过变更配置文件打通连通性。日常业务中,集群经常需要上线和下线机器,导致配置文件需要经常性的变更,偶尔A集群加了一批机器,B集群压根不知道,造成集群间通信时而通,时而不通,查找原因非常困难。同时由于各种原因,会造成夸父之间的连接经常性地处于半通不通状态。查找这样的连接几乎也需要两两测试连接,对于一个2000台的集群,则需要测试2000×2000次操作,工作量非常大。华佗吸收了大量开发和运维经验,用了随机抽样覆盖加自动处理的方式解决了夸父连通性监控和处理的问题。

2013年初,云梯2集群中的硬件3年保质期已过,但任务却越来越多,连续好几次的基线超时都与坏盘、慢盘相关。但对于坏盘和慢盘,大家一直都没有一个很好的办法和标准来界定――究竟坏到什么程度、慢到什么程度就会对应用产生影响。于是华佗就开始了解决坏盘和慢盘问题之旅。飞天5K项目期间,由于规模效应,盘、机器、网络的各种故障几乎成为了常态,各种异常都成为造成集群服务质量严重下降的根源。但在应用层来处理这种底层的异常显然是隔靴搔痒,又慢又费劲,例如:

  • 发现总有一些机器有各种异常,使之很慢,但又没有完全死透;
  • 集群间12根光纤有一根异常,造成部分通信异常,出现大量长尾的数据拷贝进程,拖慢总体进程;
  • 集群内的一台交换机时断时通,造成服务断断续续或者服务时间巨长;
  • 有一个Job的Worker进程内存总是超限造成被杀,影响其他进程。

定位和思考

在过去的3年里,尤其是做飞天5K项目的3个多月里,飞天单集群的规模增长了近一个量级,离线集群的数量也增长了10倍,而运维人员的规模却没有显著的增加。按照当时的增速,运维人员和机器的数量比例将达到10000 : 1。根据以往的运维经验,这个规模下,如果没有故障的自动化处理,运维人员几乎24小时都要处理故障,因为底层一个简单的故障放大到上层可能是几十倍到几百倍的复杂度。例如一个交换机的网络故障(半坏不坏),可能就会引起大批量的任务失败,但调查失败的根本原因可能要翻遍整个系统才知道是网络故障。更重要的是单集群的规模增大之后,人为处理故障过程中可能出错的概率更大,并且一旦出错,整个集群会无法服务,影响面将更大。

飞天平台各个组件设计之初已具备了非常好的容错功能,但一飞天平台各个组件设计之初已具备了非常好的容错功能,但一直没有和运维体系进行很好的对接,故障处理一直是运维人员通过各种零散的工具或人工在维护处理,成本越来越高。由于以上原因,华佗就承担了飞天平台自动化故障处理系统的任务,提升集群故障发现、处理的效率和准确性,解放运维人员,提高飞天稳定性和可靠性。

实现

如何能又快又好地发现和解决线上故障呢?我们进行了很长时间的思考,得到了图2中的架构图。

华佗一般通过华佗Master与外围系统打交道,既接受盘古、伏羲这样的飞天组件订阅硬件、OS相关对象的状态机以便采取对应动作规避故障,同时支持驱动磁盘、内存这类对象的维修管理。如图3所示,每个C代表一个Checker,W代表一个Worker。每个虚线框代表一个集群,每个集群会出一台机器组成一组Master,通常3~5个大集群共用一组Master。

华佗内部是典型的Master / Slave架构

  • Master:一般1个数据中心共享一组Master,Master采用Raft协议实现高可用,Master提供Agent所需的各种存储、协调、全局决策调度服务。例如,状态机服务、MaxCompute倒入服务、Quota服务和Checker分发。
  • Agent:调度本地Checker和Worker,同时提供本地Checker和Worker所需的服务――KV和Queue等。
  • Checker:按照Master配置要求,完成故障的发现和状态维护,同时产生Action Checker来完成故障处理。
  • Worker:处理Master发送的Task。
  • Client:Client以SDK的形式内嵌在飞天的各个组件中,可以订阅华佗各个对象的状态、Event等。

外围系统

  • MaxCompute:阿里云数加-大数据计算服务,华佗用MaxCompute进行大规模系统和故障的数据挖掘,用以提高故障检测准确率和预测故障的发生。阿里云数加-大数据计算服务MaxCompute产品地址:https://www.aliyun.com/product/odps
  • 维修系统:运维团队和供应商对接的硬件维修平台,华佗通过维修系统以工单的形式来报修硬件。
  • Portal:华佗提供运维操作平台,用来监控和管理整个华佗。
  • ApsaraComponent:飞天基础服务模块,包含伏羲(飞天的调度系统)和盘古(飞天分布式文件系统),通过华佗SDK订阅华佗的状态机来实现与华佗的交互。

详细实现

描述故障

想要很好地处理故障,就需要清晰地描述故障。状态机是一种不错的选择,我们对于任何需要华佗处理的对象都建立状态机来管理其整个生命周期。常见的状态机包括但是不限于:磁盘、机器、网络、内存、CPU、Apsarad(飞天守护进程)、ChunkServer(飞天存储进程)。一个故障的定义很自然:对象状态或状态组合。例如,对于磁盘故障,当一块盘处于ERROR状态时,单纯就是磁盘故障;3块盘故障处于ERROR状态时,就是整个机器的故障。状态机是整个华佗的核心,所有的故障发现、处理、预测都是围绕状态机来完成的。

故障发现

Checker负责发现故障,发现故障后产生故障事件,Master处理Checker发现的事件,派发相应的动作给Worker,Worker负责执行具体Action(短期)或者Task(长期运行);同时如果满足条件,将进行状态迁移。每个对象的状态都有对应的Checker,Checker会一直负责检查处于本状态的条件,如果已不满足了,则直接将状态机变回次态。Checker是整个华佗的基础,所有故障的发现,触发源头都是Checker。Checker是系统里量最大的,也是Badcase积累的结果,如果要保持系统Checker快速的迭代更新,同时要防止Checker本身有Bug而造成滚雪球效应,该怎么办?先思考一下,后面会说到。

处理故障

当Checker进行状态变迁或处于某个状态时,会产生对应动作(Action),对应动作会进行某个操作,一直到失败或进入下个状态。有些状态的变迁在Master端可能会产生Task,Task需要一些机器整体统一做一个动作,例如,某个集群的Master Role迁移,或某个交换机下线。

版本控制:灰度发布,全量更新,版本校验

Checker定位于可能快速更新迭代的组件,以便运维或者开发能够快速地支持各种故障的处理,Checker本身可能是个Binary、脚本、Rule。为了保证线上Checker的质量,除了日常的Review和测试,线上的灰度发布和版本控制必不可少。华佗使用SVN进行Checker的版本管理,使用Master进行版本分发。华佗可以做到IP粒度版本控制和校验,基于此,华佗可以进行多版本同时灰度,同时验证发布,以增加Checker的迭代速度。

Quota管理和手工驾驶

在整个华佗运行过程中,可能会有我们预料不到的Bug产生,这些Bug可能会放大错误,产生滚雪球的效应。例如,可能磁盘的判断会在特定条件下出错,这样会让大批量的磁盘下线,造成集群剧烈抖动。也可能Kernel出现类似208天的问题(Linux Kernel著名的一个Bug:系统连续运行208.5天自行重启),引起机器大批量的宕机。基于以上考虑,结合华佗自我保护机制,华佗引入Quota管理和手工驾驶,即当故障率超过华佗预设阈值时,它将直接报警,不再采取任何措施,进入手工驾驶状态,同时日常的变更也可以进入手工驾驶的状态。

Portal

华佗的所有状态机、报警、事件和动作都可以通过Portal和API进行查询和订阅,方便其他系统接入。Portal也可以进行日常的华佗版本查看、变更和其他的操作。最常见的使用场景是当某个Job失败后可以通过Portal来查询Job所在的机器是否发生过故障

日常数据收集、故障深度挖掘和预测

除了日常的实时故障处理,华佗也收集OS和硬件的关键数据,如Dmesg、Smartctl、Top、Tcp、Ecc等。这些关键的数据进入到MaxCompute进行数据挖掘,来预测某个对象下一个状态(故障)的发生概率,同时也会根据挖掘的结果来调整Checker的规则和参数,以提高故障检测的准确率。

常见的场景

华佗目前已能够处理主流硬件和OS相关的故障,长尾Badcase处理逐渐增加中,可以适应快速迭代和开发节奏,同时帮助运维和开发共同沉淀线上集群的故障管理经验。

磁盘管理

图4中每个节点都是一个状态,每条线上标注了进入到下一个状态的条件。

A.磁盘打分

华佗会根据磁盘的硬件、软件相关的10多个检测项目,按照既定规则库对磁盘的100多个评分项进行一个综合评分,将磁盘进行分级:Good、Slow、Warning、Error和Fatal。磁盘的好坏和快慢受很多因素影响,加上应用对于磁盘的诉求也不一样,如Online关注延时,Offline更关注吞吐,还有更细分的指标关注寿命等,所以打分规则是动态调整的,各个应用可以指定各个指标的权重和计算规则。图5是我们对一年的某个生产数据进行分析后得出各个规则和指标对于最终结果的影响度。

图5中的横轴是各个Rule(指标),纵轴是影响度。前面几项都是根据后面的一些基础指标慢慢积累调节出来的,例如在Offline的集群上,我们发现Kernel某个线程D状态的次数决定了这块盘的快慢,如果长期处于D状态,则磁盘一定是出故障了。

B.磁盘的状态变迁

  • 在磁盘进入SLOW或WARNING状态时,在线应用一般会选择不再使用此磁盘,因为此时磁盘可能已经出现损坏的迹象,会造成延时大规模增加,但对于理想的应用则可以继续使用。
  • 一旦磁盘进入ERROR状态,则表明此磁盘可能马上损坏,必须立即执行下线动作。此时盘古通过订阅华佗的磁盘状态机识别到后,会将磁盘设置成SHUTDOWN状态,即磁盘不可读写开始备份数据。
  • 待华佗通过盘古确认数据备份完毕(数据安全),将磁盘进入到REPAIR状态。在REPAIR状态时,华佗会通过运维的维修系统进行报修。
  • 供应商根据报修系统报修的状态,每周进行2~3次的磁盘更换服务。更换完毕后,华佗会自动检测到有新盘上线,继而进入到NEWBIE状态。进入NEWBIE状态的磁盘,华佗会进行自动分区、格式化、预挂载。
  • 预挂载完毕后,华佗就会进入TEST状态,进行基本的检查和小型Benchmark测试后决定继续维修还是上线。
  • 测试通过的盘,就会挂载到真实的挂载点上开始供盘古使用。同时磁盘进入到GOOD状态。

C.所有的磁盘数据都会通过Analyzer进入到MaxCompute进行挖掘和分析,分析完毕后会通过调整规则、指标、参数等提高磁盘检测的准确度,这是一个长期的过程。

机器管理

图6是机器状态转换图,机器管理和磁盘类似。

  • 当机器有各种原因(根分区只读、Load超高、内存坏)会进入的ERROR状态,伏羲会订阅华佗的状态,发现进入ERROR状态,会将在这台机器上的进程全部调度走。
  • 调度走以后,华佗机器的状态机会很快进入到FIX状态,进入到FIX状态后会根据进入原因采取对应的动作,尽量修复(Reboot、Restart相关进程、清理磁盘)。如果修复失败,机器的状态机将进入REPAIR状态。
  • 进入REPAIR状态后,盘古会通过订阅的状态机发现,自动将机器SHUTDOWN开始备份数据。备份完毕后,华佗会将其通过报修系统报修掉。厂商会根据情况进行每周2~3次的机器维修。
  • 维修完毕后,机器进入NEWBIE状态。进入NEWBIE状态的机器将会进行RECLONE相关环境准备等操作。
  • 完毕之后进入待上线状态TEST。华佗会进行基础的环境检查,检查完毕后通知Fuxi上线。

网络故障检测

网络的检测不像磁盘,单机就可以解决掉,并且现在都是双上联、Multipath的网络,就是你和A机器进行通信走的是一根线一条路,你和另外一个机器B进行通信走的是另外一根线一条路。而恰恰有问题的情况是:一根线或者其中一个交换机有问题,造成网络时好时坏、时快时慢,加上集群热点等情况,非常难于定位和排查。华佗采用简单投票的方式筛选出最有问题的机器,工作方式如下。

  • 每台机器会实时监测到它所通信机器的网络丢包、TCP重传、RTT、带宽等指标。
  • 应用本机规则决定是否投票给异常的机器,投票给其他机器的同时投票给自己。
  • 得票最多的top N机器就是有问题的机器。
  • 找出top N机器所有通信有问题的五元组(协议、源地址、源端口、目的地址、目的端口),根据五元组算出所有通信的路径。
  • 对于算出路径上的网络设备,查询其错误日志,看是否有相应的故障,有问题报警给网络。如果有问题,则将对应的机器转换至ERROR状态,进入坏机器的处理策略中。

心得

通过建立磁盘自动化的处理和磁盘故障的预测,可以大大提高集群磁盘的整体合格率,原因是新集群上线一段时间内,出厂不合格的磁盘,华佗通过集群预热期就下线掉了,再经过半年坏盘淘汰后进入稳定期,集群整体磁盘的可使用寿命大大提高。在我们的实践中,坏盘率可以做到非常接近磁盘的MTTF。

磁盘作为集群中数量最多、增长最快(6块→12块→18块→24块)、故障率最高、处理最复杂(涉及到数据安全)、最消耗人力的硬件,自动化的处理收益最高。磁盘作为集群中数量最多、增长最快(6块→12块→18块→24块)、故障率最高、处理最复杂(涉及到数据安全)、最消耗人力的硬件,自动化的处理收益最高。

机器各种故障区分度很低,对于Offline的业务,我们采用了最简单直接的处理方式,Replace、Restart、Reboot、Reimage和SHUTDOWN。使得每种故障能够有明确的行为,降低上层处理的复杂度。

网络是非常基础的服务,所有的服务都依赖网络,使得网络变得非常敏感和复杂。一个5K集群,其交换机数量100 + ,端口数量超过10K。一旦有问题,第一时间定位是最关键的,华佗的引入使得网络故障定位由原来的小时级别降低到分钟级别。

总结

由于故障的处理和平台及业务密切相关,所以这里只是介绍了华佗通用的一面,只是冰山一角。具体各种故障处理里隐藏着大量的细节,这些细节的处理都是平台拿一次次的故障堆出来的,这也是Google和Amazon等大型平台对于自动化平台讳莫如深的原因。

阅读原文直接点击

相关推荐