MIT6.824 Distributed System(1)

MIT6.824 Distributed System(1)

July 1, 2024

分布式系统

<p>以下是我在学习分布式系统的一些心得和具体的实验, 该学习是围绕 MIT6.824 的实验进行的笔记技术。</p>

什么是分布式系统

分布式系统是一个由多个独立计算机组成的系统,这些计算机通过网络(HTTP, RPC 等)相互通信和协调,以实现共同的目标。分布式系统的主要特点是其组件在物理上分布在不同的地点,但它们通过网络连接在一起,协同工作。

在摩尔定律的推动下,我们从单核发展到了多核。然而,在多核的情况下,我们不能无限制地增加核心数量。近年来,摩尔定律遇到了瓶颈,我们必须打破这一瓶颈,而分布式系统正是解决这一问题的关键。分布式系统的主要目标是将多台计算机连接在一起,共同执行一个任务,或者说是将一个任务分发给多台计算机,让它们分别执行一部分,从而实现任务的分流和合并,加速任务的处理。

我们需要增强计算能力,以满足当前的需求。当我们处理数百GB甚至数TB级的数据时,计算能力的提升尤为重要。我们不能仅仅依赖硬件的提升,因为硬件的发展触及了许多尚未突破的知识领域。因此,我们必须寻找新的途径来提高计算能力,分布式系统因此应运而生。

分布式系统的核心在于通过网络将多台计算机连接起来,形成一个协同工作的系统。这种系统可以有效地处理大规模数据和复杂计算任务,通过并行处理和任务分配,显著提高整体的计算效率。此外,分布式系统还具有高可用性和容错性,能够在部分节点失效的情况下继续运行,确保系统的稳定性和可靠性。

总之,分布式系统是应对摩尔定律瓶颈的有效解决方案,它通过协同多台计算机的工作,提高了计算能力,满足了大数据和复杂计算任务的需求。随着技术的不断进步,分布式系统将在未来的计算领域发挥越来越重要的作用。

驱动力(有利部分)

  1. 提高计算性能:通过使用大量的计算机,可以实现大量的并行运算,充分利用多CPU、多内存和多磁盘资源,从而显著提升计算性能。这对于处理大规模数据和复杂计算任务至关重要。
  2. 容错能力:分布式系统能够提供容错机制,通过在多台计算机上运行相同的任务,即使其中一台计算机发生故障,系统也可以无缝切换到另一台计算机继续运行,确保服务的连续性和可靠性。
  3. 空间分布的自然需求:某些问题在空间上是自然分布的,例如跨国银行转账。在这种情况下,不同地理位置的服务器需要协同工作,确保交易的顺利进行。分布式系统提供了一种有效的协调方法,满足这类需求。
  4. 安全性考虑:在处理不可信代码或需要与潜在风险代码交互时,分布式系统可以将代码分散在多台计算机上运行,通过特定的网络协议进行通信,从而限制潜在的错误和安全风险的影响范围,提高系统的整体安全性。

挑战(需改进部分)

分布式系统面临的挑战主要包括:

  1. 并发编程和复杂交互:由于系统中存在多个并发执行的部分,开发者需要处理并发编程带来的复杂性,包括同步和异步问题。这些复杂交互可能导致难以预测的行为和错误,使得分布式系统的开发和维护变得困难。
  2. 局部错误和网络故障:在分布式系统中,由于涉及多台计算机和网络,可能会出现局部错误或网络故障。与单台计算机不同,分布式系统可能部分组件正常工作,而另一部分组件停止运行,或者所有计算机都在运行但网络连接不稳定。这种局部错误和网络故障增加了系统的复杂性和维护难度。
  3. 性能预期与实际差距:设计分布式系统的初衷通常是为了获得更高的性能,例如通过使用一千台计算机或一千个磁盘臂来提升性能。然而,实际性能往往难以精确预测,因为涉及到众多因素,如硬件性能、网络延迟、任务分配等。因此,需要精心设计和优化才能使系统达到预期的性能水平。

抽象接口(展望)

分布式系统的实现和抽象对于开发者来说,必须围绕几个核心部分:首先是存储,其次是通信。一般来说,存储我们直接使用物理存储设备。然而,物理存储还有一些细分部分。至于通信,我们利用网络进行机器间的相互通信,因为有多台机器,网络如 HTTP 和 RPC 等技术能提供稳定可靠的连接,使得多台机器能够顺畅通信。

此外,对于分布式系统中的存储、计算和通信,我们必须设计一些非常简单的接口,使得用户或其他应用在使用这些分布式系统时能够简单易用。我们必须将所有系统的复杂性隐藏在抽象接口的背后。虽然对于分布式系统来说,完全隐藏其复杂性是一个难以实现的想法,但我们必须朝着这个方向努力。我们的抽象接口必须使得整个系统看起来像一个非分布式的系统,就像一个单独的简单系统。然而,我们又希望这个接口背后是一个具有极高性能和容错率的分布式系统,这对抽象接口的设计是一个挑战。

在实现这些抽象接口时,我们需要考虑如何简化用户的使用体验,同时确保系统的性能和可靠性。这需要我们在设计时充分考虑分布式系统的特性,如并发控制、数据一致性和故障恢复等。通过不断优化和改进,我们可以逐步接近这个理想化的抽象接口,为用户提供一个既简单又强大的分布式系统。

在考虑这些抽象时,首先出现的话题是实现。在构建分布式系统时,使用了许多工具,例如:

  • RPC(远程过程调用):RPC的目标是掩盖我们在不可靠网络上进行通信的事实,使得远程调用看起来就像本地调用一样简单。
  • 线程:线程是一种编程技术,使我们能够利用多核心计算机。在本课程中,线程提供了一种结构化的并发操作方式,从而简化了并发编程。

实际上,成功的分布式系统需要在抽象的设计与具体实现之间找到适当的折衷。虽然这一过程充满挑战,但同时也孕育着无限的创新潜力。在现实世界中,一个设计良好的分布式系统能够解决众多看似不可解的问题,它通过协调众多计算资源的合作,实现了数据存储和处理的规模化、高效化

实践部分

可扩展性(Scalability)

通常,构建分布式系统的目的是为了实现可扩展的加速,即通过增加计算资源来提高系统的性能或吞吐量。具体来说,如果使用一台计算机解决问题需要一定时间,那么增加一台计算机后,理想情况下应该能够在相同时间内解决两倍的问题,或者在一半时间内解决相同数量的问题。这种性能的线性增长就是我们所追求的可扩展性。

可扩展性是一个强大的特性。如果一个系统能够通过简单地增加计算机数量来提升性能,这将是一个巨大的成果,因为计算机可以通过购买来获得。相比之下,如果不增加计算机,就需要投入大量资源来优化现有系统,这通常是一个昂贵且耗时的过程。因此,我们希望能够通过从少量计算机扩展到大量计算机,来应对流量的大幅增长。

在构建大型网站时,可扩展性是一个必须时刻考虑的因素。为了获得与计算机数量匹配的性能,需要精心设计系统。例如,一个典型的网站可能包括一个HTTP服务器、用户和浏览器,以及一个基于Python或PHP的web服务器与数据库交互。当用户数量增加时,可以通过增加web服务器来分散用户请求,从而提高系统的处理能力。然而,这种可扩展性并不是无限的。在某个临界点,数据库可能会成为瓶颈,即使增加更多的web服务器也无法提升性能。

在这种情况下,可能需要对系统进行重构,例如将单个数据库拆分成多个数据库来提升性能。这种重构需要大量的工作,但在某些情况下是必要的。在本课程中,我们将看到许多关于分布式存储系统的例子,这些系统通常用于支持大型网站,因为单个数据库或存储服务器无法支撑如此大规模的网站。

总结来说,可扩展性是我们希望通过增加机器来实现系统性能提升的目标,但在现实中,这需要通过合理的架构设计来实现。需要认识到,虽然增加机器可以提升性能,但在某些情况下,系统的某个组件可能会成为瓶颈,需要通过重构或其他方法来解决。

可用性(Availability)

容错是指系统在出现故障时仍能继续运行的能力。如果你只使用一台计算机构建系统,那么系统通常是可靠的,因为一台计算机可以稳定运行多年。然而,如果你使用数千台计算机构建系统,那么即使每台计算机都能稳定运行一年,对于1000台计算机来说,平均每天也会有3台计算机出现故障。

在大规模分布式系统中,一些罕见的问题会被放大。例如,在1000台计算机的集群中,总是会有机器故障、运行错误、运行缓慢或执行错误任务的情况。网络问题也很常见,如网线松动或交换机故障。因此,大规模系统会将一些几乎不可能且不需要考虑的问题,变成持续不断的问题。

由于错误总会发生,设计时必须考虑系统能够屏蔽错误或在出错时继续运行。同时,为了为第三方应用开发人员提供方便的抽象接口,我们需要构建一种基础架构,能够尽可能多地对应用开发人员屏蔽和掩盖错误,使他们不需要处理各种可能发生的错误。

可用性是容错的一个重要概念,它表示在特定类型的错误下,系统仍然能够正常运行,提供完整的服务。例如,通过构建多副本系统,当一个副本故障时,另一个副本可以继续运行。然而,如果所有副本都故障,系统就不再可用。因此,可用系统通常是指在特定故障范围内,系统仍然能够提供服务。

除了可用性,另一个容错特性是自我可恢复性。这意味着如果出现问题,服务会停止工作,不再响应请求,但在修复后系统可以恢复正常运行。这是一个比可用性更弱的需求,因为在故障修复期间,系统将完全停止工作。然而,修复后系统可以完全正确地重新运行,因此可恢复性是一个重要的需求。

为了实现这些特性,有许多工具。其中最重要的是非易失存储和复制。非易失存储(如硬盘、闪存、SSD)可以在电源故障时保存系统状态,以便在电源恢复后继续运行。然而,更新非易失存储是代价很高的操作,因此出现了许多非易失存储的管理工具。为了避免频繁写入非易失存储,需要进行许多思考以获取好的性能。

复制是另一个重要的容错工具,但管理复制的多副本系统会有些棘手。在任何多副本系统中,都会有一个关键问题,即副本可能会意外偏离同步状态,不再互为副本。lab2和lab3都是通过管理多副本来实现容错的系统,你将会看到这里有多复杂。

一致性(Consistency)

一致性是分布式系统中的一个核心概念,它定义了系统中操作的行为和结果。在构建分布式存储系统时,理解一致性尤为重要,因为它直接影响到系统的性能、可靠性和用户体验。

强一致性与弱一致性

为了解决不一致性这个问题,我们需要定义一致性的规则。一致性有两种主要类型:强一致性和弱一致性。

  • 强一致性:保证get请求总是返回最近一次put请求写入的值。这意味着系统需要确保所有副本在任何时候都保持同步。实现强一致性通常需要大量的通信,因为每次putget操作都需要与所有副本进行通信,以确保它们都更新或检查了最新的数据。
  • 弱一致性:不保证get请求总是返回最近一次put请求写入的值。这意味着系统允许读取到旧数据。虽然弱一致性可能导致读取到旧数据,但它可以减少通信需求,从而提高性能。
权衡

强一致性虽然提供了最高的数据准确性,但实现它的代价很高。在分布式系统中,为了容错和性能,副本通常分布在不同的地理位置。这导致跨副本的通信延迟增加,从而影响系统的响应速度。因此,许多系统选择弱一致性,以换取更高的性能和更好的容错性。

个人学习目标

  1. 基本理解分布式系统的各项功能和具体的实现。
  2. 亲自动手去实现一个小型的分布式系统,做好每一件分布式系统的一些细节。
  3. 归纳总结一下,在本次分布式系统学习中遇到了一些问题,或者是一些学习经验。

外链

Lecture 01 - Introduction

最后更新于