干货分享,百度如何实现大规模分布式监控系统的高可用
编者按:近日,百度云资深研发工程师董涵受邀出席由InfoQ主办的QCon北京2018全球软件开发大会,发表了“ 大数据实时计算和存储系统的高可用建设”的主题演讲。分享了百度监控后端服务在日均处理万亿级监控数据场景下, 保障服务可用性方面的运维及开发经验,重点介绍了故障自愈、容量建设等内容,获得了参会人员的广泛关注,本文根据此次演讲改编。
Noah是百度运维自动化平台的统称,它涵盖了服务管理、监控、部署、任务调度等一系列产品和能力。而Noah的“眼睛”是Argus监控系统。经过多年发展,它已经成为一个功能覆盖全、性能强大的监控体系,它不仅支撑了百度内部所有核心业务的监控需求,还支撑了很多外部用户的运维基础设施建设,是服务高可用的基石。正因为此,监控系统本身的高可用架构建设,一直是运维技术的重中之重。
以下是正文。
挑战:如何确保高可用性
如上图所示,百度监控系统具备业务规模大、系统吞吐高等特点,其自身可用性建设是一个持续性的工程,在服务发展的每个阶段,可用性工作的侧重点也各有不同。
在前期的可用性建设中,百度已经实现了服务的弹性扩缩容能力,并且系统已经具备N+1冗余,实现了故障处理流程的自动化。
随着业务量的不断增大和接入用户量的增多,我们遇到了突发流量过载和故障恢复效率低的问题。一方面,我们支撑了百度数百个业务,每个业务每天都在做着大量的迭代更新,任何非预期的监控配置变化都可能造成监控系统的流量突增甚至过载。另一方面,随着各业务产品自身逐渐实现了故障自愈能力,监控系统已经成为了每个业务产品故障自愈效率的关键一环,这也就迫切需要监控系统自身,提高可用性和故障恢复效率。因此,我们将容量管理、故障自愈列为重点建设方向,以完善和加强百度监控系统的高可用能力。
容量数据建设:两个阶段
我们的容量数据经历了两个阶段:
最初我们依赖离线压测结果和人工修正,估算系统的负载情况。但这种方式的缺陷是显而易见的。
首先,线上服务的部署依赖关系复杂、流量大、变动也很频繁。离线压测一般投入资源很有限,是线上服务的缩水版。其测试结果很难准确反映线上服务的容量,也很难暴露线上大流量场景才能出现的一些问题。例如,某些临界区非法占用导致程序低概率崩溃的问题,属于低概率复现的bug。在线上大流量环境中才能出现。但对存储类应用的影响较大。可能造成反复重启的慢节点,进而影响系统容量。这种问题的提前暴露,对可用性保障有重要意义。
其次,人工估算修正重度依赖工程师的经验,对于每个系统来说,一般只有某些高级开发和运维工程师才能估算出有效的数据。难以归纳为统一的方法并作为工程经验加以传承,是不可持续的。
经过前期的可用性建设,我们的服务都实现了N+1冗余能力,具备线上压测的条件。因此,我们引入了线上压测,使用线上压测的系统服务数据,来作为容量数据。
我们的压测思路:在线上冗余集群,接入实际线上流量和部分模拟的业务流量。通过不断增加模拟业务流量,直到服务的核心指标,类似pv、pvlost、平响等指标开始出现异常,说明系统已达到服务能力上限。
这样做的好处是大部分流量是线上流量,更贴近实际线上场景。压测平台需要提供的流量也比较小,降低数据库类型下游处理数据污染的工作量。
我们已经基于这一组容量数据,实现了全局限流能力,可有效拦截全局流量突增造成的系统过载。
过载保护:两种限流方式
我们的服务包含了采集、计算、存储和查询等多个环节,每个环节都或多或少地会受到流量过载的影响。
最初给我们造成比较大影响的是 “查询”操作的流量,因为监控系统本身就是一次写入、反复查询的业务场景。我们的服务端提供了thrift、http等多种查询接口,这些接口的流量直接受用户业务量和操作方式的影响。例如,用户会查询一个相当长时间范围的监控数据,通过脚本进行批量查询,或请求失败时的反复重试。这些都增加了请求量,给线上服务的稳定性造成了影响。
对于此类场景,我们一方面优化系统性能,通过业务隔离、冷热数据分离、VM参数调优等方式,提升系统吞吐量。另外,我们也提供了标准化SDK,统一查询重试策略,增加退避重试、自动重选下游等逻辑。在保障成功率的同时,避免了不规范的用户操作对容量的影响。
当然,上述情况更多是能够规避预期内流量,但随着新业务的不断接入,经常由于配置错误、日志格式变化等造成数据采集端、汇聚计算侧数据量突增的情况。对于这部分流量,我们通过限流来解决,核心思想是基于统计信息,在数据流经过的各个环节,参考配额进行限流。
经过权衡实现成本和限流效果,我们选择了两种限流方式,本地源端限流和全局通路限流。
本地源端限流主要体现高时效性和低开销,覆盖单实例维度超限/流量超限场景。
全局通路限流可以覆盖全局超限场景,例如某个产品线整体的多维度组合超限。另外,它所有流量都要通过proxy转发,这种方式几乎可以在系统中的任意层次接入,不需要对系统中的模块进行改造。
故障自愈:如何缩短时间
在以前的故障中,由于监控系统本身的复杂度,我们的故障止损时间多在5min以上,最长的甚至达到十数分钟。长时间的故障,轻则造成业务失败率高、趋势图展示失败等,带来用户困扰;重则触发漏报警或误报警,无法让业务感知自身的线上故障,造成业务损失。
因此提升监控系统自身故障的止损时效性,缩短故障时间,也是关键一环。
在故障感知层面,为了提升故障感知召回率和时效性。我们在系统中使用了多种指标组合,既包含系统监控、业务监控、网络监控,也包含SLI、服务、集群、实例多种维度的指标,同时使用智能异常检测技术,做到高准确和高时效。
另外,就是自愈逻辑,需要针对不同系统的业务特点进行适配。例如,对于存储系统,自动止损需要参考数据完备性指标,只有在数据是完整的情况下,才能将流量切入目标集群。
还有一些场景,受限于成本和业务特性,我们仅能给出降级止损方案。例如我们的事件数据库(EventDB),由于某些原因,其备集群只保留了部分数据,无法承担全量查询。这种场景下,自愈系统就需要将流量尽可能倾向主集群,在主集群恢复可用状态时,第一时间将流量切回,避免长时间降级。我们通过给集群设置不同的权值实现了这个能力。
此外,我们的自愈操作会定期进行演练和盲测,确保止损预案和自愈效果符合当前系统的设计,并能够满足业务需求。
当前我们的自愈能力已经覆盖了流式计算、时序数据库、事件数据库等核心子系统。上线以来,一共执行过数百次故障自愈操作,故障召回率达到99%以上,MTTR小于2min,有效满足了故障恢复效率优化的需求,并降低了运维工程师的人力投入。
小结
分布式系统的高可用设计是一个复杂的课题,我们会持续在架构容错升级、提升故障自愈能力和恢复效率等层面继续探索,将系统的可靠性做到最优。
来源:百度云 ')}