分布式系统的麻烦

举报
JavaEdge 发表于 2022/07/30 23:45:28 2022/07/30
【摘要】 我们讨论了很多系统如何处理错误。如多副本故障切换,复制延迟和事务并发控制。理解系统出现的各种临界条件,才能更好处理它们。但现实更复杂,现在将复杂最大化,假设可能出错的东西都一定会出错 [^i]。[^i]: 除了一个例外:我们将假定故障是非拜占庭式的(请参阅 “拜占庭故障”)。分布式系统和单点软件区别很大,主要在于,有许多新颖和刺激的故障。本文来了解实践中出现的问题,理解哪些能依赖、哪些不能。...

我们讨论了很多系统如何处理错误。如多副本故障切换,复制延迟和事务并发控制。理解系统出现的各种临界条件,才能更好处理它们。

但现实更复杂,现在将复杂最大化,假设可能出错的东西都一定会出错 [^i]。

[^i]: 除了一个例外:我们将假定故障是非拜占庭式的(请参阅 “拜占庭故障”)。

分布式系统和单点软件区别很大,主要在于,有许多新颖和刺激的故障。本文来了解实践中出现的问题,理解哪些能依赖、哪些不能。

工程师核心任务是构建可靠系统,即使出错,也要完成预定工作,满足用户期望。 本文来看我们面临的挑战。

本文对分布式系统可能出现的故障进行全面、悲观总结。

1 故障与部分失效

单点开发,一般以一种可预测方式运行:要么工作,要么故障。有bug的软件可能最终会在某天暴露(而问题通常可重启来解决),但问题主要原因可能还是软件本身的bug。

单点软件一般不应有模棱两可现象:硬件正常工作时,相同操作总产生相同结果(即确定性)。而若硬件有问题(如内存损坏或接口松动),结果往往是系统故障,如内核崩溃,蓝屏,启动失败等。因此单点软件要么功能完好,要么完全失效,而不会介于两者之间。

这是计算机设计的一个有意选择:若内部错误,宁愿计算机完全崩溃,而非返回错误结果,因为错误结果往往更难处理。因此,计算机隐藏一切模糊不清的物理实现,呈现出一个理想的系统模型。CPU指令总以确定性方式操作,若写一些数据到内存或磁盘,则这些数据将保持不变且不会被随机破坏。

涉及多节点时,量变引起质的变化。在分布式系统中,理想化的系统模型不再适用,必须面对混乱的现实。各种都可能会出问题。

分布式系统中,尽管系统部分工作正常,但系统某些部分可能会以难预测方式故障,即部分失效。难点在于部分失效的不确定性:若涉及多个节点和网络,时而正常,有时会出现不可预知的失败。正如我们将要看到的,你甚至不知道是否成功了,因为消息通过网络传播的时间也是不确定的!

这种不确定性和部分失效的可能性,使得分布式系统难以工作。

1.1 云计算&&超算

构建大型计算系统的思路:

  • 规模的极端是高性能计算领域。数千个CPU的超级计算机用于计算密集型的科学计算任务,如天气预报或分子动力学
  • 另一个极端是云计算,定义不明确,但通常和多租户数据中心,连接 IP 网络(通常是以太网)的商用计算机,弹性 / 按需资源分配以及计量计费等相关
  • 传统企业数据中心位于这两个极端之间

不同集群构建方式的故障处理也不同。高性能计算,一般定期对任务状态进行快照,然后保存在持久存储,当某节点故障,解决方案是简单停止整个集群的任务;等故障的节点修复后,从最近的快照检查点继续执行。因此,超级计算机更像是一个单节点计算机而非分布式系统:让部分失败升级为整体失败,若系统任何部分故障,干脆让所有东西崩溃(就像单台机器上的内核崩溃)。

本文重点放在实现互联网的服务系统,这与超级计算机很不同:

  • 许多互联网应用都是在线的,需随时以低延迟服务用户。任务服务不可用(如停止集群来修复)都不能接受。而天气模拟这样的离线(批处理)工作则可停止并重启,影响较小
  • 超算由专用硬件构建,每个节点很可靠,节点通过共享内存和 远程直接内存访问(RDMA)来通信。而云计算中的节点由商用机器构建,出于大规模部署时经济因素的考虑,单节点的成本低廉主要而依靠较高的集群聚合性能,但也具有较高故障率
  • 大型数据中心网络通常基于IP、以太网,以 CLOS 拓扑排列,提供更高的对分(bisection)带宽。超级计算机通常使用专门的网络拓扑结构,例如多维网格和 Torus 网络,这为具有已知通信模式的 HPC 工作负载提供了更好的性能
  • 系统越大,其组件失效率越大。但在有成千上万个节点的系统,总有一些东西坏了。若处理策略只是简单停止-修复,一个大系统最终会费大量时间错误恢复,而非做有用工作
  • 若系统能容忍某些故障节点,并继续保持整体继续工作,则对运维很有用。如滚动升级:每次重启一个节点,而集群总体继续给用户提供不中断服务。云环境中,若某台VM运行不佳,可杀死它并启动一台新VM
  • 位置分散的部署中(保持数据更接近用户以降低访问延迟),通信很可能通过互联网,和本地网络相比,通信速度缓慢且不可靠。而超算通常假设它们的所有节点都紧密靠近

要使分布式系统可靠工作,必须接受部分故障可能性,并在软件中提供容错。即需要在不可靠组件上构建可靠系统(没有完美可靠性,所以需要理解我们能实际承诺的极限)。

分布式系统中,怀疑,悲观和偏执狂才能有所精进。

基于不可靠的组件构建可靠系统

直观感觉,系统可靠性应取决于其最不可靠的组件。但事实并非如此:从低可靠的基础构建更可靠的系统一直是计算机领域的惯用手段,如:

  • 纠错码数字数据在通信信道上准确传输,偶尔会出现一些错误,例如由于无线网络上的无线电干扰
  • IP层本身不可靠:可能丢包、延迟、重复或乱序数据包。 但 TCP在IP之上提供更可靠的传输层,确保丢失的数据包被重传,消除重复包,并且数据包被重新组装成它们的发送顺序

虽然系统整体可以比它的底层部分更可靠,但可靠性有限。如纠错码只能处理少量的某几位错误,但若信号被彻底干扰,则通过信道可得到多少数据,是有根本性限制。 而TCP虽能重传、重组,但肯定不能消除网络传输延迟。

尽管系统不完美,但仍有用,因为它处理了一些棘手的底层故障,使得其它错误更易理解和处理。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。