本文总结了过去遇到的许多次宕机事件中反复出现的问题。工程团队在处理这些事件时,某些模式(无论是作为风险还是作为资产)几乎次次都能遇到。
从这些反复出现的模式中,我们提取出了一些工程团队准备采纳的经验教训,希望你也能从中学到有用的知识并做好准备。
使用自己做出来的东西是一种很好的做法——毕竟,如果你都不这样做,你怎么能指望客户使用你的产品和服务呢?如果你不拿自己公司的生产力当作赌注,如何为这些产品和服务实现的流程背书呢?
但这种健康的习惯也会产生反作用,因为这种行为会造成依赖循环。所谓依赖循环是说,你依赖自己的系统……来修复你的系统。
这种依赖模式还有其他一些实例,它们都违背了一条座右铭:不要重复自己。为什么只为了监控用途就要再运行一种数据库?你的生产数据库本来运行得很好,所以把遥测数据也放在那里就行了。
这些循环也会在停机期间带来严重后果。例如,你可能需要身份验证才能访问操作系统,修复身份验证模块……或者监控本来应该正常运行的数据库以获取指标数据,找出数据库出了什么问题。总之就是这样的死循环。
甚至客户通信系统有时也会损坏,因为你用了自己的系统将系统状态传递给客户。
大家都对现代公有云及其提供的无数 API 感到非常兴奋。弹性!编排!所有运维都可以自动化,这样人类就不会被吵醒了!
但是这种热情有时会让我们过度自动化系统,进而很难测试退化的用例。而且这些未经测试的退化用例可能会有很大的不利影响,相比之下,在健康的系统状态下,实现自动决策带来的那点效率或经济优势是不够看的。
但即使自动化确实是明智的(因为系统需要经常调整,和/或调整所涉及的经济成本较大),自动化有时也缺乏必要的“恐慌模式”,无法识别参数何时超出正常范围。在这些情况下,自动化应该停止自动化操作并通知运维人员,因为它即将开始做出一些非常不合逻辑的决定了。
如果一切都是无状态的,那会怎样呢?那些讨厌的数据库总是给我们找麻烦。甚至在前端层表现出来的问题也常常是上游数据库引发的堵塞,源头可以追溯到深层服务栈的瓶颈。
这个主题的素材非常丰富,我们把它分解成三个子课程:
生产系统喜欢平坦、均匀且差异小的负载。对数据库服务器来说,它们喜欢许多非常快速的查询,可能都是有索引支持的,这样最坏情况下成本也是可以控制的。
为确保这一点,请将你的任意批量查询放在专用的辅助服务器中,或者放在一些 OLAP 系统(如 BigQuery 或 Snowflake)中。或者转储到 CSV 和并行 grep 都可以。不管这些批量查询复杂程度如何,是不是符合你的数据集大小和流程,都请这样做。
而且,如果你对查询时间分布还不够了解,无法知道尾部是否有疯狂的表扫描,请立即添加相应的监控。
什么是中间魔法?我们来大致了解一下。
好选项:使用像 MySQL 这样的无聊事物并自己处理分片。这会很麻烦,因为你必须在应用层做很多额外工作,但当它崩溃时你可能会知道它是如何运作的。这在 10 年前可能是正确的想法,但现在看来也不错。
更好的选项:只需购买一个更大的服务器并使用一个未分片的 MySQL/PostgreSQL 服务器和一个或两个副本。这种办法一直都是好方案,尽可能选择它。
可能是 2021 年后最好的选项:花钱找云服务提供商为你运行数据库,包括所有备份和故障转移等业务。如果你真的喜欢,你甚至可以使用很帅气的数据库,例如 CloudSpanner、DynamoDB 之类。完全、不透明地依赖第三方在过去是不可想象的,但这可能是 2021 年最好的办法。这些大公司在这方面做得非常好,毕竟他们做得不好的话,因为你的公司就是依赖他们运营的,估计你们已经完蛋了。缺点是它会让你破费多多,因为这些服务的定价很高。
玩火选项:使用一些声称可以自动解决所有扩展和故障转移问题的东西,但你仍然需要做运维工作,而且它的生产环境历史比 MySQL 之类的东西少得多。当它出错时,很少有人知道如何操作,或充分了解其内部结构以诊断其编排流程的复杂故障模式。我们在这些停机事件中遇到的可能嫌疑人包括 MongoDB 和 Cassandra。
如果你不能证明你可以恢复某项内容,那么备份就没有任何意义。并且你还要恢复到正确的记录上,恢复需要的时间太久也不行。
让我们来看看有哪些情况:
Error: permission denied on directory /data
。你的公司完蛋了。因此,请一定要证明你的恢复是有效的——自动化并监控这一步骤,不要只是偶尔做一次验证——并确保它们会在可接受的时间内恢复完成。4 小时的宕机会是糟糕的一天,但 4 天的宕机后,你的公司就完蛋了。确保你的公司政策可以容忍这样的恢复时间,并让你的领导签字,这样当工程团队在灾难期间需要 7 小时才能恢复数据库时,他们也不会抓狂。
尽管我们尽了最大努力,错误仍然会发生。我们会引入错误、或错误配置的东西、或传播错误的防火墙规则,或其他什么事物。
但分阶段部署可以把问题锁定在确定的范围内,因此你可以在火势蔓延并烧毁整个站点之前先看到哪里在冒烟。
我们讨论过的许多团队都有一套周密的部署方法,以确保他们公司的员工是第一批尝试其服务更改的用户,然后只有一小部分客户会提前试用新的部署。
下面是一个具体的例子:
对于采用这些方法的公司来说,一些小问题往往不会被大多数用户发现,因为它被自用、金丝雀或其他阶段提前捕获了。
而在公司没有使用分阶段部署的情况下,事情显然不太顺利……编写事后分析的团队往往是第一个指出分阶段部署会有多大影响的团队。
最后,虽然我们都愿意相信,如果测试非常彻底,并且周到地安排了所有事情,我们将不会再遇到大规模宕机事故……可我们都知道它们仍然会迟早发生。
因此,正如从许多停机事件中了解到的那样,如果在停机之前就把策略和计划内置到我们的系统和剧本中,我们就更容易从这些事件中恢复了。
策略意味着经过深思熟虑并做出决定,例如:如果整个站点因超载而停机,我们首先要减少哪些流量来恢复正常?这些流量涉及什么类型或什么类别的客户?如果这些决定是提前做出的,并由领导签字,甚至可能得到律师的验证,工程团队就更容易把压力减到阈值以下。
计划是说:我们可以设置类似“恐慌模式”之类的东西,在这种模式下编排会停止、负载均衡器变得不那么聪明,并且非必要的工作会自动暂停。我们可以有一个运行时参数,调整它可以减少一点负载,这样我们就不必关闭和打开所有东西,惊动一大堆客户了。
在回顾了所有这些压力巨大的宕机事件后,我们得出了一个非常令人鼓舞的结论:包括我们在上面列举的许多实践在内,一些常见实践可以预防或显著减轻各种站点停机问题带来的严重影响。
原文链接:
https://downtimeproject.com/podcast/7-lessons-from-10-outages/
领取专属 10元无门槛券
私享最新 技术干货