身体突然发胖是有病吗:分布式计算基础

来源:百度文库 编辑:九乡新闻网 时间:2024/05/03 21:40:15

分布式计算基础


在介绍远程文件系统时,特别介绍了文件管理的工作划分不同的部分,分布到客户机和文件服务器两个不同机器上,全部任务仍在操作系统内完成。在远程文件的情形中,分布实际上增长了而不是减少了进程的执行时间。远程文件系统的优势只是实现了以文件作为单位的网络资源共享。和远程文件的情形不同,网络操作系统还可以支持用户划分任务,分布、并行执行划分后的各个子任务,以达到充分利用网络资源、减少整个任务执行总时间的目的。

6.4.1 计算分解

网络中的计算机总是和传统的顺序进程模型一起来完成应用处理,如同前面章节中所表现的一样,操作系统允许自治进程能够在一个单CPU系统中并行执行。网络为计算提供了一种机会,它可以使计算划分成多个逻辑单元,然后让它们在网络的不同计算机上同时执行。从应用开发人员的角度来看,根本的问题是将串行的计算划分成N个计算单元,其中N个单元都能同时执行,就会有最小的开销。在面向对象技术发达的今天,计算单元静态表现为组件,组件由类构成。组件运行时,表现为一个个建立的对象、线程(或进程),通过它们向网络提供服务或请求网络服务。

应用任务的划分是开发人员的事情,因为任务的划分必须知道在整个任务中各个子任务之间的逻辑关系。并行的子任务如何在支持的网络上分布一般由开发人员来决定。他们把子任务组件静态部署到运行它们的主机上。图6.17 所示的应用分布是一种典型情况,它分为三层次:数据管理层、业务逻辑层和表达层。支持这种分布式应用往往是网络操作系统和Web系统共同完成的。

 

 

                                                           图6.17    数据管理层、业务逻辑层和表达层

6.4.2支持分布式计算

网络操作系统为分布式计算提供服务和环境:

1.客户/服务器模型

单机上操作系统提供了父进程创建子进程的操作。在网络操作系统中,没有显式的系统调用来动态地在另一个机器中创建、调度、撤消一个进程。客户/服务器模型为分布式计算的基本模式。任何特定的应用程序都可以通过把计算划分成一组被动的服务器计算和另一组主动的客户计算来使用该模式。客户根据应用程序的输入数据执行计算,然后当需要时激活服务器。客户/服务器模型也是一种显式的网络进程调度模型。服务器在网络上的一个确定的位置被启动,客户在网络中的任意位置独立启动对服务器的请求。在这种情形中,客户或服务器的计算单元在它所在的计算机中作为一个普通进程来对待。默认情况下,单计算机的多道程序设计调度策略用于为分布计算部分提供服务。

在一些主流的中间件系统中,如J2EE、.Net,它们使用对象或线程来激活服务。在网络中任一机器上注册的用户可以启动一个独立的应用程序,控制通常随着客户/服务器流进行,即,一个服务器正在网络上运行,客户通过本地服务代理(client stub)在服务器启动相应的服务代理(server skeleton),激活引起计算单元实例化的活动,实现客户与服务器交互,实现与应用相关的分布式计算。

当代网络操作系统由于它对编程模式有如此之大的影响,所以操作系统和编程语言都在进行分布式计算方面的研究。

 

2.进程通信与同步

在单机操作系统中进程通信、同步机制依赖于共享存贮器。在网络进程之间没有共享的存贮器,操作系统通常提供一个基于消息或事务实现网络进程通信与同步。

(1)消息

消息传递机制是网络环境中分布式计算的基础。在高性能应用领域中,经常提供应用程序员直接使用的网络消息传递机制接口,甚至操作系统在实现分布式环境中其他方面的应用时也使用该接口。在单机进程管理讨论了基本的进程通信操作(send()和receive()),这里讨论如何在网络协议上实现网络进程通信操作。

消息服务有两个目的:

1)它提供一个进程与另一个进程共享信息的显式机制。

2)它可以被用于同步接收者与发送者之间的操作。

接收者进程必须有一个信箱来缓冲消息。信箱的消息已经被发送出来,但逻辑上还没有被接收者所接收。发送操作可以是同步或者异步进行的。在同步操作中,发送者要等待,直到发送的消息被安全地传送到接收者的信箱中。在异步操作中,发送者传送消息后继续运行,而无需查看是否发送的消息已经被加放到接收者的信箱中。接收操作可以是阻塞的或者是非阻塞的。在阻塞情况下,当一个接收者读取信箱中的一个消息时,如果没有消息它会被阻止,继续直到消息出现。在非阻塞接收操作时,接收者未发现消息也会继续运行。

在网络系统中,为了把信息放入到远程机器另一个进程的地址空间中,信息内容通常必须被拷贝几次,图6.18概括了通过网络进程发送操作的过程。首先,发送者在一个内部缓冲中生成要被传送的信息,然后信息被拷贝到操作系统的地址空间中,因此它可以被拷贝到另一个进程的信箱中。假设使用网络层协议,信息从一般的消息中被拷贝到报文中,而在报文又必须被拷贝到数据链路层的帧中,通常是在一个控制器的硬件缓冲中进行,然后被拷贝到物理网络中进行传输。在接收机器中,必须进行一组类似的拷贝过程。注意到它没有使用传输层协议,并且它忽略了信箱的管理,而其中可能还请求额外的拷贝操作。拷贝操作通常是基于网络的消息传递机制的性能的限制因素。操作系统设计者所面对的挑战就是要最小化这种操作的数目。当代操作系统努力实现消除不必要拷贝操作的消息传递机制,这表明确操作系统必须首先提供一个应用级的消息传递接口,它可以直接被应用程序员参及系统软件所使用。操作系统就可以根据它的设计策略和通信中所采用的网络协议类型来优化接口的实现。

 

在网络分布计算中,一般使用消息来建立计算的次序而获得同步。消息在每个进程中都与同步相关联的,每个消息都带有发送计算机本地时间的时间戳,然后结合该时间戳来确定与消息发生相关联的一个全局次序。

(2)事务

事务的思想把一序列操作组织作为一个整体来被执行,如同执行单个命令一样,如果该序列操作都被完成或者根本就没有被执行(直到以后的某个时间被执行),那么事务是正确的。事务在很多情形中可以用于获得与同步一样的效果。分布式各部分之间的交互是非常复杂的,这导致任一部分之间都可能交换相关的消息,或者相关消息流中的任一消息都可能会被从一个部分发送到另一部分中。这种相关的消息流称之为一个事务。一个事务是相关的命令序列,要么所有命令都被执行了,要么一个也没有执行。一个事务引起了一组特殊的微观活动,并且在两个部分之间进行交互以获得某种微观层的效果。作为一个软件系统例子,假设一个服务器的数据文件包含一组记录,每个记录有N个数据项组成。它们可以被一组用户进程中的任一个进程更新。如果有两个或多个客户都企图同时更新同一条记录中的多个数据项,那么问题就出现了。假设进程Pi改变记录中的数据项3、6、2以及8的同时,进程Pj试图改变记录中的数据项5、8、4以及6 (见图6.18)。那么将会有两个客户命令序列。如图6.19所示,首先Pi发送一个消息到服务器要求更新记录k中的数据项3,然后发送一个消息要求更新记录k中的数据项6,依次类推。

 

由于Pi可能更新了数据项3和6之后让Pj更新数据项5、8、4以及6,然后又让Pi更新数据项2和8,因此结果是服务器中记录k数据项8的值是Pi更新的,但数据项6的值是Pj更新的。在一些应用程序中,这也许是可以接受的,但在其他一些应用中却是灾难性的。例如,如果数据项6存一个人的名字而数据项8存其地址。这个例子意味着Pi修改记录k的事务必须完成,然后由进程Pj完成修改记录k的的事务;或者Pj先完成修改记录k的事务,然后由进程Pi完成修改记录k的的事务。

程序员通过标记语句序列的开始与结束来定义一个事务。服务器会检测事务开始的标记,并随后将把所有来自客户端的命令作为事务的一部分来对待,直到收到一个事务结束的标记。如果服务器代表一个特定客户开始处理一个事务,那么服务器就有责任要么执行完所有的命令直到事务结束,要么保留服务器的状态好像一个命令也没有被执行一样。当服务器遇到事务结束标记时,它就提交命令序列的结果,从而改变服务器的信息状态,如果服务器由于与其他事务的冲突而中止了正在执行的事务,那么它就可能取消(abort)该事务。如果中断事务,服务器将恢复所有的信息,包括从事务开始起执行的命令所改变的状态,到事务开始之前它们所处的状态。客户也可以取消一次事务,然而,事务被取消,通常指的是由于命令冲突由服务器所做的取消操作。

在很多情形中,操作系统使用事务来协同进程的操作。例如远程文件系统为大多数页级、块级以及文件级的处理而使用事务,因为信息的变化要求在任意时刻对客户端与服务器状态中的多个域更新。

事务实现要求必须在事务开始的时候,有效地对相关资源状态做一快照,假定快照信息可以用于恢复检测点的资源状态,那么事务中的命令就在资源的拷贝或者初者初始资源上被执行。如果在一个事务进行中另一个事务又开始了,那么状态必须认真地保存,如果第一个事务被提交,就保留操作过程的结果。如果事务被取消,资源状态可以基于检测点的信息进行恢复。如果事务被提交,改变后的拷贝就变成了主版本,检测点的信息就可以释放了。

事务操作情形下死锁可能会发生,一个服务器在执行所有事务过程中可以涉及到死锁,所以只要事务出现不执行的情况,服务器就可以执行进行死锁检测。允许服务器根据它的检测条件取消任一事务,所以它可以从死锁中恢复。

(3)并发控制

并发控制是一种技术,通过它系统可使一组进程在一个共享资源集上交叉执行一组事务。它所产生的效果如同单个进程在事务过程中独享所有的相关资源一样,因此,尽管事务内部的操作可能是并行进行的,但并发控制要保证一组事务间逻辑上的串行化。

在服务器中资源锁是一种实现并发控制的最简单机制。当事务改变资源的一部分时,服务器就在事务持续期间锁定该资源。在随后的进程试图改变被锁的资源部分时,因为资源被锁而不能实现,一直要等到第一个事务结束。

两阶段锁协议(two-phased locking protocol)保证一组事务将产生正确的串行化结果,且不会发生死锁。在第一个阶段期间,事务请求完成任务所需要的所有锁,并且期间不释放任何一个锁。在第二个阶段期间,它释放锁并且不再请求,一种极端的情形是,当事务被初始化时发出所有的锁请求,并且当事务结束时发出所有的锁释放请求。

锁的使用出现了下列和死锁相关的问题:

1)如果资源是一个文件,那么锁是应该加到一个磁盘块、一个逻辑文件页,还是整个文件涉及到管理的锁数目与支持事务间并发访问量。

2)如果事务恰好锁住了系统资源某些部分的同时而又请求其他部分,死锁就可能会发生。

在采用两阶段锁方法的情况下,会强制每个事务在它初始化时,请求所有它需要的锁。并发控制机制必须显式地避免死锁,否则,它将不得不强制实行每个事务请求锁的次序、死锁检测或者剥夺策略。

并发控制是围绕逻辑上集中的锁管理器来考虑的,如果资源被分布在网络上,锁管理器必须能够从每个构成结点中获得状态。对多道程序设计环境较慢的网络通信速度,基于加锁的分布并发控制倾向于使用锁来控制相对大的资源单元。在文件高速缓存的讨论中,描述了版本如何被用于处理并发文件访问。类似的方法可以用于并发控制中,它通过在每个事务上设置一个时间戳,然后基于时间戳维护版本的拷贝。版本的后期处理确定访问冲突的情形,并且确定事务发生的次序。虽然这种方法不能解决所有的冲突现象,但它确实可能支持很多的情况。

另一个困难如同一般的同步中所出现的一样,即如果事务起源于不同的机器,它们的时间戳必须从一个全局时钟中得到而不是一个局部时钟。

(4)死锁管理。死锁检测算法依赖于系统资源的分配状态。在网络中,资源的集合包括每个机器中的所有资源,而且在任意时刻检测所有机器的状态已经被证明是非常困难的,因而在网络环境中分布式死锁检测是一个难以解决的问题。

6.4.3客户/服务器模型的实现

1. 远程对象方法调用概述

分布式计算中,组件是静态分布的单位,组件由类构成。组件运行时构造的对象与其他分布的组件构造的远程对象之间交互、协作,实现它们提供服务。下面以远程对象方法调用为例,阐述客户/服务器模型的实现原理,远程对象方法调用也是支持分布式计算的基础。

面向对象的程序设计中讨论的对象都位于同一台机器上,即位于同一地址空间中。一个对象调用另一个对象提供的方法,通过共享的堆栈传递参数和调用结果。远程对象方法调用RMI(Remote Method Invocation)是把本地对象方法调用的概念加以扩充后,以适应对象分布环境下的交互、协作。RMI的形式和行为与本地对象方法调用的形式和行为极其相似,主要的差别在于被调用的对象代码实际运行在与调用者位于不同的主机结点上。图6.20表示主机A的程序远程调用主机Y的类RemoteServer对象remotes的方法remotePi()。习惯上,这里请求远程调用者叫客户(client),接收远程调用并完成要求方法调用者叫服务器(server)。

 

远程对象方法调用者(客户)首先发送一个远程调用请求,请求消息包括:调用的对象、方法、参数等,随后进入等待读远程调用结果;服务者接收客户发送的调用请求消息,然后利用客户提供的参数,调用要求的对象方法,并返回结果到调用的客户。从调用者的角度看,该框架所产生的行为好像是从一个对象到另一个类对象间的方法调用一样。

 

(2)客户代理和服务器代理

上述客户程序中调用远程对象remotes的方法remotePi(),由于对象remotes及其方法remotePi()不驻留在本地机器上,客户包含远程调用的程序(类),编译找不到引用的类,语法上就通不过,更不用说运行了。为了实现远程调用语义,在客户方引入一个远程调用方法代理(clientStub),它是一特定功能的程序(类),它具有远程类同样的类首部,同样的远程类方法首部。它的每个方法体实现把远程调用过程名、参数等发送到服务器,这样语法上满足客户包含远程调用的程序编译的要求。服务器一方也引入服务器代理(serverStub),它也是一特定功能的程序(类),它负责接收客户代理发来的远程调用请求,装配方法参数,调用相应的对象方法,把调用结果返回给客户代理。客户代理接收服务器代理的调用结果,并返回给客户调用程序。客户代理存放在客户方,服务器代理存放在服务器方。客户程序与客户代理在客户方成功编译、连接;服务器代理与远程服务类在服务器方成功编译、连接。当程序运行时,客户程序调用远程方法remotes.remotePi(),实际调用的是其客户代理的remotePi(),客户代理和服务器代理协同承担了远程调用的重要功能(见图6.21)。

 

                                   图6.21 客户代理、服务器代理和RMI实时运行系统

2.远程方法调用的实现

在RMI实现中有几个需要关心的问题:

1.RMI的结构

RMI实现可以采用图6.21中的通用形式,客户机执行客户程序(Client),其中包含有客户端应用程序代码、客户代理以及传输机制。服务器通过传输机制实现Server进程(服务器server stub)主程序以及远程过程的服务器实现。客户代理把本地过程调用翻译成RPC协议中客户端的活动,并且服务器代理实现RPC协议的服务器端部分。如图所示,Client进程中的RMI本地调用客户代理代码。客户代理通过名字服务器定位执行远程过程的服务器地址。Server进程必须事先已经注册了远程过程所用的全局名字,在示例中为remote()。查询只需要在第一次调用时进行,以后客户与服务器就将建立起连接,在随后调用中使用已存在的连接。接下来,客户代理将参数打包在一个消息中并传送到Server进程中的服务器代理。由于该服务器可能服务几个不同的远程过程,所以它从到来的消息选择一个远程过程。服务器代理完成调用并将结果参数打包返回给Client进程,同时Client进程将一直被阻塞等待调用的结束。当Client进程得到返回的消息时,它解包返回参数并传递到主程序中。

2.按照本地调用方式扩展远程调用

RMI机制可能强制程序员在编译时,链接编辑时或者运行时来区分是RMI还是本地过程调用。如果要在编译时进行这种区分,那么程序员需要与本地调用所不同的一个RMI使用接口,例如,一个远程过程调用可能采用的形式为:

callRemote (remoteF, a1, a2, …, aN, …);

其中callRemote是一个被链接到调用程序地址空间的本地过程,参数规定了远程过程的名字remoteF,同样规定了过程调用的参数。

程序员选择在链接时区分本地和远程方法,那么系统对于本地和远程调用采用相同的形式。编译器将不区分它们并将自动地为远程方法调用客户代理,链接编辑器将被要求解决所有的外部访问。为了解决外部访问,链接编辑器将需要类似于链接信息库中的信息来说明进程是本地的还是远程的。链接编辑器所需要的最少信息是那些指向远程过程的符号标识。

远程方法运行时刻说明是最一般的方法,这种方法请求与动态消息绑定相同的一种对动态绑定的支持。编译器或者链接编辑器将不能解决外部访问,因而外部访问假定在运行时刻被绑定。这种延迟绑定要求静态绑定机制在编译的代码中保留足够的信息,使运行系统能够解决外部访问。

3.定位远程过程

调用者必须能够定位远程对象服务位置(机器、端口、对象)。一般来说,支持RMI的服务器部署的机器、使用的端口是可以约定的。RMI的服务器还必须的支持命名服务。远程对象在服务器一端通过命名服务注册,同时,网络客户访问该RMI的服务器的命名服务,可以按相应远程对象名找到其引用对象。

远程对象网络位置的动态绑定是最有用并且应用最广泛的方法。它如图6.22所示,客户代理是中间媒介,并且是被静态地链接到调用程序。当第一次执行RMI时,客户代理要求命名机制确定远程对象位于什么地方,在随后的调用中,它已经知道了服务器的位置。

4.代理(stub)的生成

客户/服务器模型基于公共的服务接口(Interface),服务器实现这个接口,客户调用这个约定的服务接口。远程接口不同,客户代理和服务器代理也不同。分析表明:每个远程对象方法的客户代理和服务器代理只与远程方法接口有关。因此,利用RMI编译器,读入远程对象的接口文件,就可以自动生成远程接口对应的客户代理和服务器代理。

 

5.网络支持

传输机制实现网络消息传递,虽然要求可靠性,但实际上往往使用专门用于RMI协议的数据报来实现。RMI协议并不要求具有像TCP所提供的虚电路一样的全部特征,当发送者和接收者作为已知行为的客户代理和服务器代理时,一个专用的协议是相对容易构造的。

在服务器端,每个远程过程的模块必须准备接收远程调用。这要求服务器包含一个调用进程代理(服务器代理),接收来自客户代理的调用请求,并进行本地调用。在通常的情形中,服务器通过命名服务注册每个过程,从而使客户代理能够在调用时定位过程。远程对象注册包括将对象名增加到命名服务器中,并且将内部标识号映射到方法名。

在调用时,客户代理将调用参数打包成消息,并发送到由名字服务器所指定的网络远程调用代理接口。服务器接收消息传送到服务器代理,由服务器代理解包参数,识别出被调用的过程并调用它。当过程返回时,服务器代理将结果打包并返回给客户代理,由客户代理再解包返回的结果并返回到调用者。

当通过传值方法进行参数传递时,使用这种机制很容易进行处理,而通过传名、传指针方式传递参数则难以实现。对于后一个问题,不同的远程过程使用了不同的方法,然而,每一种都将增加在客户代理与服务器代理之间进行网络传输的负担。

RMI对于跨越不同机器间的分布式处理是有用的,但它们并不鼓励并行计算。当一个调用者调用远程对象方法时,在该方法执行期间它会被阻塞。所以当考虑一个RMI实现时,性能总是一个主要问题。虽然RMI提供了延迟绑定,但它的性能开销必须尽可能地小,即使这样,在当代分布式应用中远程过程还是被广泛采用,因为它们并不需要了解分布机制和策略,却实现了一个传统的编程模型。    

 

 

 

                                                                                                                    上一节