All systems are distributed

This article has a certain depth of thinking, but some views may be biased. For example, the author believes that there is no root cause for faults in distributed systems (There is no root cause), and finding the root cause is mostly futile.

content

1. Embrace the fault

2. Distributed design, localized development

3. Data is the lingua franca of distributed systems

4. The role of humans in complex systems

Below is the translation.

Logistics Center

What people should be surprised about is not so many failures every day, but how few failures every day. You shouldn't be surprised that your system crashes occasionally, but that it can run without errors for a long time. — Richard Cook

Jean Bookout, 76, was driving her Toyota Camry on an unfamiliar road in Oklahoma in September 2007, with her friend Barbara Schwarz in the passenger seat. Suddenly, the car began to accelerate on its own. Bookout tried pressing the brakes and pulling the handbrake, but to no avail, the car continued to accelerate. Eventually the car hit an embankment, injuring Bookout and killing Schwarz. In subsequent legal proceedings, Toyota's lawyers pointed to the most common culprit in such accidents: human error. "People sometimes make mistakes while driving," declared one of the lawyers. Bookout is very old and not a familiar path to her, thus causing this tragedy.

However, a recent product reliability test for Toyota turned things around in a 180-degree turn: A stack overflow error caused by a software bug in the Camry was the culprit. This event is important for two reasons:

  • The most common culprit behind this type of accident - human error - turned out to be not the cause of the accident (this assumption itself is questionable)
  • This event shows how we can seamlessly move from a software bug to a glitch or (potentially larger) loss of company revenue to the realm of personal safety

It's probably also easy to talk about this in a small way: There seems to be a common bug (currently) found in the software on a particular car model.

但这件事的外延要有趣的多。考虑一下目前发展地如火如荼的自动驾驶汽车。自动驾驶消除了人为失误 这个背锅侠,那我们得到的结论将是:在很多方面,自动驾驶汽车要比传统汽车更加安全。但事实真是这样吗?考虑下面的情况:

  • 如果发生了完全在汽车自动驾驶系统控制之外的事将会怎样?
  • 如果训练汽车识别红绿灯的数据有错误怎么办?
  • 如果 Google 地图让它去做一些明显很愚蠢的事,并且这些事很危险怎么办?

我们已经到达了软件开发中的一个特殊点 —— 不管是在技术上还是在社会/组织上,到 了这个点我们不再能理解、看到、或控制系统的所有组件 —— 我们的软件正在变得越来越复 杂和分布式。软件行业本身已经变成一个分布式的、复杂的系统。

我们如何开发和管理那些庞大到无法理解、复杂到无法控制、出错方式也无法预测的系统?

拥抱故障

分布式系统曾经只是计算机科学博士和软件架构师的领地,受众非常小。但现在不同了。仅仅因为你在笔记本电脑上写程序、无需关心消息如何传递和锁问题,并不意味着你不 需要关心分布式系统:

  • 你写的程序发起了多少对外部服务的 API 调用?
  • 你的代码是跑在PC 上还是移动设备上 —— 你确切地知道所有可能的设备类型吗?
  • 当你的应用正在运行时,它可能遇到哪些网络方面的限制,关于这些你知道多少?
  • 当软件到达特定规模时,它会遇到哪些瓶颈,关于这些你又知道多少?

在经典分布式计算理论中,我们学到的一件事情是:分布式系统经常会发生故障,而且 大都是局部而非全局故障。这些故障不仅难于诊断和预测,而且很难复现 —— 可 能是某个特定的第三方数据流没数据了,可能是位于某个你从未听说过的地方的路由器挂掉 了。你永远在同短时故障(intermittent failure)作斗争,这注定是一场失败的战役 吗?

应对复杂分布式系统的方法并不是简单地增加测试,或者采用敏捷开发流程,也不是采用 DevOps 或者持续交付(continuous delivery)。任何单一的技术或方法都无法阻止类似 丰田汽车事故这样的事情再次发生。实际上,类似这样的事情肯定会再次发生。

解决这类问题我们需要拥抱这样一种观念:无法预知的故障种类太多了 —— 我们面对的是一 片巨大而未知的未知海洋;此外,还需要改变我们构建系统时 —— 以及运维现有系统时 —— 的思考方式。

分布式设计,本地化开发

好了,现在我们可以确定的一点是:每个编写或开发软件的人都需要像分布式系统工程师 一样去思考。但这句话到底意味着什么?在实际中,它意味着:丢弃那种单计算机(节点)的思考模式(single-computer mode of thinking)。

直到最近,我们才可以将计算机视为一个相对确定性的东西(a relatively deterministic thing)。当编写一个在某台机器上运行的代码时,我们能够确定性地假设很多东西,例如 ,内存查询的方式。但现在已经没有应用还运行在单台机器上了 —— 云就是这个时代的计 算机(the cloud is the computer now),它就像一个生命系统(living system),一 直在持续不断地变化,尤其是在越来越多的公司开始采用持续交付这种新范式的过程中。

因此,你必须开始:

  • 接受这样的假设:支撑你的软件运行的系统一定会发生故障
  • 对为什么会发生故障以及故障可能会以怎样的形式发生做出预案
  • 针对这些预案设计数据收集方案

这并不是像说一句“我们需要更多测试”那么简单。传统的测试哲学中,假定 所有测试用例都是能够描述出来的,但在分布式系统中这一点不再成立。(这并不是说 测试不重要了,而是说测试不再是万灵药。)

当处于一个分布式环境、并且大部分故障模 式都是无法提前预测也无法测试时,监控就成了唯一的理解应用行为的方式。

数据是分布式系统的通用语言

如果对刚才的比喻(复杂系统就像一个生命系统)进行延伸,那在 诊断出一个人中风后 才去寻找病因 与 在中风前就能及早发现问题 明显是两种方式。你当然可以翻阅病 例上的就诊记录,从中看出其实早有中风的苗头,但你更需要的是一个早期告警系统, 以及一种在问题刚发生时就能看到并尽可能快地介入处理的方式。

另外, 历史数据只能告诉你哪里出了问题,并且是局限在特定时间段内的问题。但在处理分布 式系统相关的问题时,需要关心的事情要比仅仅 ping 一下服务器通不通多多了。

与测量和监控相关的工具现在已经有很多,这里不会就具体工具展开讨论,而是要告诉你:在查看自己的应用和系统的监控数据的过程中,你会对“直方图通常比平均值更能说明问 题”有越来越深的理解,在这个过程中开发者不会再将监控视为纯粹是系统管理员的领 域。

复杂系统中人的角色

无论多么复杂的软件最终都是人写出来的。

任何对分布式系统和复杂度管理的讨论最终都必须承认 人在我们设计和运行的系统中 的角色。人是我们创造出来的复杂系统中不可分割的一部分,而且很大程度上我们要对他 们的多样性(variability )和适应性(resilience )负责(或对他们缺乏这两种特性负 责)。

作为复杂系统的设计者、建造者和运营者,我们受一种厌恶风险(risk-averse)文化 的影响,不管我们是否意识到这一点。在试图(在进程、产品或大型系统中)避免故障的过 程中,为了使自己能够有更多“把控”(control),我们倾向于粗细不分地列出需求( exhaustive requirements)和创建紧耦合(tight couplings),但这种方式经常 更容易导致故障,或者产生更脆弱的系统。

当系统发生故障时,我们的方式是责备(blame)。我们粗鲁地寻找所谓的故障“原因” —— 实际上,相比于寻找真正原因以避免将来再出现类似问题,这种所谓的寻找故障“原因”的 过程经常只是一个减轻负罪感和寻求内心平静的活动。这类活动通常会导致人们继续加强对 系统的“把控”,而结果是最终的系统更加脆弱。

这里的现实是:大部分大故障都是一连串小故障叠加的结果,最终触发了某个事件(most large failures are the result of a string of micro-failures leading up to the final event)。这些故障并没有根本原因(There is no root cause)。我们最好不 要再去试图寻找根本原因了,这样做只是在攀登文化期望(cultural expectations)和强 大且根深蒂固的心理本能(psychological instincts)的悬崖峭壁。

20 世纪 80 年代奏效的流程和方法论,到了 90 年代已略显落后,现在更是完全不适用了 。我们正在探索新的领地和模型,以构建、部署和维护软件 —— 以及开发软件的组织自身( organizations themselves)。

推荐

A Big Picture of Kubernetes

Kubernetes入门培训(内含PPT)


随手关注或者”在看“,诚挚感谢!

本文分享自微信公众号 - 云原生技术爱好者社区(programmer_java)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324140374&siteId=291194637