Part II

Distributed Systems

如果没有分布式系统,我们可能无法拨打电话、进行银行转账,或是进行远距离的信息交换,事实上我们每天都在使用分布式的系统,有些时候,尽管我们可能不承认:基于客户端跟服务端的应用就是一个分布式系统。

对于许多现代的软件系统来说,Vertical scaling 垂直扩展 (为相同的软件提供具有更大内存、更快 CPU 或更快磁盘) 是不可行的。更高配置的机器会非常昂贵,并且很难直接进行替换,可能还需要一些特殊的维护。一个可行的替代方式是 Scale Horizontally 水平扩展:将程序运行在多台机器上并通过网络将他们连接起来,让他们如运行在一台单独的机器一般。

分布式系统可能在机器的数量上会比较不一样,他让上百台的机器一起参与,这些机器可能是手持设备、传感器或是一些高性能的计算机。

只把数据库运行在单个节点上的时代已经过去了,现代化的数据库系统可能会将多个节点集合成一个集群来提供更大的存储容量、提供更高的性能以及更强的可靠性。

尽管分布式领域的理论的突破都不是什么新的事物,但大部分的相关的分布式应用都是近期的才出现的。到了今天,我们看到了更多的人对这个主题产生了兴趣,以及相关的更多的研究跟进展。

Basic Definitions

在分布式系统中我们有多种不同的参与者 (通常称为 processes 处理者、nodes 节点或 replicas 副本)。每个参与者都会有其自身的状态,参与者之间使用通信的链接 (Communication Links) 来进行消息交换。

处理者通过 clock 来获取时间,这个 clock 可以是 logical 逻辑的或是 physical 物理的。Logical clocks 逻辑时钟一般通过某种严格递增的计数器来实现,Physical clock 物理时钟也会称为 wall clocks 墙上时钟,他会与现实世界的时间进行绑定,并能够通过本地的处理来获取,比如可以通过操作系统的时钟信息获取。

在说起分布式系统时,几乎不可能不去提到因为其内部各个部分各自分离而形成的必然的困难。通过通信链接进行的 Remote Processes 远程过程调用可能会出现的缓慢或不可用的状态,这让远程过程调用的状态处理变得格外的复杂。

大部分关于分布式系统领域的研究都会围绕与没有任何一样东西是完全可靠的:通信的频道可能会延迟、错序或者没法正常的送达消息;处理器可能会停止、变慢、崩溃、失去控制或者是突然失去响应。

分布式编程跟并行编程领域中有许多共同的主题,因为 CPU 就是一个具有链路、处理器跟通信协议的微型分布式系统。你可以在 Consistency Models 中看到许多的并行编程相关的信息,只是,其中大部分的基础元素没办法直接复用,因为远程模块的通信成本以及链路跟处理器的不可靠性。

为了克服分布式环境中的困难,我们需要使用一种特殊类型的算法,Distributed Algorithms 分布式算法,他具有本地很远程状态的概念,以及需要在不可靠的网络及可能发生的组件失败中保持工作。我们会使用 state 状态跟 steps 步骤 (或 phases) 以及他们的 transitions 转换来描述算法。每个处理器都会在本地执行算法的步骤,并且使用本地执行跟处理器交互的组合来构成分布式的算法。

分布式的算法描述了本地的行为以及多个独立节点间的交互。节点通过发送消息来进行通信。算法定义了参与者的角色、需要交换的消息、状态、转换、执行的步骤、传输介质的属性、时序的假设、失效的模型以及其他用来描述处理器跟他们之间交互的特性。

分布式的算法提供了许多不同的目标,包括:

  • Coordination

    一个用来监督多个工作节点的动作跟行为的处理器

  • Cooperation

    多个参与者之间会依赖与其他参与者去完成他们的任务

  • Dissemination

    将信息快速、可靠的传播给其他感兴趣的合作伙伴的处理器

  • Consensus

    用来实现多个处理器之间的一致性

在本书中,我们会在对应的上下文中以更使用的方式讨论这些算法的用法,而不是倾向于比较学术性的方式。首先,我们会覆盖所有必须的抽象信息,包括处理器之间的连接,以及构建更复杂的通信模式的进展。我们会首先从 UDP 开始,他不保证发送方发送的数据能够成功的发送到目的地;在最后,为了达成共识,多个处理器之间必须要接受一个特定的结果。