【日常随笔】业务线上数据变更风险治理

162 阅读13分钟

本文参考自本人的以下三篇CSDN文章,欢迎大家关注!

在线上变更事故风险的治理方案当中,数据变更算是较难治理的一个环节。这是因为,不同于传统的代码或配置类变更,数据变更是需要区分具体的目的来case-by-case分析的,而代码和配置变更则不用考虑具体的变更目的,或者说,代码和配置变更的目的,就是做数据变更,不是说概念上有并行关系。因此,要治理好业务线上数据变更风险,我们首先需要梳理具体的变更场景,然后各个击破。

本文介绍三类数据变更场景以及其中风险规避的方法,详细如下:

SQL变更:问题及拦截手段

在DB做变更发布的各类场景当中,通过SQL更改DB数据内容,是最为常见的场景。既然是最为常见的场景,那么可能产生线上问题的概率也就越大。本篇文章就来探讨一下,要尽量减少SQL发布产生线上问题的可能性,需要采取什么样的手段。

首先是针对SQL语句本身而言,需要做积累检查。假设用的是MySQL,那么SQL类型大体可能分为以下几种:

  • 新增类:CREATE表/列/索引、INSERT数据
  • 更改类:UPDATE数据
  • 删除类:DELETE数据、DROP表/列/索引(包含替换场景)、TRUNCATE

针对这些SQL类型,其产生线上风险的概率也不尽相同,需要分别进行治理。

针对删除类SQL,本身就需要直接拦截告警。从变更管控的视角,删除类的变更建议需要二次确认目的以及回滚的方式。针对DELETE数据的操作一般不推荐,从业务视角来看,通过软删除的方式一般相对更加合理,一来回滚方便,二来不会破坏自增主键的连续性;针对DROP类,需要确认删除的表、列、索引是否在用,是否有上下级依赖。如果存在的话,需要确认依赖是否在用,防止业务逻辑不可用的情况。

针对UPDATE类操作,由于容易回滚,建议二次确认回滚SQL。此外,UPDATE的扫描行数和影响行数不宜过长,通过EXPLAIN的方式,可以直到UPDATE操作具体用到了哪个索引,扫描行数和影响行数是多少。如果扫描行数/影响行数过高,势必会引起慢查询的问题;而如果更新量级不高的情况下,影响行数比扫描行数低很多,也需要确认下是否有误圈选数据的问题。针对后者,如果DB集群是master写slave读的情况下,建议先SELECT圈选出数据,统计主键,再依照主键做正式UPDATE发布。

针对CREATE/INSERT类操作,这类操作风险相对于UPDATE/DELETE较低,但也有一些需要注意的点。INSERT类操作,需要确认未被声明字段的默认值具体的业务含义,如果存在业务含义,需要确认是否符合预期;CREATE类操作,针对表主要确认索引、列是否加全,针对索引主要确认是否存在重复前缀导致冗余的情况。

然后是针对DB本身而言。DB的性能监控,包括请求延时、QPS、主从同步延时、慢查等内容,以及上下游服务的性能监控,业务对账,都需要确保完整可用。这里尤其针对DDL类操作,如果是对大表的索引/列做新增或删改,容易导致同步延时,进而导致DB性能出现开销,或者业务不可用。因此这种情况,建议需要在非高峰期操作,减小变更的影响面。

整体来看,SQL发布是业务变更中比较频繁的一部分。要做到拦截问题,减少线上问题影响面,上述的策略可以做一个总体参考。

批量刷数:发布流程和风险点

在项目日常开发过程中,批量刷数也是有一定频率的变更场景之一,同时也是容易产生风险的一种变更操作。本文就来聊下,批量刷数的发布需要经历哪些流程,以及流程中每个环节中有什么风险点需要考虑。

首先需要了解批量刷数这个操作是个什么意义。无论是新增/删除一些数据也好,还是UPDATE某些已有线上数据也好,其背后要么对应着一个新业务开发,要么对应着一个bugfix。因此,批量刷数的本质其实就是一个业务需求,需要有完整的一套需求评审 -> 技术评审 -> 线下测试 -> 线上发布 -> 发布验证的过程。

第一个环节是需求评审。需求评审的主要的目的,一是为了做刷数的可行性评估,二是做刷数记录归档。

由于刷数的时间长&难以回滚的特性,不到万不得已的情况下,修复问题或是开发新需求,一般是不需要刷数操作的。如果需要做刷数操作,那么就需要提供需求背景信息,以及为什么一定需要刷数操作来达到需求目的,这样,从PM和TL角度,可以初步评估刷数的必要性,以及是否有更好的workaround。如果需要做刷数,那么这个需求就可以被归档到特定的业务模块里,以方便做进度跟踪和方案回溯。更甚者,如果需求管理平台自带流程管理和审批功能,那么在发布过程中,许多review跟审批操作都可以统一收敛到需求管理平台当中,这也是符合业务习惯的一种落地方式。

之后第二个环节便是技术评审。技术评审是整个批量刷数过程中最为重要的一环,因为在这一阶段,就必须考虑到整个刷数过程需要如何操作,上线分怎样的步骤,以及出现问题如何止损,刷数正确性如何验证。就规避风险而言,具体有需要考量以下点:

  • 上下游关系:厘清刷数DB/服务涉及的上下游业务链路,尤其留意刷数操作触发下游数据同步/消费任务的场景时,引发过高并发/QPS的问题。除了确认上下游链路的完整性跟合理性外,还需要通过历史运行数据,估算一个合理的并发度。
  • SQL影响面:DML场景下需要有EXPLAIN分析影响行数/命中索引情况,DDL场景下留意主从同步延迟给业务带来的影响。必要时,拉DBA做性能跟风险评估。
  • 结果验证:在业务层面,需要如何验证刷数的效果,需要周知哪些负责人,如何确认数据有效性。这里尤其建议,测试/对账方案的评估过程,以及实际上线/刷数后验证的过程,强制QA介入,防止产生业务质量风险。
  • 操作手法:刷数是一次性操作还是分批操作,选取的case覆盖哪些,分批和观察的节奏如何,如何验证刷数的正确性
  • 过程监控:刷数期间,需要关注哪些业务和性能监控指标,监控告警需要知会到谁,级别如何
  • 回滚止损:如果刷数操作不符合预期,怎样快速回滚,避免出错后因为缺失回滚方案导致二次犯错风险

技术评审之后是线下测试。线下测试最基础的保障是业务功能正常,但这里有一个风险是,线上刷数的量,相对于线下测试的量,实际是多得多的。像是SQL未命中索引、以及下游MQ堆积消费之类的操作,在线下测试时期,大概率没有办法暴露出来。而考虑到刷数需求的紧急程度,一般也很难紧急构造很重量级的数据跟上下文来还原线上场景。因此业务层面,规避这类风险的一个方法是,在技术评审环节去评估哪些问题是小数据量测试时无法暴露的,并在线下测试环节中给予一个复查checklist兜底。

线下测试完毕之后,就到了线上发布环节,这其中有几点需要考虑。首先是选择发布的时段,一般而言需要在上下游业务的非高峰期发布,以及非节假日发布,会比较保险。其次是发布的上线审批环节,除了选定合适的审批人操作外,操作的信息以及后续发布过程的信息,需要周知到上下游关联人。之后是发布的节奏,一般采取分批次发布的方式,比如先按业务用例最小集刷10个以内的数据量,然后刷20%左右,最后刷剩下80%。分批发布过程中,需要有足够的观察时间,防止发布过程中出现异常但来不及回滚。

线上发布的风险,除了来源于方案设计层面,操作层面的风险也不可避免。如果数据量大,刷数并发QPS过高,那么很容易引发下游的问题。因此建议每一批次发布操作实际发起时,有另一人知会或者review操作细节。如果出现不符合技术方案的操作,也可以及时阻止。同时,发布过程中的业务/性能监控信息,上下游/DBA负责人也有义务一起关注,要关注的信息点,也需要在发布前的方案里,做好详细分工。

线上发布过后,就是最终的测试验证跟对账了。这里尤其注意的是,验证和对账操作,在小批次发布的时候,就可以进行操作,或者是做成实时化巡检的形式,便于及时验证发布可靠性,也能够满足某些定时刷数任务的需求。

总的来说,刷数操作,从需求提出到发布完成,整个过程是非常紧凑跟紧张的。但最重要的一点,还是得保证刷数的稳定性,即便可能会有时间层面的损失。沉淀一套刷数流程SOP,归纳可能的风险点跟处理方案,能够有效提升刷数操作的规范性跟稳定性。以刷数流程为指导,同样也能保证发布的效率,也能规避到中途出现意外的情况下,不知如何处理,导致发布脏数据或者更大的事故影响。

数据同步/迁移:变更期间注意事项

数据同步或者迁移操作也算是线上数据变更的一种类型。由于涉及的数据量非常大,一旦发生故障,会直接影响线上业务,并且较难止损。从变更风险管控的角度考虑,数据同步或迁移操作也需要走合理的发布窗口,并且在操作前也需要做足够的影响分析。本文就来聊一下数据同步和迁移的变更期间注意事项。

数据同步按照持续状态的不同可以分为一次性同步跟持续性同步。从质量保障的角度,要降低持续性同步的风险,需要额外考虑数据跟组件性能的监控,其它方面的考虑两者没有太大的差别。数据同步的操作手法也有很多种,既可以通过搭建中间件,实现一个导入binlog到MQ然后再导到其它存储的通路,也可以通过自建业务服务,通过批量刷数的方式主动导入大量数据。对于后者,在上文当中已经提到了一些通用的风险点,但如果考虑到数据同步的需要,还会有一些额外的考量。

第一块是压力,数据同步的压力相比于一般修数是更加大的,源存储有读的压力,而目标存储有写的压力,并且由于一般读操作可能会分散到多个存储节点,写压力对于单点存储的影响会更大,因此需要重点考虑目标节点当前的QPS情况,选择一个相对合适的数字。

第二块的考量点是同步数据的筛选和转化。通常如果涉及到异构数据存储,同步链路上需要执行数据转化的服务节点,这些节点也会承受一定的压力。如果服务节点的QPS过高,可能会影响服务节点连带的一些服务,或者也有可能导致服务节点注册的网关触发限流,这样就有业务不可用的风险。同时,数据转化本身的代码逻辑也需要保证健壮性,如果触发了corner-case导致服务报错,也有可能影响甚至阻塞数据同步。

第三块的考量点是数据校验。尤其针对批量调用服务接口导入数据的情况,需要通过一定的机制去验证数据的正确性,保证同步的数据生效并对符合业务需求表现。校验方面,需要补上小时级、日级的数据对账;发布过程本身,也需要保证有阶段性的灰度过程,并尽可能随机遴选数据,确保全量发布前数据验证无误。

最后再回到压力。这块讨论的是数据同步已经在线上稳定运行时,其它变更需要考虑到线上已有的数据同步链路。好比说DB数据的增量持续性同步,如果线上有大批量的修改数据,那么就会有可能导致潜在的数据同步链路因为突然的压力发生阻塞,影响某些业务可用性。要解决这个问题,需要梳理变更操作涉及的DB,以及DB涉及的数据同步链路,通过小流量灰度的方式初步检测压力状况如何,再逐步地修改并发参数,找到最合适的变更方式。