读书笔记:《混沌工程》第二部分——混沌工程原则(3、4章)

Posted by Jiajie Wu on March 26, 2020

优化一个复杂系统的性能需要在混乱的边缘进行,既在系统行为即将开始变得混乱、无迹可寻之前。

————Sydney Dekker,Drift Into Failure


开篇

在现实中,复杂系统发生“混乱”是随机且无序的。虽然混沌工程的目的是为了提前找出这些“混乱”,但者不代表混沌工程的实施也是随机的。相反,它是一门原则性很强、具有实验性的学科。

开篇引文的作者Dekker主张从整体上了解复杂系统如何失效。我们不应该仅仅着眼于眼前发生的故障组件,应当也去关注组件交互中发生的偶然事件是如何导致系统滑向不稳定、不安全状态的

第二部分主要介绍了混沌工程的基本设计方法,一些更高级的原则(运用的原则越多,对系统弹性的信心越充足)。

高级原则:

  • 建立稳定状态的假设
  • 用多样的现实世界事件做验证
  • 在生产环境中进行实验
  • 自动化实验以持续进行
  • 最小化爆炸半径

以上原则每一章介绍一种,将在之后的3篇读书笔记中相继记录。

故障注入测试(FIT):Netflix公司曾经开发过一个名为FIT的工具,用来对系统进行故障注入测试。

网络故障工具(Sloth):2017年美洲SRECon大会上,indeed.com团队介绍了他们开发的一个引入网络故障的工具。这个工具运行在基础设施的每一个节点上,包括数据库和索引服务器。

第三章 建立稳定状态的假设

定义系统的稳定性,就是定义系统正常运行的状态,用一个通用的方式来区分系统行为是在预料内还是预料外。

对于复杂系统,它有很多组件、信号,许多形式的输出,为了能够更好地进行系统稳定性的实验,需要在开始实验前对系统的稳定状态进行定义。比如,对于某个视频服务,定义每秒点击大于某个阈值,就认定该服务处于稳定状态。

稳定状态:

期望通过一个模型,基于所期望的业务指标来描述系统的稳定性。稳定状态一定要和客户接受程度一致。在定义稳定状态时,要把客户和服务之间的服务水平协议(SLA)纳入考量的范围。

新服务的稳定状态确定:

  1. 最简单的、最快度的,自己运行一下这个服务。这种方法并不是最有效的,非常耗费劳动力。
  2. 先收集和系统有关的数据(监控),通过各项指标来定义服务的稳定状态。

由上面第2种方法延伸开来讲,监控的指标中,无论是系统指标,还是业务指标,都对定义系统稳定性具有帮助。

系统指标有助于诊断性能问题,发现功能缺陷。业务指标更多与用户相关,而且抓取起来比系统指标更难。

这些指标获取的延迟越低越好。

选择指标时需要注意的点:

  • 指标和底层架构关系
  • 收集相关数据需要的工作量
  • 指标和系统接下来的行为之间的时间延迟
  如果不能直接获取业务指标,可以选取和业务关系较强的系统指标。

如何描述稳定状态?

目标:期望通过一个模型,基于所期望的业务指标来描述系统的稳定性。

具体情况,具体分析。需要注意,很多指标不是固定的,而是波动的,稳定状态并非一个阈值,而是波动的变化情况。

所处行业决定了指标是否以一种可预测的方式随时间波动。可预测的方式,确定稳定状态会比较容易;不可预测的,确定稳定状态会非常复杂。

建立假设

在开始实验前,需要对实验结果有一个大概的假设。

虽然混沌工程是要找出系统未知的隐藏的问题,但这不代表就可以不对实验结果进行假设。因为没有假设就不清楚该从数据里获取什么,也很难得出有效的结论。

  1. 定义指标并理解稳定状态的行为;
  2. 建立实验的假设,思考注入不同事件可能得到的结果;
  3. 思考如何衡量稳定状态的变化,如何测量偏差(定义偏差的合理范围等等);

金丝雀分析:

在新代码发布前,先将它放到一个只接受一小部分流量的集群中进行验证,确保新版本的稳定性、健康性,最后再向外发布。

Netflix有自己内部的一套金丝雀分析工具(ACA)

第四章 用现实世界的事件做验证

常见的不可预测事件分类:

  • 硬件故障
  • 功能缺陷
  • 状态转换异常(例如发送方和接收方的状态不一致)
  • 网络延迟和网络分区
  • 上行或下行输入的大幅波动以及重试风暴
  • 资源耗尽
  • 服务之间不正常的或者预料之外的组合调用(最复杂的异常行为)

确定引入那些事件之前,需要估计这些事件发生的频率和影响范围。选择发生频率高、影响范围大的事件,更能测试出系统的稳定性。

除此之外也要考虑具体的大环境和大背景(文化因素?)。比如,在传统数据中心背景下,基础设施的稳定高于一切,硬件故障相对不常发生;当数据中心被迁移到云上,硬件由运营商来管理,硬件故障可能频繁发生。

故障隔离

  1. 故障隔离可以是物理隔离也可以使逻辑隔离。
  2. 隔离是容错的必要不充分条件。除此之外,还需要某种形式的冗余或者优雅降级。
  3. 故障域:一个故障的影响范围和隔离范围。

混沌工程采用 故障域 概念可以提升试验效果和效率。

向系统注入 根因事件:每一个资源都会形成一个故障域,这个故障域包括强依赖该资源的所有组件。向系统注入根因事件会暴露这些因资源共享而形成的故障域。例如,微服务架构中的服务组就是一个故障域。

  ps:重点强调:注入的事件一定要是我们认为系统能处理的。注入的事件也不仅仅只是故障和延迟,而是真实环境中所有可能会发生的。

Blockade

戴尔云开发的一个开源、基于Docker的、用来测试分布式应用的网络故障和网络分区的混沌工程工具。包括创建任意分区、容器数据丢包、容器网络延迟注入,以及在故障注入时便捷的系统监控能力。

总结和后记

定义稳定状态的假设 是混沌工程原则的第一条原则,它就类似对一个问题的定义。定义好了,那么之后的实验也会更顺畅地进行下去;定义不好,对后续的工作可能会造成连锁的不好的影响。

用真实事件做验证 它包括故障注入,但绝不只是故障注入。重点是通过注入根因事件找出故障域。

-END-