一、绪论
紧密耦合与松散耦合分布计算系统
1紧密耦合分布计算系统
连接方式:内部总线或机器内互连网络 ;
处理资源间距离:物理上分散,相距很近;
处理资源:处理机;
通信方式:共享存储器。
2松散耦合分布计算系统
连接方式:通信网络 ;
处理资源间距离:地理上分散,相距很远;
处理资源:计算机系统;
通信方式:报文交换。

透明性的概念
透明性:事物本来存在某种属性,但是这种属性从某种角度上来看是不可见的,称这种特性为透明性。
分布计算系统的透明性:用户或程序员看不见网络的存在。这样从用户或程序员的角度看来,网络中的全部机器表现为一个,用户或程序员看不到机器的边界和网络本身。用户不必知道数据放在什么地方以及进程在何处执行。
分布计算系统的透明性表现:
1名字透明。名字透明指的是对象的命名在全局是唯一的,不管在什么地方访问该对象使用的名字都是一样的。这样一来,在系统中移动一个程序不影响它的正确性。
2位置透明。位置透明指的是资源的名字中不包含该资源的位置信息。这样一来,当该资源在系统中移动时,在资源名字保持不变的情况下,原有的程序都可正常运行。
3访问透明。用户不用区分本地资源还是远程资源,访问本地资源和访问远程资源的方法是一样的。
4迁移透明。迁移透明指的是用户不知道一个资源或者他的作业是否迁移到另外一个位置。迁移透明需要名字透明的支持。
5复制透明。复制透明允许文件或其他对象的多个副本同时在系统中存在,但是这种情况对用户是透明的,对对象的修改应同时作用在对象的所有副本上。
并发和并行透明。多个进程可能并发或并行访问同一个资源,或一个进程同时使用多个资源,在此情况下不会产生相互干扰和破坏。
6失效透明。系统中的某一部分失效时,整个系统不会失效,仍可正常运行。
区分计算机网络系统与分布计算系统
1从文件系统的访问方法上区分 :
没有操作系统的访问方法。计算机A上的程序将B上的文件复制到A上来,然后再在A上访问此文件。
有网络操作系统的访问方法。这种方法是把不同的文件系统连接起来,一个机器上的程序可以使用路径名打开另一个机器上的文件,只是这个路径名中包含了另一个机器的信息。
如:open(“/machine_name/pathname”,READ);
或:open(“machian_name:pathname”,READ);
或:open(“/../ machian_name:pathname”,READ);
分布计算系统使用的方法。在这种方法中,所有各子系统的文件系统组成一个整体文件系统。
2从访问控制方面区分
UNIX和其他许多操作系统给每个用户赋予一个唯一的内部标识符(UID),以利于访问控制。
没有网络操作系统下的情况。这种办法要求所有要访问机器X上的文件的用户先使用属于机器X的用户名在机器X上登录。
有网络操作系统下的情况。在这种办法中,由网络操作系统对不同机器上的UID进行变换。
在分布式操作系统下的情况。在分布计算系统中,对每个用户只设一个UID,使用它可以访问任何机器,不必经过变换。
3是否区分本地执行和远程执行方面判断
在没有网络操作系统的计算机网络系统中,用户要远程执行一个程序时,该用户先远程登录到一个远程机器上,然后在那里运行作业。
在有网络操作系统的计算机网络系统中,用户在自己的终端上输入一个特殊的命令,指定一个机器运行一个程序。 如:remote vax4 who,这个命令是让远程计算机vax4运行 程序who。
在分布计算系统中,用户执行一个程序时,只需简单的给出要执行的程序的程序名和相关的参数,并不指出在何处执行这个程序,何处执行由操作系统决定。
二、进程通信
两种基本的实现进程通信的方法是:报文传递和远程过程调用RPC。
区别于
文件的远程访问方法有两种:缓存和远程服务。
报文传递:


远程过程调用:


ISIS中的组通信
ISIS中定义的通信原语 :
ISIS中定义了三种广播语义,它们分别是:ABCAST、CBCAST、GBCAST。
ABCAST提供松弛的同步通信,用于向进程组成员传输数据;
CBCAST提供虚同步通信,也用于发送数据;
GBCAST的语义和ABCAST一样,只是它用于组成员的管理,而不是用于发送一般的数据。
ABCAST 。ABCAST使用两阶段提交协议(two-phase commit protocol)的形式进行工作。首先,发送者A向进程组中的所有成员申请一个时间戳(timestamp),并将报文发送到进程组的所有成员。进程组的所有成员向发送者分配一个时间戳,该时间戳要大于所有该成员所发送的和所接收的报文的时间戳。A接收到所有成员分配的时间戳之后,从中选择一个最大的时间戳作为要发送报文的时间戳,然后向所有组成员发送一个带有该时间戳的提交报文。提交报文按照时间戳的顺序传递给应用程序。使用该协议能够保证所有报文按照同样的顺序传递到所有进程。

CBCAST。使用CBCAST原语,只能保证因果相关的报文被所有的进程按同样的顺序接收(虚同步)。利用一个向量来调整具有因果关系的报文的接收顺序。 如果一个进程组有n个成员,则每个成员保持一个有n个元素的向量,向量中的第i个元素是该成员从进程i那里收到的最后一个报文的号码。当一个进程需要发送一个报文时,它首先将向量中对应自己的元素增1,对于发送者来说,因为自己是该组的成员,发向该组的报文也意味着发向自己。发送者将修改后的向量随报文一起发送。

三、命名与保护
名字的两种形式:地址和标识符。
对一个对象进行操作或访问时,往往需要将它的标识符变换为它的地址,变换的过程中需要用到变换表,这个变换表叫做上下文(context)。
名字按结构可分成绝对名字和相对名字两种
地址结构也有两种,即平面地址和分层地址。
分层地址:路由选择容易;容易创建新的地址;一个进程迁移到另一个机器上时不能使用原来的地址
平面地址:路由选择困难;不易创建新的地址;一个进程迁移到另一个机器上时可以使用原来的地址
名字解析
在名字空间中,根据节点的路径名,就可以寻找到这个节点所存储的任何信息,这个查找的过程就称为名字解析。
大规模分布计算系统中名字解析
重复式名字解析;由顾客方名字解析器主动向各级名字服务员发起查询,逐步获取路径中的每个标号对应的节点标识符,直至完成整个路径解析。
递归式名字解析。由根节点名字服务员接收查询请求后,自动向下级名字服务员递归查询,直至获取完整结果并返回给顾客,顾客无需参与中间过程。
主要缺点是要求每个名字服务员具有较高的性能;主要优点是缓存效果同重复式名字解析的缓存效果相比更为有效,还可以减少通信代价。
加密和解密的方法分为两种类型:传统方法和公开密钥方法。
传统加密方法:
1替换法:在这种加密方法中,每个字符都被另一个字符所代替。这种加密方法称为恺撒密码,因为它最初被恺撒使用。
2位置交换法:在这种方法中,字符将保持它们在原文中的格式,但是它们的位置将被改变来创建密文。
数字签名
实现数字签名,要解决两个问题:第一,接收者能验证所要求的发送者的身份;第二,发送者在发送已经签名的报文后不能否认。
公开密钥加密技术实现数字签名要求加密函数E和解密函数D满足下列条件--就是E和D可以互换:E(D(P))=P,当然同时还有D(E(P))=P


报文摘要:使用单向散列(hash)函数可以从一段很长的明文中计算出固定长度的比特串。这个比特串通常被称为该报文的摘要(message digest) 。
报文摘要具有三个重要的属性:
1给出报文P就很容易计算出其报文摘要MD(P)。(易计算性:原始明文的摘要容易被算出)
2只给出MD(P),几乎无法推导出P。(不可逆性:摘要无法反向推断出原始明文)
3无法生成这样的两条报文,它们具有同样的报文摘要。(抗碰撞性:不同报文摘要必定不同)
报文摘要实现数字签名的过程:
A首先计算P的报文摘要MD(P);
A用自己的保密密钥(A的私钥)对MD(P)进行加密以达到签名的目的;
A将报文摘要的签名形式DA(MD(P))连同明文P一起发送给B;
B用A的公开密钥(A的公钥)解密DA(MD(P)),从而得到MD(P),验证是否是A发送的;
B使用与A同样的单向哈希函数作用于他收到的明文P`,计算出MD(P`),对比计算出的MD(P`)和收到的MD(P)是否一致,来确认是否有非法用户修改报文P。 若一致,则P`是可信任的未被篡改的原始明文P;若不一致,则P`已被篡改,不可以信任。
使用公开密钥加密技术保护权能:



信口
网络上的任何顾客和服务员都有两个信口:G和P,G是保密的,P是公开的。P=F(G),由P不能推出G。
使用F盒实现数字签名:
顾客A选择一个随机签名S并公布F(S)。A交给F盒用来发送的报文报头中包含三个特别的段:目的地(PB),源地址(GA)和签名(S)。F盒对GA和S进行单向函数变换,变换成PA和F(S)。B知道确实是A发送的,因为只有A才知道在第三段中放一个什么数S,只有此数才能产生众所周知的F(S)。
四、同步和互斥
同步点:为了达到合作,各个进程在执行的过程中必须存在若干点,超过这些点时,一个进程在另一个进程执行完某一活动前不能继续执行,这些点称为这两个进程之间的同步点。
同步机构的目的就是给进程提供某种手段,使系统保持一致状态
逻辑时钟概念
设Ci代表进程i的逻辑时钟,该逻辑时钟就是一个函数,它给进程i中的事件a分配一个正整数值Ci(a)。
时钟条件:
1对任何事件a和b,如果a→b,则C(a)<C(b)。但相反的结论不能成立。
2若a和b是同一进程Pi中的两个时间,并且a→b,则Ci(a)<Ci(b);
3若a代表“一个Pi进程发送一个报文”这个事件,b代表“另一个进程Pj接收这个报文”这个事件,Ci(a)<Cj(b)。
标量逻辑时钟
1当发生一个事件(一个外部发送或内部事件)之前,我们更新LCi: LCi:=LCi+d (d>0)
2当收到一个带时间戳的报文(m,LCj,j)时,我们更新LCi: LCi:=max(LCi,LCj)+d (d>0)
向量逻辑时钟
1当发生一个事件(一个外部发送或内部事件)之前,Pi更新LCi[i]:
LCi[i]:=LCi[i]+d (d>0)
2每个报文捎带发送方在发送时的时钟向量,当收到一个带时间戳的报文(m,LCj,j)时,Pi更新LCi:
LCi[k]:=max(LCi[k],LCj[k]) 1≤k≤n
LCi[i]:= LCi[i]+d (d>0)
如果一个全局状态是一致的并且是非传送中的,那么它就是强一致的,也就是说,局部状态集是一致的并且没有正在传送中的报文。即:没有孤儿报文就是一致状态,如果在此基础上还没有传送中的报文,那就是强一致状态。
全局状态的获取(快照算法):
1假如启动算法的进程为P,那么它首先记录自己的局部状态,然后它沿着它的输出通道发送一个标志(marker),指示接收者应该参与记录一个全局状态的工作。
2当接收者Q通过它的输入通道C收到一个标志,它将依据不同条件执行以下不同操作:
(1)如果Q还没有记录自己的局部状态,它①首先记录自己的局部状态,②并记录通道C的状态为空报文序列,③然后也沿着它自己的输出通道发送一个标志。
(2)如果Q已经记录了自己的局部状态,通过通道C收到的标志用来指示Q应该记录通道的状态。通道的状态是Q记录它的局部状态以来到收到这个标志前所收到的报文系列。
3如果一个进程已经沿它的每个输入通道接收到一个标志,并对每个标志进行了处理,就称它已经完成了它的那部分算法。
4一个进程的局部状态,连同它的所有输入通道的状态将被发送到这个快照的发起进程。
互斥问题就是定义一些基本的操作来解决共享资源的多个并发进程的冲突问题。
互斥算法的主要目标是保证在任一个时刻只能有一个进程访问临界区。
一个正确的互斥算法必须避免冲突(死锁和饿死)和保证公平性。为此,算法应满足以下三个条件:
1已获得资源的进程必须先释放资源之后,另一个进程才能得到资源;
2不同的请求应该按照这些请求的产生顺序获得满足,请求应该按照某种规则进行排序,例如使用逻辑时钟确定请求的顺序; (保证公平性)
3若获得资源的每个进程最终都释放资源,则每个请求最终都能满足。
Lamport时间戳互斥算法由以下5条规则组成 :
1一个进程Pi如果为了申请资源,它向其它各个进程(该算法中大家均为资源的管理员)发送具有时间戳Tm:Pi的申请资源的报文,并把此报文也放到自己的申请队列中;
2一个进程Pj如果收到具有时间戳Tm:Pi的申请资源的报文,它把此报文放到自己的申请队列中,并将向Pi发送一个带有时间戳的承认报文。如果Pj正在临界区或正在发送自己的申请报文,则此承认报文要等到Pj从临界区中退出之后或Pj发送完自己的申请报文之后再发送(只要我正在用或者想要用,我就不管三七二十一都不会立即承认其他人),否则立即发送;
3一个进程Pi如果想释放资源,它先从自己的申请队列中删除对应的Tm:Pi申请报文,并向所有其他进程发送具有时间戳的Pi释放资源的报文;
4一个进程Pj如果收到Pi释放资源的报文,它从自己的申请队列中删除Tm:Pi申请报文;
5当满足下述两个条件时,申请资源的进程Pi获得资源:
(1)Pi的申请队列中有Tm:Pi申请报文,并且根据时间戳它排在所有其它进程发来的申请报文前面(我自己的队列中有我自己的申请,且我的申请排在其他人的申请之前);
(2)Pi收到所有其它进程的承认报文,其上面的时间戳值大于Tm(承认报文的时间戳肯定大于申请报文的时间戳)。
Lamport时间戳互斥算法在有着n个进程的系统中,完成一次互斥所需要的报文数目为 3(n-1)
Ricart-Agrawala互斥算法由以下规则组成 :
1一个进程申请资源时向所有其他进程发出申请报文(可以是时间戳);
2其它进程收到申请报文后若不在临界区并且自己未申请进入临界区,或者自己虽然发出了申请报文,但自己的报文排在收到的申请报文之后,则回答表示同意;
3申请资源的进程仅在收到所有进程的回答报文后才进入临界区使用资源;
4一个进程使用完资源后,它向所有未给回答的其它申请发送回答报文。
Maekawa互斥算法
请求子集:在Maekawa互斥算法中,一个进程P在发出申请报文后,不用得到所有其他进程的回答,而只须得到一个进程子集S中的所有进程的回答即可进入临界区。称S是P的请求子集。假设Ri和Rj分别是进程Pi和Pj的请求子集,要求Ri∩Rj≠NULL。
1当进程Pi请求进入临界区时,它只向Ri中的进程发送请求报文。
2当进程Pj收到一个请求报文时,如果它自上一次临界区释放后还没有发出过回答报文给任何进程,且自己的请求队列中无任何请求,它就给该请求报文一个回答。否则,请求报文被放入请求队列中。
3进程Pi只有收到Ri中的所有进程的回答后,才能进入临界区。
4在释放临界区时,进程Pi只给Ri中的所有进程发送释放报文。
考虑一个七个进程的例子,每个进程的请求子集如下:
R1:{P1,P3,P4};
R2:{P2,P4,P5};
R3:{P3,P5,P6};
R4:{P4,P6,P7};
R5:{P5,P7,P1};
R6:{P6,P1,P2};
R7:{P7,P2,P3}。
Bully选举算法
1P发送选举报文到所有优先级比它高的进程。
2如果在一定时间内收不到任何响应报文(说明P可以认为自己就是现在系统中优先级最高的进程),P赢得选举成为协调者。它向所有比它的优先级低的进程发送通知报文,宣布自己是协调者。
3如果收到一个优先级比它高的进程的回答(说明此刻有人比我高,我级别不够,乖乖退出选举,等通知看谁是选出来的协调者),P的选举工作结束。同时启动一个计时器,等待接收谁是协调者的通知报文,如果在规定时间内得不到通知报文,则它重新启动选举算法。
4任何时候,一个进程可能从比它的优先级低的进程那儿接收到一个选举报文,它就给发送者回答一个响应报文(哟,怎么还有级别比我低的人相当老大,这能忍?发报文通知他你别当了,我来!),同时启动如上所述的相同的选举算法,如果选举算法已经启动,就不必重新启动。


Dijkstra自稳定系统:有一个特别的进程,它对于状态转换使用独特的特权,其他进程使用另一个特权。给定n个k状态进程,k﹥n,标号分别为P0到Pn-1。P0是特别的进程,其他进程Pi(0<i≤n-1)是一样的。
Pi的状态转换如下:(假设Pi的状态记作Si)
Si≠Si-1⇒Si:=Si-1, 0<i≤n-1
P0的状态转换如下:
S0=Sn-1⇒S0:=(S0+1) mod k
五、分布式系统中的死锁
死锁发生的条件
1互斥。正如我们第五章所讨论的,互斥是一种资源分配方式,保证同一个资源在同一时刻最多只能被一个进程占用,它用于防止多个进程同时共享访问不可同时共享访问的资源。
2不可剥夺的资源分配。系统将一个资源的访问权分配给某一个进程后,系统不能强迫该进程放弃对该资源的控制权。
3占有并等待。必然有一个进程占用了至少一个资源,同时在等待获取被其他进程占用的资源。
4循环等待。在等待图中有一个循环路径。
处理死锁的策略
可以使用PAID来概括死锁处理的各种方法:预防(Prevent)、避免(Avoid)、忽略(Ignore)和检测(Detect) 。
1预防死锁。通过限制请求,保证四个死锁条件中至少有一个不能发生,从而预防死锁。
2避免死锁。如果资源分配会导致一个安全的结果状态,就将资源动态地分配给进程。如果至少有一个执行序列使所有的进程都能完成运行,那么这个状态就是安全的。
3忽略死锁。忽略死锁是UNIX常采用的一种方法,这种方法只是简单地忽略死锁问题(针对死锁很少发生的情况)。
4检测死锁和从死锁中恢复。允许死锁发生,然后发现并解除死锁。
资源死锁通常使用AND条件,而通信死锁通常使用OR条件
在使用AND条件的系统中,死锁条件是在等待图中存在回路。
但是在使用OR条件的系统中,等待图中的回路未必会引发死锁。在使用OR条件的系统中,死锁条件是存在结(knot):一个结K是一个节点集合,对于K中的任何节点a,a能到达K中的所有节点,并且只能到达K中的节点。
基于时间戳的预防死锁方法(可以看出来这两种方案中如果出现了死亡,那么死亡的一定是更年轻的进程)
包括两种死锁预防方案。这两种方案相互补充,这种方法常用于分布式数据库系统中。
等待—死亡方案(wait-die scheme)。该方案是基于非剥夺方法。当进程Pi请求的资源正被进程Pj占有时,只有当Pi的时间戳比进程Pj的时间戳小时,即Pi比Pj老时,Pi才能等待。否则Pi被卷回(roll-back),即死亡(释放自己所占有的资源)。
伤害—等待方案(wound-wait scheme)。它是一种基于剥夺的方法。当进程Pi请求的资源正被进程Pj占有时,只有当进程Pi的时间戳比进程Pj的时间戳大时,即Pi比Pj年轻时,Pi才能等待。否则Pj被卷回(roll-back),即死亡。
死锁检测的实例
AND模型下的Chandy-Misra-Hass算法 (边跟踪算法的一种)
1在Chandy-Misra-Hass算法中,分布式死锁检测算法使用一个特殊的报文,在等待图中该报文从一个进程传递到另一个进程,该报文称为探测报文(probe message)。如果报文回到发起者,那么就有死锁存在。探测报文包含一个三元组(i,j,k),表示该报文是一个由进程Pi发起的死锁检测报文,现在由进程Pj所在的站点发往进程Pk所在的站点。
2当一个进程接收到一个探测报文时,它首先检查自己是否等待某个(或某些)进程,如果它正在等待某个(或某些)进程,它将向所有它等待的进程转发这个探测报文(探测报文一直沿着进程的等待方向转发)。
AND模型下的Chandy-Misra-Hass算法中打破死锁方法:
1探测报文的发起者杀死自己(有好几个处于同一死锁的进程都发送了探测报文,他们各自的探测报文都回到自己了,结果他们都会自杀,这就导致一个死锁的循环重要重启好几个进程,效率低下)
2发起者进程选取一个具有最大标识符号码的进程杀死
AND模型下的Mitchell-Merritt算法
1其限制是每个进程每次只能请求一个资源。
2探测报文在等待图中,沿等待方向的相反方向传送,这样的图叫反向等待图(reversed wait-for graph)。
3每当进程收到探测报文时,它将自己的标识符和探测报文发起者的标识符相比较,如果自己的标识符大于探测报文发起者的标识符,它就用自己的标识符取代探测报文发起者的标识符,自己变成探测报文的发起者。
4当几个进程同时发起死锁检测时,只有一个进程能够成为唯一的探测者。
OR模型下的Chandy-Misra-Hass算法

六、分布式系统中的容错技术
坚固存储器是对一个可以经受系统失效的特定存储器的逻辑抽象,也就是说,坚固存储器里的内容不会被一个失效所毁坏。
坚固存储器的实现方法:磁盘镜像、RAID
原子操作
一个原子操作就是由硬件独立执行的一系列动作。也就是说,每一个动作或者被完全彻底地执行,或者所有的动作根本没有执行,系统的状态保持不变。一个原子操作要么全部完成,要么在执行过程中出现错误的时候相当于根本没有执行。
向前式恢复:假定可以完全准确地得到系统中的故障和损失的性质,这样就有可能去掉这些故障从而使得系统继续向前执行
向后式恢复:适用于系统的故障无法预知和去掉的情况,在这种情况下,要定时地存储系统的状态,这样当失效导致系统处于不一致的状态时,系统可以恢复到从前没有发生故障的状态,在此状态下重新执行
检查点:在向后式恢复中进程被恢复到一个先前的正确的状态。进程执行中的一些点被称为“检查点”(checkpoint),在以后发生错误的情况下,进程可以被恢复到这些点。
检查点的两种分类:同步检查点和异步检查点
一个强一致(strongly consistent)的检查点集合是由一系列的没有孤儿报文和没有丢失报文的局部检查点组成。
一个一致的检查点集合是由一系列没有孤儿报文的局部检查点组成
一致检查点的检测方法:
比较发送的和接收的报文数量来检测孤儿报文的存在。如果接收到的报文数目和任何发送报文的进程发送的报文的数目是一致的,那么就可以认为找到了一个局部检查点的一致集合。

Sync-and-Stop(SNS)算法中有一个进程pc负责管理全局检查点建立过程。各进程的检查点建立过程如下:
1pc向所有进程广播检查点开始报文Mb(begin)(第一次同步开始);
2任一个进程接收到报文Mb后停止运行,并在自己所发送的报文全部到达接收者后向pc进程发送报文Ms1(表示第一次同步);
3pc接收到所有进程发送的报文Ms1后,即意味着第一次同步结束。pc向各进程广播报文Mchk(checkpoint),第二次同步开始;
4任一个进程接收到报文Mchk后,立即作局部检查点,检查点建立完成之后向pc发送报文Ms2(表示第二次同步);
5pc接收到所有进程发送的报文Ms2后,意味着第二次同步结束。pc向所有进程广播报文Me(end);
6各进程接收到报文Me后,删除旧的检查点,仅保留新的检查点,然后继续执行。SNS算法的恢复过程十分简单,只需回卷到检查点处继续执行。
经过第一次同步之后,任何进程所发送的报文都已经被对应的接收进程接收到,任何进程之间不会存在孤儿报文,也不会存在丢失报文,满足一致性的要求。
经过第二次同步,则表示所有进程的局部检查点都已经建立完了。
Chandy-Lamport(CL)算法:
1建立检查点的过程可由任一个进程pc发起,pc进程停止运行,并向与其所在机器直接相连的机器上的进程广播报文Mb(begin),然后进程pc建立局部检查点;
2进程p接收到报文Mb后,若进程p还未开始建立检查点,则进程p停止运行并立即向与其所在机器直接相连的机器上的进程广播报文Mb,然后进程p建立局部检查点;
3进程p开始建立检查点后,若接收到其他进程发送的非检查点控制报文m(检查点控制报文是这些正在制作检查点的进程之间为了建立检查点而相互通信的报文,这些必要的报文不需要保存),则保存报文m(这些报文的信息并未被保存到检查点里面,因为在建立检查点这一过程开始后它们才到达,所以不会被记录到检查点里,而是简单的单独保存它们以便在回卷时候重发);
4当进程p完成局部检查点的建立,并且接收到与其所在机器直接相连的机器上的所有进程发送的报文Mb后,进程p向pc进程发送报文Ms(sync同步);
5当进程pc接收到所有进程发送的报文Ms后,pc进程向所有进程发送报文Me(end),并删除本进程旧的检查点,进程pc继续执行;
6其他进程p接收到报文Me后,删除本进程旧的检查点,继续执行。
在恢复过程中,CL算法在回卷到当前检查点重新执行的同时还必须重发过程c)中保存的报文m(因为这些报文的信息并未被保存到检查点里面,在建立检查点这一过程开始后它们才到达,所以不会被记录到检查点里,而是简单的单独保存它们以便在回卷时候重发)。与SNS算法相比,CL算法减少了两次全局同步的开销。CL算法的缺点是其控制报文的数目与机器间的拓扑结构有关。
基本的可靠组播方案

简单方案:接收者收到组播报文后不向发送者发送应答报文,只有在接收者发现丢失一个报文后,才向发送者发送一个反馈报文,指出某个报文丢失了。
问题1:多个接收者丢失报文时,仍然会出现反馈报文拥塞的情况 ;
问题2:在理论上讲,发送者必须在其历史缓冲区中长时间保存它发送的每一个广播报文(因为发送者不知道到底哪一个报文可能丢,所以必须全部都缓存起来以备不测)。
非层级式反馈控制
成功接收到组播报文的接收者不向发送者发送反馈报文,只有在接收者发现有报文丢失的时候才会发送反馈报文,也就是说只有否定应答被当作反馈报文返回给发送者。
如果一个接收者发现它丢失了报文m,它不仅将反馈报文发送给发送者,还将反馈报文组播给组内的所有其他进程。
其他同样丢失了报文m的接收者收到这样的反馈报文后,就不会发送同样的反馈报文。这样接收者只会收到一个反馈报文,从而只重复组播报文m一次(防止不同接收者对于同一个丢失报文的重复反馈)。

问题1:为了确保只有一个反馈报文返回给发送者,需要对所有接收者的反馈报文进行精确地调度,即给每个接收者精确地设置延迟时间,在一个广域网中,精确地设置延时是十分困难的。
问题2:对反馈报文进行组播的时候会对成功地接收到组播报文的接收进程产生干扰,也就是说,其他成功接收到组播报文的接收进程被迫接收和处理一些对他们来说毫无用处的报文(这些抑制反馈的报文只是对于那些未能成功接收到组播的进程有意义,对于成功接收到组播的进程来说它们全无意义)。
层级式反馈控制
在层级式可靠的组播方案中,进程组被划分成多个子进程组,这些子进程组被组织成树型结构,包含有发送者的子进程组是树的根。在一个子进程组内,可以采用任何一种可靠的组播技术。
每个子进程组任命一个本地协调者,负责处理该子进程组内的接收者的重发请求。本地协调者有自己的历史缓冲区。如果协调者本身丢失了报文m,它会要求它的父亲子进程组的协调者重发报文m。

原子组播中的虚同步:

七、分布式数据管理

FIFO一致性
一个进程中的所有写操作能够以它在该进程中出现的顺序被所有其他进程看见。但是不同进程中的写操作在不同的进程看来具有不同的顺序。
处理机一致性:在这种模型中,不仅要求一个进程中的所有写操作能够以它在该进程中出现的顺序被所有其他进程看见,还要求不同进程对同一个数据项的写操作,应该被所有进程以相同的顺序看见。
弱一致性
即同步操作才能把对于数据修改的消息发送出去,这个修改才被认为是有效的。读之前必须同步才能确保读的是新鲜且有效的;写之后同步才能确保修改操作生效。
释放一致性
1前面的所有acquire操作完全成功完成以前,对共享数据的读写操作不能执行;
2在一个释放操作被允许执行之前,所有以前的读写操作必须完成;
3对同步变量的访问必须遵守FIFO一致性模型。
进入一致性
即一个进程无论是想去对于一个文件做非互斥性的读,还是做互斥的写,他都必须先拿到这个文件的锁,不然操作不能进行。一个文件的锁被某人持有时,其他人对此文件的尝试访问都失败。
并发控制的目的:是在有多个用户的情况下允许每个用户像单个用户那样访问共享资源,多个用户同时访问时互相不干扰。并发控制要解决多个用户的活动之间的切换,保护一个用户的活动不受另一个用户的活动的影响,以及对相互依赖的若干活动进行同步等问题。
无并发控制的情况下可能出现问题:丢失更新,检索的不一致
并发控制正确性标准有两条:
1用户交给系统的每个事务处理最终将被执行,并最终得到完成;
2多个事务处理并发执行的结果和这多个事务处理串行执行的结果相同。
一致调度的充分条件是这种调度执行的结果和所有事务处理串行执行的结果是一样的
满足这个条件的调度叫做可串行化调度或线性化调度。
两个调度等价:在事务处理系统上两个调度等价当且仅当
1两个调度中每个对应的读操作读自同一个写操作;
2两个调度中有同样的最终写。
两阶段封锁:
两阶段封锁可以保证一致性,实现正确的并发控制。两阶段封锁的主要内容如下:
①访问一个对象前先封锁它,为此必须先获得锁;
②对所有要访问的对象封锁前不对任何对象进行解锁;
③不要封锁已经被封锁的对象,为此不同的事务处理不可同时获得冲突的锁;
④事务处理执行结束前,为每个被它封锁的对象解锁;
⑤一旦一个事务处理释放一个锁,该事务处理就不能再获得另外的锁。
每个事务处理锁的过程可分成两个阶段:锁的增长阶段和锁的收缩阶段。增长阶段中事务处理获得所有的锁而不释放任何锁;收缩阶段释放所有的锁而不取得另外的锁。
两阶段封锁的问题:
问题1:在锁的增长阶段会出现死锁的问题(锁的收缩阶段不会)。发生死锁是因为在加锁机制中,锁是一种竞争的资源。死锁问题可以用第六章讨论的办法来解决。
问题2:在锁的收缩阶段容易出现层叠回退(cascaded aborts)的问题。层叠回退的问题发生在一个事务处理操作失败后回退,在回退前由于该进程已经释放了某些数据对象上的锁,所以其他事务处理可能已经读取了被这个事务处理修改过的数据对象,这些事务处理也必须回退。层叠回退可以用严格的两阶段封锁方案来解决
原子事务处理的性质:
一个事务的处理只有以下两种结果:一种是事务处理完全正确地执行完毕;另一种则是当事务夭折或者取消时,相当于该事务完全没有执行。称之为原子事务处理。
1原子性(Atomicity)。一个原子事务处理的执行必须确保是完全执行完毕或相当于完全没有执行。
2一致性(Consistency)。一个事务处理必须以一致性的状态开始,以一致性的状态结束。不能违背系统的恒定性。
3孤立性(Isolation)。原子事务处理所有的中间操作必须以孤立的形式执行。只允许在该事务处理操作的某个数据对象达到一致的状态时才能够被其他事务处理访问。也就是说,并发的事务处理之间不会发生相互干扰。孤立性也称为可串行性。
4持久性(Durability)。一旦事务处理已经被提交,即使在发生系统失效的情况下,结果将永不丢失。
原子事务处理组成部分:
1事务处理管理员:负责使该事务处理的各个参加者就该事务处理是否提交或夭折达成一致意见;
2恢复管理员:负责在事务处理失效后恢复状态;
3缓冲器管理员:负责在主存和磁盘间传送数据;
4运行记录(log)管理员:负责各种操作及状态的记录;
5锁管理员;负责并发控制;
6通信管理员:负责透明的跨网络的通信,在分布式事务处理中通知事务处理的管理部分。
原子事务处理的局部恢复技术:意图表,先写运行记录
意图表方法:适合严格的两阶段封锁(不会产生层叠回退)
1把事务处理要向各数据对象施加的所有修改操作(即写操作)都存放在一个表中,该表称为意图表;
2该表被写入坚固存储器中;
3事务处理管理员决定该事务处理是否提交;
4若该事务处理提交,则在表中设置完整标志,开始按照意图表修改在磁盘中的那些对象;
5删除意图表。
意图表失效后的处理方法:
1若意图表不存在(即所有数据均还没有修改过),则夭折该事务处理。
2若意图表不完整,即在写意图表时节点崩溃(还未修改磁盘中数据库的内容),则夭折该事务处理并删除此表;
3若意图表完整,即在按坚固存储器中的意图表对数据对象进行实际的更新时节点崩溃(此时可能修改了数据库中的内容但还没有修改完),则系统按表中的说明进行更新(即按照完整意图表中记录的操作对于数据库重新进行更新,管他哪些更新了那些没更新,全部重新从头再更新一遍),更新完毕后删除意图表。
先写运行记录方法:适合非严格的两阶段封锁(可能产生层叠回退,在收缩阶段或者事务夭折的时候)
向运行记录写入旧值→向运行记录写入新值→对数据对象进行实际的更新
执行过程:先写运行记录的方法在事务处理的执行过程中,对数据对象进行了实际的修改(区别于意图表方法)。但是在数据对象被修改前,需要在运行记录中写一个记录项,用于告诉事务处理管理员对哪个数据对象进行修改,修改前的值和修改后的值是什么,以便用于失效后的恢复。只有在这个记录项正确地写到运行记录之后,才能对实际的数据对象进行修改(确保数据已经完成备份之后才能修改实际数据)。该运行记录是放在坚固存储器之中的。
分布式事务处理的全局恢复:分布式提交(如两阶段提交)
两阶段提交协议(2PC)
1协调者的准备提交阶段:
①向所有的参加者广播一个PREPARE(准备)报文;
②等待每一个参加者的回答。
每个参加者仅在“完成此事务处理中属于它应该完成的那部分工作,同时写好运行记录之后”才发出一个回答报文。
2协调者的提交阶段:
如果有一个参加者回答一个ABORT(夭折),或者有一个参加者超时未回答,则将ABORT项写入运行记录中(协调者裁决这一次协议是夭折的),然后向所有参加者广播一个ABORT报文,在收到参加者的承认后(即便有的参加者已经成功完成了这一操作,仍然要强行夭折已经完成的这一操作),本次协议的执行结束。如果所有参加者发来的PREPARED(准备好了)报文,则进行以下操作:
①在运行记录上写入一个COMMIT(提交)项;
②向所有的参加者广播一个COMMIT报文;
③等待每个参加者做出肯定回答ACK-COMMIT;
④将COMPLETE(完成)项记入运行记录,本次协议的执行结束。
3参加者的准备提交阶段:
①等待协调者的PREPARE报文;
②完成自己的工作,将运行记录项写入运行记录;
③如果成功,则将COMPLETE项记入运行记录(参加者自己的运行记录),并向协调者发送PREPARED报文;否则发送ABORT报文。
4参加者的提交阶段:
①等待协调者的裁决报文;
②向协调者发送回答。如果裁决是ABORT则将事务处理作废,同时将ABORT项写入运行记录中,释放锁,发送夭折承认报文ACK-ABORT;如果裁决是COMMIT,在运行记录上写入一个COMMIT项,释放锁,发送提交承认报文ACK-COMMIT。

数据库一致性包含两个方面:冗余副本的相互一致性和每个副本的内部一致性。
复制控制算法用来保证兼容可串行化,保持数据库多副本间的相互一致性
兼容串行化:设并发事务处理T1和T2分别使存储处理机P和Q产生活动A1(P)、A1(Q)和A2(P)、A2(Q),如果A1(P)→A2(P)在P处是正确的串行顺序(即可串行化调度的顺序),则在Q处的可兼容串行化应为A1(Q)→A2(Q)。 (交叉的次序应当是一样的)
同步表决方法中如果一个数据库有n个副本,现在要完成一次更新,需要多少个报文?2n(n-1)个报文
法定数方法要读取一个文件,必须要得到NR(读定额)个服务员同意。要修改一个文件,需要得到NW(写定额)个服务员同意。NR和NW应满足:NR+NW>N。
最有利于读:NR=1,NW=N
最有利于写:NR=N,NW=1
八、分布式文件系统
分布式文件系统的共享语义
1UNIX语义:顾客对打开的文件进行的写可立即被其他同时打开此文件的顾客看到,即使该顾客在远程也能够看到。
2对话语义:对于打开文件的write可立即被本地顾客看见,远程的顾客虽然也同时打开该文件,但却看不见。一旦文件关闭,对此文件所作的修改仅在以后开始的对话中才能看见,该文件已经打开的各副本不表现这些修改。
3事务处理语义:几个文件对话对一个文件的作用及其输出等效于以某个串行次序执行这些对话的作用及其输出。
4不可改变的共享文件语义:文件被其创建者说明为共享的,它就不能再被修改。

文件的远程访问方法有两种:缓存和远程服务。
对话语义和缓存整个文件非常匹配,UNIX方法和远程服务方法配合的很好(UNIX和缓存配合很差)
缓存时,优点:服务员负载和网络通信量都减少,扩充能力加强,网络开销低于远程服务时。缺点:一致性问题,经常写问题不适合使用缓存方案,会频繁导致一致性问题。
缓存副本的更新策略
1立即写
2延迟写(驱逐时写,周期性写,关闭时写)
“关闭时写”适合“对话语义”; “立即写”方法比较适合UNIX语义。
有状态的(stateful)服务员:服务员在为其顾客请求进行服务的时候,保存其顾客的有关信息。
无状态的(stateless)服务员:服务员在为其顾客请求进行服务的时候,不保存该顾客的任何信息。
无状态服务比有状态服务更加坚定(无状态服务的状态不依赖于本地,崩溃了换一个健康实例可以继续执行)
文件复制:文件复制是一个冗余措施。这里指的是不同机器上的文件复制,而不是同一机器上不同介质上的文件复制。复制文件可以增强其可用性。
网络文件系统NFS

NFS v3一个对于远程服务的请求对应一个RPC,而NFS v4多个对于远程服务的请求可以对应一个RPC 。
NFS v4以前的版本同许多其他分布式文件系统的区别是,其文件服务员是无状态的。但是,NFS v4放弃了这种方案,其服务员是有状态的。
九、分布式调度
调度算法分为两类:全局调度和局部调度
分布式调度的基本目标:
1负载平衡(提高整个系统的流量)
2负载共享(缩短特定程序的执行时间)
调度算法的有效性来看,调度算法分为最优调度算法和次优调度算法
次优的调度算法分为两类:
1近似的次优调度算法:和最优调度使用相同的算法但解空间较小
2启发式的次优调度算法:使用比较简明的规则和一些直觉的规则来进行调度,如程序局部性原理
下面都是静态调度:

任务聚类的粒度:一个给定任务聚类的粒度被定义为任务的计算量与通信量的比值(比值大的是粗粒度,比值小的是细粒度)。
如果粒度太大(意味着计算量大,许多任务会被分派到同一节点而增大计算量,同时减小各节点之间通信开销),就会限制并行性,因为潜在的并行小任务可能被聚类进同一个大任务而分配给一个处理器。粒度太小(意味着通信量大),进程切换和通信的开销就会增加,从而降低性能。
常见聚类算法
1关键路径聚类
2消除通信延迟的聚类
3任务复制


优先图粒度
任何非线性聚类可以被转换成具有更少或相等执行时间的线性聚类。注意,上面的结论暗示了一个粗粒度程序的线性聚类性能优于任何非线性聚类。然而,对细粒度程序而言,可能存在也可能不存在一个非线性聚类优于线性聚类。



两种最优调度算法
两种方法都假设通信代价可以忽略,优先图中每个节点的执行时间是一样的,即一个时间单元。具体限制如下:
在第一个有约束的调度问题中,优先图是一棵树。
在第二个有约束的调度问题中,只有两个处理器可用。
情况1:优先图为一棵树


情况2:只有两个处理器可用

下面都是动态调度:
动态调度算法有六个策略:启动策略、转移策略、选择策略、收益性策略、定位策略和信息策略。
动态负载平衡算法:非抢先式又称为任务放置,抢先式又称为进程迁移
区别于
进程转移的形式:非抢先方式又称为进程放置,抢先方式又称为进程迁移
进程转移的主要目的:使由个人工作站组成的系统的计算资源容易共享,用户在执行若干相对独立的任务时,可把它们从某些重负载工作站移到另外一些轻负载工作站上加快完成。
进程转移和远程执行的一般要求(进程转移的依据):
1透明性。进程运行的结果与该进程在系统中什么地方执行无关。
2有效性。迁移一个进程需要时间,支持该进程远程执行也需要时间,这些时间应尽量短。
集中式调度:系统中有一个中央调度服务员,负责搜集状态信息并做出全部调度决策。各机器周期性地向它发送状态更新报文,报告它们的负载信息;顾客向它发送远程执行请求。中央调度服务员根据负载情况,建立一个主机候选者的有序表,依次选择主机,对顾客的远程执行请求进行响应。
分散式调度:每个机器自己进行选择活动。它必须①不断地记录整个系统状态或者②当需要时查询系统状态信息。
混合式调度
混合式调度:每个工作站有一个局部调度程序,还有一个后台作业队列,用户提交的作业和远程作业都放到此队列中。有一个工作站除了局部调度程序和作业队列外,还有一个协调程序(协调者)。协调者为有后台作业等候的工作站上的调度程序分配空闲工作站资源,之后各工作站如果其队列中有多个后台作业,则由本地调度执行程序决定下次应执行哪个作业。
Sprite系统的进程迁移:
1向目的节点发送一个RPC,确认是否允许迁移该进程。
2当要迁移该进程时,使用标准信号中断该进程的执行。
3传送该进程的“进程状态”,包括各寄存器的内容、用户标识符和小组标识符、信号处理信息、基地节点和该进程标识符。
4传送虚拟地址空间(可能还用到了虚拟存储)。把所有重写的页送到文件服务器,把对应的交换文件的页表和说明符送到目的节点。
5将该进程已打开的文件的说明符和当前工作目录打包并传送。
6发送一个RPC结束迁移,允许被迁移的进程在目的节点上恢复执行。
7最后,该进程在目的节点上恢复。
十、分布式共享存储器
与紧密耦合的多机系统相比,DSM系统具有以下特点:
1规模可扩充。在紧密耦合的多机系统中,由于各处理机共享的是一个单一的物理存储器,主存访问都要经过一个集中环节(例如总线)进行,这就限制了多机系统的规模(一般为几十台处理机)。DSM不存在这样的限制,可以扩充至很大的规模(多至上千个节点)(扩充共享存储器只需要不断往里面加入新的物理上的存储器节点即可,就可以在逻辑上无限扩充)。
2廉价。由于DSM系统可以用现有的硬件来构造,并且无需连接共享存储器与处理机的复杂接口,因而DSM的构造成本要低于紧密耦合的多机系统。
3兼容性。在共享存储器多机系统上编写的程序原则上都可以无需修改或稍加修改后转换到DSM系统上运行。
与松散耦合的多机系统相比,DSM和使用报文传递的松散耦合系统在通信方式上的区别:
1访问的透明性。使用报文传递方式访问共享的数据变量时,程序必须明确地使用节点地址信息和通信原语(如SEND和RECEIVE)。而在DSM中系统提供了一种抽象的共享地址空间从而隐匿了物理地址和通信细节,使得程序直接面向共享的数据。
2共享数据结构的复杂性和异构性。使用报文传递方式,由于数据是在不同的地址空间之间传递,从而使得具有复杂数据结构的数据难于在不同类型的计算机及进程之间传递。而在DSM中,可以借助引用机制(reference)去实现上述数据访问,复杂性与异构性的问题由引用机制去处理,从而进一步简化了并行程序设计(多进程和多线程)。
3数据的局部性。在DSM中,新访问的数据项与其周围的数据一起按块或按页移动,而不是只移动新访问的数据本身。根据程序的局部性原理,这样可以大大地减小网络的通信开销。
分布式共享存储器两类基本方法实现缓存一致性:即探听缓存方法和使用目录的方法。
Berkeley探听协议数据块有四种状态:重写(dirty)、共享重写、有效和无效:

实现DSM的算法 :

1、中央服务员算法 (不允许迁移,不允许复制):中央服务员管理数据,所有请求被发给他,并且由他处理
2、迁移算法(允许迁移,不允许复制):只有一个副本,该副本一直在被传递到需要读写它的节点
3、全复制算法(不允许迁移,允许复制):写操作→都得全局排序
读操作→若与“发生在执行读操作节点上的写操作”有关→进行全局排序
4、读复制算法 (允许迁移,允许复制) :读远程块→请求远程节点给我一个只读副本,再读
写远程块/无本地块写权限→先无效所有其他人手上该块副本,再写
目录协议有三种主要类型:全映像目录、有限目录和链式目录
全映象目录怎么写:

链式目录替换方法

1万+

被折叠的 条评论
为什么被折叠?



