> For the complete documentation index, see [llms.txt](https://zlt-shadow.gitbook.io/sicp-in-python-cn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zlt-shadow.gitbook.io/sicp-in-python-cn/di-4-zhang-shu-ju-chu-li/4.6-fen-bu-shi-ji-suan.md).

# 4.6 分布式计算

大型数据处理应用程序经常协调多台计算机的工作。分布式计算应用程序是指多个相互连接但相互独立的计算机协同执行联合计算的应用程序。&#x20;

不同的计算机是独立的，因为它们不直接共享内存。相反，它们使用消息相互通信，信息通过网络从一台计算机传输到另一台计算机。

### 4.6.1 消息

计算机之间发送的消息是字节序列。 信息的目的各不相同；消息可以请求数据、发送数据或指示另一台计算机评估过程调用。在任何情况下，发送计算机必须以接收计算机能够解码和正确解释的方式对信息进行编码。 为此，计算机采用一种赋予字节序列意义的消息协议。&#x20;

消息协议是一组用于编码和解释消息的规则。 发送和接收计算机必须就消息的语义达成一致，才能成功通信。 许多消息协议规定消息符合特定的格式，在这种格式中，位于固定位置的某些位指示固定的条件。 另一些则使用特殊的字节或字节序列来分隔消息的某些部分，就像编程语言语法中的标点分隔子表达式一样。&#x20;

消息协议不是特定的程序或软件库。相反，这些规则可以应用于各种程序，甚至是用不同的编程语言编写的程序。 因此，具有巨大不同软件系统的计算机可以参与到相同的分布式系统中，只需遵循管理系统的消息协议。

**TCP / IP协议。**&#x5728;因特网上，消息使用[因特网协议(IP)](http://en.wikipedia.org/wiki/Internet_Protocol)从一台机器传输到另一台机器，该协议指定如何在不同的网络之间传输数据包，以允许全球因特网通信。 IP在设计时假设网络在任何点上都是不可靠的，并且在结构上是动态的。 此外，它不假定存在任何通信的中央跟踪或监控。 每个包包含一个包含目的IP地址和其他信息的头。 使用简单的路由规则，尽最大努力在整个网络中将所有数据包转发到目的地。&#x20;

这种设计对通信施加了限制。 使用现代IP实现(IPv4和IPv6)传输的数据包最大大小为65,535字节。 较大的数据值必须在多个数据包中分割。 IP不能保证数据包的接收顺序与发送顺序相同。 有些报文可能会丢失，有些报文可能会传输多次。

[传输控制协议](http://en.wikipedia.org/wiki/Transmission_Control_Protocol)是根据IP定义的一个抽象，它提供可靠的、有序的任意大字节流的传输。 协议通过正确排序IP传输的数据包、删除重复的数据包以及请求重新传输丢失的数据包来提供这种保证。 这种改进的可靠性是以延迟为代价的，延迟是将消息从一点发送到另一点所需的时间。&#x20;

TCP将数据流分解成TCP段，每段包括数据的一部分，前面是包含序列和状态信息的头，以支持可靠、有序的数据传输。 有些TCP段根本不包含数据，而是建立或终止两台计算机之间的连接。&#x20;

在两台计算机a和B之间建立连接需要三个步骤：

1. A向B的端口发送请求以建立TCP连接，并提供发送响应的端口号。&#x20;
2. B向a指定的端口发送响应，并等待应答。&#x20;
3. A发送一个确认响应，验证数据可以在两个方向上传输。

在这三步“握手”之后，TCP连接就建立起来了，A和B可以互相发送数据。终止TCP连接按照一系列步骤进行，在这些步骤中，客户机和服务器都请求并确认连接的结束。（四次挥手）

### 4.6.2 客户机/服务器体系结构

客户机/服务器体系结构是一种从中央源分发服务的方法。服务器提供服务，多个客户机与服务器通信以使用该服务。在这个体系结构中，客户机和服务器扮演不同的角色。服务器的角色是响应来自客户机的服务请求，而客户机的角色是发出请求并利用服务器的响应来执行某些任务。下面的图表说明了架构。

![](/files/-MXw7X0QoBJQE7Z4Bmyz)

该模式最具影响力的应用是现代的万维网。 当一个web浏览器显示一个web页面的内容时，几个运行在独立计算机上的程序使用客户机/服务器架构进行交互。 本节描述请求网页的过程，以说明客户机/服务器分布式系统的中心思想。&#x20;

**角色。** web用户计算机上的web浏览器应用程序在请求web页面时扮演客户端角色。 当从Internet上的域名(如www\.nytimes.com)请求内容时，它必须与至少两个不同的服务器通信。&#x20;

客户端首先从域名服务器(DNS)请求位于该名称的计算机的Internet协议(IP)地址。 DNS提供将域名映射到IP地址的服务，IP地址是因特网上机器的数字标识符。 Python可以使用socket模块直接发出这样的请求。

```
>>> from socket import gethostbyname
>>> gethostbyname('www.nytimes.com')
'170.149.172.130'
```

然后，客户机从位于该IP地址的web服务器请求web页面的内容。在本例中，响应是一个[HTML](http://en.wikipedia.org/wiki/HTML)文档，其中包含当天新闻的标题和文章摘要，以及指示web浏览器客户机应该如何在用户屏幕上展示内容的表达式。Python可以使用urllib.request模块进行检索此内容所需的两个请求。

```
>>> from urllib.request import urlopen
>>> response = urlopen('http://www.nytimes.com').read()
>>> response[:15]
b'<!DOCTYPE html>'
```

在接收到这个响应后，浏览器会对页面的图像、视频和其他辅助组件发出额外的请求。 之所以会发起这些请求，是因为原始HTML文档包含了附加内容的地址以及如何将这些内容嵌入到页面中的描述。&#x20;

**一个HTTP请求。** 超文本传输协议(HTTP)是一种使用TCP实现的协议，它管理着万维网(WWW)的通信。 它假定web浏览器和web服务器之间有一个客户机/服务器架构。 HTTP指定浏览器和服务器之间交换消息的格式。所有web浏览器都使用HTTP格式从web服务器请求页面，所有web服务器都使用HTTP格式发回它们的响应。&#x20;

HTTP请求有几种类型，最常见的是针对特定web页面的GET请求。 GET请求指定了一个位置。 例如，在web浏览器中输入地址<http://en.wikipedia.org/wiki/UC\\_Berkeley> 会向web服务器在en.wikipedia.org上的80端口发出HTTP GET请求，以获取位置/wiki/UC\_Berkeley上的内容。&#x20;

服务器返回一个HTTP响应：

```
HTTP/1.1 200 OK
Date: Mon, 23 May 2011 22:38:34 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
Last-Modified: Wed, 08 Jan 2011 23:11:55 GMT
Content-Type: text/html; charset=UTF-8

... web page content ...
```

在第一行中，文本200 OK表示在响应请求时没有错误。头文件的后续行提供了关于服务器、日期和发回的内容类型的信息。&#x20;

如果你输入了一个错误的网址，或者点击了一个损坏的链接，你可能会看到这样的错误信息：

```
404 Error File Not Found
```

这意味着服务器返回了一个HTTP头，它启动了：

```
HTTP/1.1 404 Not Found
```

数字200和404是HTTP响应代码。一组固定的响应代码是消息协议的一个常见特性。协议设计者试图预测将通过协议发送的公共消息，并分配固定的代码以减少传输大小并建立公共消息语义。在HTTP协议中，响应代码200表示成功，而404表示找不到资源的错误。HTTP 1.1标准中还存在各种其他响应代码。

**模块化。**&#x5BA2;户端和服务器的概念是强大的抽象。服务器提供服务(可能同时提供给多个客户机)，而客户机使用该服务。客户端不需要知道如何提供服务的细节，也不需要知道如何存储或计算它们接收到的数据，服务器也不需要知道它的响应如何被使用。

在web上，我们认为客户机和服务器位于不同的机器上，但即使是在一台机器上的系统也可以拥有客户机/服务器架构。例如，来自计算机输入设备的信号通常需要对运行在计算机上的程序可用。 这些程序是客户端，使用鼠标和键盘输入的数据。操作系统的设备驱动程序是服务器，接收物理信号并将其作为可用的输入。此外，中央处理单元(CPU)和专用图形处理单元(GPU)通常参与客户端/服务器架构，CPU作为客户端，GPU作为图像服务器。&#x20;

客户机/服务器系统的一个缺点是服务器是单点故障。 它是唯一具有分发服务能力的组件。 可以有任意数量的客户端，它们是可互换的，可以根据需要来来回回。&#x20;

客户机-服务器系统的另一个缺点是，如果客户机太多，计算资源就会变得稀缺。 客户端增加了对系统的需求，而不贡献任何计算资源。

### 4.6.3 点对点系统

客户机/服务器模型适合面向服务的情况。然而，对于其他计算目标来说，更平等的劳动分工是更好的选择。术语点对点被用来描述分布式系统，其中劳动被分配到系统的所有组件中。所有的计算机都发送和接收数据，它们都贡献了一些处理能力和内存。随着分布式系统规模的增加，其计算资源的容量也会增加。在点对点系统中，系统的所有组件都为分布式计算贡献了一些处理能力和内存。

所有参与者之间的分工是点到点系统的识别特征。 这意味着对等体需要能够可靠地彼此通信。 为了确保消息到达它们预期的目的地，点对点系统需要有一个有组织的网络结构。 这些系统中的组件相互协作，以维护有关其他组件位置的足够信息，以便将消息发送到预期的目的地。

在一些点对点系统中，维护网络健康的工作由一组专门的组件承担。这样的系统不是纯粹的点对点系统，因为它们有不同类型的组件，提供不同的功能。支持点对点网络的组件就像脚手架一样：它们帮助网络保持连接，它们维护不同计算机位置的信息，它们帮助新用户在它们的社区中占据自己的位置。&#x20;

点对点系统最常见的应用是数据传输和数据存储。 为了进行数据传输，系统中的每台计算机都通过网络发送数据。 如果目标计算机在一个特定计算机的附近，该计算机帮助发送数据。 对于数据存储来说，数据集可能太大而不能存储在任何一台计算机上，或者太有价值而不能仅存储在一台计算机上。 每台计算机存储数据的一小部分，并且在不同的计算机上可能有相同数据的多个副本。 当一台计算机出现故障时，它上的数据可以从其他副本中恢复，并在替换的计算机到达时放回原位。

语音和视频聊天服务Skype是使用点对点架构的数据传输应用程序的一个例子。 当两个人在不同的电脑上进行Skype对话时，他们的通信是通过点对点网络传输的。 这个网络是由运行Skype应用程序的其他计算机组成的。 每台计算机都知道它附近其他几台计算机的位置。 计算机通过将信息包传给相邻的计算机，再传给其他的计算机，以此类推，直到信息包到达预定的目的地。 Skype不是一个纯粹的点对点系统。 由超级节点组成的脚手架网络负责登录和注销用户，维护有关用户计算机位置的信息，并在用户进入和退出时修改网络结构。
