分布式系统8种认知偏见


分布式系统的谬误是由L Peter Deutsch和Sun Microsystems公司的其他人提出的一套论断,描述了刚开始接触分布式应用的程序员总是做出的错误假设。

微服务的大规模采用,迫使更多的工程师了解这一决定在其系统中的影响。

在讨论系统设计时,我经常看到这8个谬误被普遍忽视或淡化。

1、网络是可靠的
为了建立一个可靠的系统,你必须理解并接受这样一个事实:任何特定的通信都可能失败;因此,我们需要为系统提供一种方法来处理这种潜在的误传。因此,最终,这归结为重传,它可以有多种形式。

一个这样的模式是存储和转发模式。我们不是直接将数据发送到下游服务器,而是将其存储在本地或其他地方。这也允许在灾难性的情况下进行恢复,而简单的重试循环会缺乏这种保证。

有许多技术适合这种模式,如RabbitMQ、ActiveMQ和你喜欢的云计算供应商的各种专有解决方案。  

我们希望建立互联网上最大的系统设计社区!我们很希望你能加入我们。你可以在Twitter上找到我们。


2、延迟为零
我喜欢把延迟看作是完成任何请求的严格开销。信息可以很大,也可以很小,而延时是不变的。与带宽不同,延迟通常与光速和通信距离(或路径)有关。所以两个系统之间的距离在这里起着重要作用。

延迟是无所不在的。它发生在所有的通信中。

理想情况下,这种开销应该尽可能的小。延迟与从汽车上卸下杂货非常相似。  你从厨房到汽车所需的时间就是延时。

你是想在一次旅行中抓取尽可能多的东西,还是想单独带着物品,花几百次往返来卸下汽车?

内容交付网络和边缘计算本质上是试图使冰箱和干线之间的距离尽可能地接近。通过将数据复制到更接近需要的地方,我们可以大大减少延迟。


3、带宽是无限的
假设你继续在一个渠道上无限制地增加数据大小;可能是一个相当大的错误。这个问题只有在规模困难的情况下才会出现,而特定的通信渠道也会达到其极限。

我第一次遇到这个问题是在我不小心将我的主页所需的有效载荷增加了10倍的情况下。这个特定的API在每次页面加载时都要进行3MB的无缓存调用。这包括整个有效载荷在数据库中的往返。

我们的系统很快就遇到了几个带宽限制,这使网站很快就瘫痪了。

现在你可能在想,你只是告诉我在每次往返中尽可能多地采取一些措施来减少延迟的影响。这是真的,但它确实有其局限性。这在很大程度上取决于你的系统设计和各自的优先级,但意识到这种权衡是非常重要的。


4、网络是安全的
假设你可以信任你所在的网络或你为之建立系统的人,这可能是一个重要的错误。

如今,随着众包漏洞赏金计划的出现和每天都有重大漏洞的新闻,这一点变得更加明显。

在设计你的系统时采取安全第一的立场将在未来获得回报。即使花时间评估你当前系统的安全漏洞也是一个很好的开始,并将很快产生一个简短的改进清单。


5、拓扑结构不会改变
网络结构不会永远是一样的。例如,如果一个关键的基础设施发生故障,流量能否继续流向适当的目的地?我们有单点故障吗?

随着Docker和Kubernetes的出现,现在改变网络拓扑结构的便利性几乎使我们认为这是理所当然的,几乎是危险的。

像Zookeeper和Consul这样的工具确实有助于解决围绕服务发现的问题,并允许应用程序对我们系统的布局和构成的变化做出反应。

构建能够对这些拓扑结构的变化做出反应的系统可能很棘手,但最终会产生更具弹性的系统。


6、有一个管理员
这句话让我花了一些时间来理解,基本上是说你不能控制一切。

随着你的系统的增长,它们将依赖于你控制之外的其他系统。因此,花点时间想想所有的依赖关系;你有从你的代码到你运行它们的服务器的一切。

有一个明确的方法来管理你的系统和它们各自的配置是非常重要的。随着具有不同配置的系统数量的增加,管理和跟踪变得很困难。  基础设施即代码(IaC)可以帮助编纂你系统中的这些变化。

当问题出现时,有一个很好的诊断方法,监控和可观察性将是关键的工具,可以节省你的时间。

适当的解耦也可以帮助确保整个系统的弹性和正常运行时间。

7、传送成本为零
我们经常认为,我们用来在系统之间发送数据的资源是一种简单的商业成本。现在当事情很小的时候,这种开销和成本可以忽略不计。

尽管如此,随着系统的发展,这种成本可能是值得优化的,与gRPC或MessagePack等传输优化格式相比,JSON等消息格式可能有点沉重(双关语)。

意识到这种成本是非常重要的;然而,它确实有其权衡。尽早这样做可能会在短期内造成更多的麻烦,而不是它的价值。

8、网络是同质的
在我的日子里,我已经写了不少的垫片;把一种格式的数据转换成另一种。

我们喜欢一切都干净整洁,但现实世界却远非如此。可互操作性是至关重要的。

这种灵活性确保我们的系统在 "新的热门框架 "出现时,或者当你需要在它并不打算使用的环境中运行你的新系统时,能够继续发挥作用。(显然,互操作性有其局限性)

知道所有的系统都是不一样的,不把你的解决方案与某一方面耦合起来,可以为你节省时间,并在以后的工作中避免头疼。