9

万级实例规模下的数据库故障自愈探索实践 - 更多 - dbaplus社群:围绕Data、Blockchai...

 1 year ago
source link: https://dbaplus.cn/news-160-4986-1.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

万级实例规模下的数据库故障自愈探索实践

林锋英 2022-12-15 10:54:29
     

本文根据林锋英老师在〖deeplus直播:大规模数据库运维的化繁为简之术〗线上分享演讲内容整理而成。(文末有回放的方式,不要错过)



林锋英,vivo互联网高级数据库研发工程师。

近几年 vivo 数据库运维规模快速增长,从数量上看增长了几倍,达到了万级别的规模,与此同时 DBA 每日需要处理200多条告警。

随着运维规模越大,线上故障也就越多,DBA 对于每个故障的处理时效将会下降,如果没有强有力的工具能提高故障的排查和修复效率,那么线上的稳定性就得不到保障。因此我们的想法是,我们固然要不断提供更加丰富的工具,但无论工具再丰富,都需要人去主动使用,因此更重要的是改变以人为主、工具为辅的运维模式,引入自动化分析和自愈的手段来提升运维效率。

2.实现思路

2.1 短期和长期目标

目标确定后,接下来需要确定目标的实现思路。我们调研了业界的一些解决方案后,发现能力的发展可以总结为以下三个阶段:

图片
  • 平台化:能够提供一些数据和统计信息,运维人员再基于这些信息来进行运维;

  • 智能化:已经能够提供分析和建议,但是否采纳需要运维人员自行判断;

  • 自动化:已经有部分场景可以实现自动恢复,无需人工参与了。

通常平台的发展过程如上所述,但是也需要结合我们自身的情况来决定,因为我们投入的人力较少,不是成团队地投入这个工作,因此不太可能遵循这么一个发展策略。因此基于人力投入的情况,我们定下的目标是,短期内我们要做投入产出比最高的工作,以求达到立竿见影的效果,但长期来看,图中成体系的基础能力还是需要建设起来。

2.2 寻找切入点

为了短期达到立竿见影的效果,就需要寻找一个切入点。如果我们观察一个故障的生命周期的话,可以看到故障的生命周期分为故障前、故障中和故障后:

图片
  • “故障前”包括故障预防 ;

  • “故障中”包括故障发现、故障定位和故障恢复;

  • “故障后”包括故障复盘。

那么从整个故障的生命周期来看的话,按照我们的经验,DBA 大部分时间都是消耗在故障定位和故障恢复上的,而因为每类故障具有相似的定位路径,所以比较容易去定义定位规则、沉淀专家经验。因此我们的想法是将重点放在故障定位和故障恢复这两个阶段上,去提高 DBA 的运维效率,优先找一些投入产出比高的场景去实现故障自愈。

2.3 结合实际情况后的发展思路

结合前面提到的短期目标和长期目标,我们确定下来这么一个发展思路。

图片

首先我们会重点去实现各类故障场景的自动分析和自愈,这些自动分析和自愈行为是由故障消息驱动的,这也是一个比较直观的方式,因为 DBA 通常也是收到故障消息后,才去进行故障定位等操作。然后当过程中需要某类基础能力时,就去重点发展该能力。

这样我们的短期目标和长期目标就都能兼顾到。

2.4 如何在实现过程中保证数据库可用性

在实现方案前,需要先思考一个问题,即我们如何在实现过程中保证数据库的可用性?

之所以把数据库可用性单独提出来,是因为故障自愈是自动触发、自动执行的,而且过程中通常需要去触达数据库,比如查询数据库的状态或执行操作,那么这种自动的操作本身会带来比较大风险,因此更加需要考虑实现过程中,如何避免对数据库造成的可用性影响。那么如何避免可用性影响呢?我们的答案是将每个故障自愈方案上线的流程标准化。

3.具体实现

3.1 故障自愈方案上线流程

下图是我们以可用性为第一考量的前提下,确定下来的故障自愈方案上线流程。

图片
  • ①确定方案:当有一个新的故障自愈场景需要实现时,首先需要把自愈方案确定下来,即确定在这个故障场景中,需要“做什么、怎么去做”。这里有两种确定方案的方式,可以和 DBA 进行咨询交流确定方案,也可以通过分析线上案例来确定方案

  • ②开发测试:方案确定后进行程序的开发测试,此处不必赘述

  • ③线上灰度:开发测试完成后,需进行线上灰度,这里我们支持针对具体对象进行灰度,比如某个集群经常发生该类故障,那么可以指定灰度该集 群。如果没有具体对象,也可以设置百分比随机灰度。当然如果某些故障场景发生的频率很低,我们一开始也会进行线上演练,通过在线上模拟故障的方式来进行验证

  • ④全网生效:灰度完成后,开放全网生效

  • ⑤演进方案:每个故障自愈方案不是上线后就是最终形态,还需要我们结合用户反馈以及后续案例来不断进行迭代优化

上述流程的五个步骤中,“确定方案”和“演进方案”是重点,因此下文展开介绍。

3.1.1 确定方案

在实践中,我们通过和 DBA 咨询交流以及分析线上案例的方式来确定故障自愈的方案。

这里介绍下发生磁盘告警时自动清理 MySQL Binlog 的方案,通过和 DBA 咨询交流的方式,我们确定了该方案。具体方案流程如下图所示,其实整个方案就重点关注了两个问题:

第一个问题,如何确定哪些 Binlog 是不可以清理的?答案是未备份的 Binlog 不能清理,因为会影响增量备份;备库未同步的 Binlog 也不能清理,因为会影响复制同步。

第二个问题,如何保证删除过程中的系统可用性?这里我们采用分批删除、每次删除睡眠一秒的方式来平滑删除带来的 IO 压力。

图片

有时不是所有方案都能够通过咨询交流的方式确定下来,对于根因分析的场景,因为每个运维人员的运维经历有所差别,如果要把所有可能的情况枚举出 来,那么会导致方案十分冗长,因此一种更好的方法是通过分析线上真实案例来确定方案,这样产出的方案是最贴合线上情况的,后续也可以不断结合案例做迭代优化。

这里介绍下我们如何确定 SQL 类告警根因 SQL 分析方案。为了确定这个方案,我们分析了50个线上案例:首先找出哪些案例是能明显看出有根因 SQL 的, 再对有根因 SQL 的类别进行细化,最后得到根因 SQL 的判断步骤。

图片

3.1.2 演进方案

针对某个故障场景的方案通常不是一步到位、直接拥有自动恢复故障的能力的,而是在实践中不断演进。我们把方案演进的过程分为下图三个阶段:

图片

那么为什么要分阶段去演进方案呢?

  • 从效率的角度看,能够先快速上线比较简单的方案,可以快速地提高运维效率;

  • 从可用性的角度看,前一阶段是后一阶段的基础,只有前一阶段验证成熟了,再去不断演进是比较安全的做法。

以 SQL 故障场景为例来演示方案的演进过程。我们的 SQL 故障场景方案一开始只是提供数据和统计,然后进一步地通过案例分析的方式,使其可以根据规则尝试找出导致告警的根因 SQL,目前正在实现对根因 SQL 的自动优化建议,最终目标是可以具备对问题 SQL 自动优化、自动限流的能力。

图片
3.2 故障自愈流程

基于上述的思路,我们实现了一个故障消息驱动、基于规则的故障自愈流程。

图片

首先我们监听了故障消息,当自愈系统接收到故障消息时,会根据这个消息类型去规则库中查找对应的自愈流程,再通过流程编排引擎运行起来。流程中会去调用相关基础能力,最后生成一个处理结果通知,发送到我们的工作沟通软件。同时也会将这次流程的运行信息保存到分析中心,用户后续可以在分析中心看到详细的现场快照、分析结果,还能对这次分析进行评价标注。

下面对流程中的重点组件进行介绍。

3.2.1 故障消息

首先是故障消息,在一开始设计时,我们期望是可以支持接入各种故障消息,比如告警事件、巡检事件等,但是在实践中,我们还是优先针对 TOP 告警场景进行开发,因为故障消息中,绝大部分都是告警。而且据我们统计,TOP 5 的告警差不多占了所有告警的一半,优先针对 TOP 告警短期内能取得不错的效果。

图片

3.2.2 规则库

规则库保存了故障消息类型和自愈流程的绑定关系,自愈系统收到故障消息后,会根据这个消息类型去规则库中查找对应的自愈流程。这里我们实现了一个简单的流程编排功能,我们的想法是,先实现一些原子操作,再去将这些操作组合成一个流程,这样可以让操作具有的复用性,也更容易实现新的流程。

比如针对 CPU 告警,我们将 TOP 分析和 SQL 根因分析独立成两个原子操作,这样这两个操作也能复用在其他流程中。

图片

3.2.3 分析中心

在分析中心,用户可以看到监控告警详情、现场快照、分析的结果,还可以通过这里向我们反馈这个告警的原因、如何排查等信息,帮忙我们去进行迭代优化。这样自愈流程就不是一个黑盒了,也方便运维人员之间进行协作。

图片
3.3 数据采集和计算

3.3.1 数据采集

故障自愈需要大量的数据支持,我们将数据分为三种类型。

  • 监控数据:我们这边的数据库种类比较多,每种数据库都有自己监控采集方式;

  • 日志数据:采集流程中 Agent 先会向 Manager 查询自己需要采集哪些日志,然后以类似 tail 的方式一行一行地采集,再上报给 Manager,最后由 Manager 根据配置的正则表达式解析成结构化数据,写入 Kafka。这些日志包括慢日志、运行日志、全量日志等;

  • 事件数据:我们开发了一个事件系统的 SDK,由各个服务使用这个 SDK,将自己服务的事件上报到事件系统。

图片

3.3.2 数据计算

数据采集后,一些数据需要做计算处理。我们现在对数据做实时计算的场景比较少,下图是近期的全量 SQL 需求。

图片

首先由 Agent 采集 SQL LOG 文件,进行批量上报,为了降低 Kafka 的带宽压力,上报的时候需要进行压缩。上报时指定实例地址作为 Kafka 分区 Key, 以保证同一个实例的数据能写到同一个 Kafka 分区,因此也就能保证在实时计算端,同一个实例的数据会落在同一个处理线程上,这样就能在接收到数据后,做一个预聚合,降低发往下游的网络流量。然后通过逐层聚合的方式,先聚合出每分钟每个 SQL_ID 的平均执行次数、平均响应时间等指标,再根据SQL_ID 的聚合数据,聚合出每分钟每个 Table 的平均访问次数指标。最后这份数据将用以支撑 SQL 趋势、表流量统计、SQL 过载保护等功能。

4.成果和案例

4.1 成果

10+种故障场景分析和自愈能力:

图片

使用6人月覆盖线上70%以上告警:

图片
4.2 案例

这里介绍一个案例:长时间执行的 SQL 数量达到阈值后,产生了告警,根据 SQL 根因分析得出,这是因为有一条长时间运行的 SQL 阻塞了其他 SQL,并把分析结果推送到故障处理群。从分析详情可以看出,这是一个 MDL 锁等待的经典场景,因为某条 SQL 长时间运行,备份进程执行 FLUSH 时请求 MDL 被阻塞,继而引发后续 SQL 请求 MDL 阻塞。

图片

5.未来展望

展望未来,仍有许多事项需要逐步建设完善:

  • 建立可观测、可跟踪的效果度量机制。目前可观测的指标只有告警覆盖率,而对于每次分析的有效性和正确率,现在还无法度量,因此需要建立一套效果度量机制;

  • 仍有许多基础能力需要逐步建设完善,比如 SQL 优化建议、SQL 限流等功能;

  • 基于规则的故障自愈方案容易碰到投入产出比降低、系统能力瓶颈等问题,因此需要借鉴业界方案,逐步使用 AI 技术,在各个功能场景进行尝试。

    ↓点这里回看本期直播
    http://z-mz.cn/5RSl3


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK