分布式系统的麻烦
我们讨论了很多系统如何处理错误。如多副本故障切换,复制延迟和事务并发控制。理解系统出现的各种临界条件,才能更好处理它们。
但现实更复杂,现在将复杂最大化,假设可能出错的东西都一定会出错 [^i]。
[^i]: 除了一个例外:我们将假定故障是非拜占庭式的(请参阅 “拜占庭故障”)。
分布式系统和单点软件区别很大,主要在于,有许多新颖和刺激的故障。本文来了解实践中出现的问题,理解哪些能依赖、哪些不能。
工程师核心任务是构建可靠系统,即使出错,也要完成预定工作,满足用户期望。 本文来看我们面临的挑战。
本文对分布式系统可能出现的故障进行全面、悲观总结。
1 故障与部分失效
单点开发,一般以一种可预测方式运行:要么工作,要么故障。有bug的软件可能最终会在某天暴露(而问题通常可重启来解决),但问题主要原因可能还是软件本身的bug。
单点软件一般不应有模棱两可现象:硬件正常工作时,相同操作总产生相同结果(即确定性)。而若硬件有问题(如内存损坏或接口松动),结果往往是系统故障,如内核崩溃,蓝屏,启动失败等。因此单点软件要么功能完好,要么完全失效,而不会介于两者之间。
这是计算机设计的一个有意选择:若内部错误,宁愿计算机完全崩溃,而非返回错误结果,因为错误结果往往更难处理。因此,计算机隐藏一切模糊不清的物理实现,呈现出一个理想的系统模型。CPU指令总以确定性方式操作,若写一些数据到内存或磁盘,则这些数据将保持不变且不会被随机破坏。
涉及多节点时,量变引起质的变化。在分布式系统中,理想化的系统模型不再适用,必须面对混乱的现实。各种都可能会出问题。
分布式系统中,尽管系统部分工作正常,但系统某些部分可能会以难预测方式故障,即部分失效。难点在于部分失效的不确定性:若涉及多个节点和网络,时而正常,有时会出现不可预知的失败。正如我们将要看到的,你甚至不知道是否成功了,因为消息通过网络传播的时间也是不确定的!
这种不确定性和部分失效的可能性,使得分布式系统难以工作。
1.1 云计算&&超算
构建大型计算系统的思路:
- 规模的极端是高性能计算领域。数千个CPU的超级计算机用于计算密集型的科学计算任务,如天气预报或分子动力学
- 另一个极端是云计算,定义不明确,但通常和多租户数据中心,连接 IP 网络(通常是以太网)的商用计算机,弹性 / 按需资源分配以及计量计费等相关
- 传统企业数据中心位于这两个极端之间
不同集群构建方式的故障处理也不同。高性能计算,一般定期对任务状态进行快照,然后保存在持久存储,当某节点故障,解决方案是简单停止整个集群的任务;等故障的节点修复后,从最近的快照检查点继续执行。因此,超级计算机更像是一个单节点计算机而非分布式系统:让部分失败升级为整体失败,若系统任何部分故障,干脆让所有东西崩溃(就像单台机器上的内核崩溃)。
本文重点放在实现互联网的服务系统,这与超级计算机很不同:
- 许多互联网应用都是在线的,需随时以低延迟服务用户。任务服务不可用(如停止集群来修复)都不能接受。而天气模拟这样的离线(批处理)工作则可停止并重启,影响较小
- 超算由专用硬件构建,每个节点很可靠,节点通过共享内存和 远程直接内存访问(RDMA)来通信。而云计算中的节点由商用机器构建,出于大规模部署时经济因素的考虑,单节点的成本低廉主要而依靠较高的集群聚合性能,但也具有较高故障率
- 大型数据中心网络通常基于IP、以太网,以 CLOS 拓扑排列,提供更高的对分(bisection)带宽。超级计算机通常使用专门的网络拓扑结构,例如多维网格和 Torus 网络,这为具有已知通信模式的 HPC 工作负载提供了更好的性能
- 系统越大,其组件失效率越大。但在有成千上万个节点的系统,总有一些东西坏了。若处理策略只是简单停止-修复,一个大系统最终会费大量时间错误恢复,而非做有用工作
- 若系统能容忍某些故障节点,并继续保持整体继续工作,则对运维很有用。如滚动升级:每次重启一个节点,而集群总体继续给用户提供不中断服务。云环境中,若某台VM运行不佳,可杀死它并启动一台新VM
- 位置分散的部署中(保持数据更接近用户以降低访问延迟),通信很可能通过互联网,和本地网络相比,通信速度缓慢且不可靠。而超算通常假设它们的所有节点都紧密靠近
要使分布式系统可靠工作,必须接受部分故障可能性,并在软件中提供容错。即需要在不可靠组件上构建可靠系统(没有完美可靠性,所以需要理解我们能实际承诺的极限)。
分布式系统中,怀疑,悲观和偏执狂才能有所精进。
基于不可靠的组件构建可靠系统
直观感觉,系统可靠性应取决于其最不可靠的组件。但事实并非如此:从低可靠的基础构建更可靠的系统一直是计算机领域的惯用手段,如:
- 纠错码数字数据在通信信道上准确传输,偶尔会出现一些错误,例如由于无线网络上的无线电干扰
- IP层本身不可靠:可能丢包、延迟、重复或乱序数据包。 但 TCP在IP之上提供更可靠的传输层,确保丢失的数据包被重传,消除重复包,并且数据包被重新组装成它们的发送顺序
虽然系统整体可以比它的底层部分更可靠,但可靠性有限。如纠错码只能处理少量的某几位错误,但若信号被彻底干扰,则通过信道可得到多少数据,是有根本性限制。 而TCP虽能重传、重组,但肯定不能消除网络传输延迟。
尽管系统不完美,但仍有用,因为它处理了一些棘手的底层故障,使得其它错误更易理解和处理。
- 点赞
- 收藏
- 关注作者
评论(0)