第一章:分布式系统的特征
-
为什么需要分布式系统:资源共享、协同计算。
-
定义:分布式系统是这样一种系统,其中位于联网计算机上的组件仅通过传递消息来通信和协调它们的操作。
-
特点:
- 并发性:多个程序(进程,线程)并发执行,共享资源
- 无全局时钟:每个机器有各自的时间,难以精确同步,程序间的协调靠交换消息
- 故障独立性:一些进程出现故障,并不能保证其它进程都能知道
-
分布式系统举例:WEB 搜索、大型多人在线游戏、金融交易、区块链系统、语音系统、数据库系统
-
分布式系统趋势:
- 泛在联网与现代互联网
- 移动与无处不在的计算
- 分布式多媒体系统
- 将分布式计算作为公共设施
-
中间件:应用到软件层,用来屏蔽底层的异构性。
-
挑战:透明性、异构性、并发、开放性、安全性、可伸缩性、故障处理
第二章:系统模型
-
系统的体系结构:用独立指定的组件以及这些组件之间的关系来表示的结构。
-
整体目标:确保结构能满足现在和将来可能的需求。
-
体系结构元素:
- 通讯实体:(进程、线程、节点)(对象、组件、web服务
- 通信泛型:进程间通信(套接字、多播、消息传递),远程调用(请求-应答协议、RPC、PMI)
-
体系结构模式:构建在相对原始的体系结构元素之上,提供组合的、重复出现的结构。
- 分层体系结构:一个复杂的系统被分成若干层。每层利用下层提供的服务。中间件是一种软件,它提供基本的通信模块和其他一些基础服务模块,为应用程序开发提供平台。
- 层次化体系结构:层次化是一种从应用角度理解系统的体系结构模式,与分层体系结构互补,是一项组织给定层功能的技术。
- 瘦客户:本地只是一个 GUI ,应用程序在远程计算机上执行。
-
基础模型:对体系结构模型中公共属性的一种更为形式化的描述。
- 交互模型:用来描述延迟的不确定性与缺乏全局时钟的影响。被用来处理消息发送的通讯性能问题,解决在分布式系统中设置时间限制的难题。
- 故障模型:组件、网络等故障的定义、分类,试图给出进程和信道故障的一个精确的约定。定义了什么是可靠通信和正确的进程 。
- 遗漏故障:进程或者通信通道没有正常的工作(进程崩溃、丢失信息)
- 随机故障:对系统影响最大的一种故障,且错误很难探知。
- 时序故障:仅发生在同步分布式系统中
- 安全模型:提供依据,以此分析系统可能收到的侵害,并在设计系统时防止这些侵害的发生。(进程、通信信道、对象)威胁:DoS攻击、移动代码。对策:加密技术与共享密钥、认证、安全通道
第三章:时间与全局状态
-
事件:一个通信动作或进程状态转换动作。
-
进程历史:在进程中发生的一系列事件,按发生在先排序,即
history(pi)=<ei0,ei1,ei2,...>history(p_i)=<e_i^0,e_i^1,e_i^2,...>history(pi)=<ei0,ei1,ei2,...> -
时钟漂移:震荡频率变化(电源稳定性、环境温度)
-
同步物理时钟:
- 外部时钟:采用权威的外部时间源。
- 内部时钟:无外部权威时间源,系统内时钟同步。
- 关系:若P(时钟集合)在范围D内外部同步,则P在范围2D内内部同步。
- 时钟正确性含义:
- 基于漂移率——漂移率在一个已知的范围内;
- 基于单调性——t′>t→C(t′)>C(t)t'>t→C(t')>C(t)t′>t→C(t′)>C(t)
- 基于混合条件——单调性+漂移率有界+同步点跳跃前进
- 物理时间同步的三种方法:
- Cristian方法:应用条件:存在时间服务器,作为外部时间源消息;往返时间与系统所要求的精度相比足够短。协议:进程P根据消息mrm_rmr,mtm_tmt计算消息往返时间TroundTroundTround根据服务器在mtm_tmt中放置的时间ttt设置时钟为:t+Tround/2t+Tround/2t+Tround/2。精度:±(Tround/2–min)±(Tround/2 – min)±(Tround/2–min)。
- Berkeley方法:主机周期轮询从属机时间,主机通过消息往返时间估算从属机的时间,主机计算容错平均值,主机发送每个从属机的调整量。
- NTP:外部同步,高可靠性,拓展性好,安全性强。
-
逻辑时间和逻辑时钟:
- 逻辑时间的引入:节点具有独立时钟,缺乏全局时钟,分布式系统中的物理时钟无法完美同步,事件排序是众多分布式算法的基石。
- 逻辑时钟:众多应用只要求所有节点具有相同时间基准,该时间不一定与物理时间相同。不进行交互的两个进程之间不需要时钟同步。
- 发生在先(偏序):
- 若存在进程PiP_iPi满足e→ie′e→_ie'e→ie′,则e→e′e→e'e→e′
- 对于任一消息mmm,存在send(m)→recv(m)send(m)→recv(m)send(m)→recv(m)
- 若事件满足e→e′e→e'e→e′和e′→e′′e'→e''e′→e′′,则e→e′′e→e''e→e′′
- 并发(X||Y):XY与YX均不成立,则称事件X、Y是并发的。
- Lamport时钟:Lamport 发明的一种简单机制,可以数字化发生在先排序。它规定每个进程维护自己的逻辑时钟(一个单调增长的计数器),进程PiP_iPi用它给事件加上Lamport时间戳LiL_iLi。若进程触发了某个事件,则将该事件标注时间戳为(Li+1)(L_i+1)(Li+1);发送消息时,在消息中附带t=Lit=Lit=Li;接收进程接收消息事件被标注时间戳为max(Lj,t)max(L_j,t)max(Lj,t)。
- 向量时钟与Lamport时钟的区别:在PiP_iPi给事件加时间戳之前,设置Vi[i]=Vi[i]+1V_i[i]=V_i[i]+1Vi[i]=Vi[i]+1。克服了Lamport时钟的缺点:L(e)<L(e′)L(e)<L(e')L(e)<L(e′)不能推出e→e′e→e'e→e′。
- 全局状态:单个进程状态的集合;
S=(s1,s2,...,sN)S=(s_1,s_2,...,s_N)S=(s1,s2,...,sN) - 割集:系统全局历史的子集(部分事件的集合,有序)。
C=<h1c1,h2c2,...,hncn>C=<h_1^{c1},h_2^{c2},...,h_n^{cn}>C=<h1c1,h2c2,...,hncn> - 割集的一致性:割集C是一致的,即对于任意事件e∈C,f→e⟺f∈Ce∈C,f→e⟺f∈Ce∈C,f→e⟺f∈C,即有果必有因。
- 一致的全局状态:对应于一致割集(增量序列)的状态 S0→S1→S2→…S0→S1→S2→…S0→S1→S2→…(系统的执行可以描述成系统全局状态之间的一系列转换)。
- Chandy和Lamport的“快照”算法:为了捕获一致的全局状态(在缺乏类似全局时钟或者全局时钟不可靠的分布式系统中来确定一种全局状态)。算法定义了两个规则:标记发送规则和标记接收规则。前者强制记录下自己状态的进程立即发送一个标记信息,后者强制没有记录状态的进程去记录自己的状态。

第四章:协调和协定
-
分布式互斥:分布式进程常常需要协调它们的动作,如访问共享资源时需要互斥来防止干扰并保证一致性,这对应操作系统领域常见的“临界区”问题。然而分布式系统中原有互斥方法基本均失效,需要一个仅基于消息传递的分布式互斥解决方案。
-
目的:仅基于消息投递,实现对资源的互斥访问。
-
假设:异步系统;无故障进程;可靠的消息投递。
-
基本要求:
- 安全性:在临界区内一次最多有一个进程可以执行。
- 活性:进入和离开临界区的请求最终成功执行。
- 顺序:先请求进入临界区的进程先进入临界区
-
评价指标:
- 带宽:消耗的带宽,与进入和退出临界区发送消息的数量成正比。
- 延迟:每次进入和退出操作导致的客户延迟。
- 吞吐量:用一个进程离开临界区和下一个进程进入临界区之间的同步延迟来衡量。
-
中央服务器算法:满足安全性和活性要求,但不满足顺序要求。

- 带宽消耗:
- enter:2个消息,即请求消息+授权消息
- exit: 1个消息,即释放消息;
- 客户延迟:
- enter: request + grant = 1 round-trip
- exit: release ;
- 同步延迟:
- 1个消息的往返时间:1 release + 1 grant。
- 带宽消耗:
-
基于环的算法:所有程序构成一个环结构,令牌按照顺时针(或逆时针)方向在程序之间传递,收到令牌的程序有权访问临界资源,访问完成后将令牌传送到下一个程序;若该程序不需要访问临界资源,则直接把令牌传送给下一个程序。在分布式领域,这个算法叫作令牌环算法,也可以叫作基于环的算法。

- 满足安全性和活性要求,不满足顺序要求。
- 带宽消耗:由于令牌的投递,会持续消耗带宽;
- 客户延迟(enter):
- Min: 0个消息,正好收到令牌;
- Max: N个消息,刚刚投递了令牌;
- 同步延迟:
- Min: 1个消息,进程依次进入临界区;
- Max: N个消息,一个进程连续进入临界区,期间无其他进程进入临界区。
-
基于组播和逻辑时钟的算法:进程进入临界区需要所有其它进程的同意。要进入临界区的进程组播一个请求消息,并且只有在其他进程都回答了这个消息时才能进入。采用Lamport时间戳避免死锁,请求进入的消息形如<T,Pi><T,P_i><T,Pi>,如果请求具有相等的时间戳,那么请求将根据进程的标识符排序。

- 满足安全性、活性和顺序要求。
- 带宽消耗:
- enter: 2(N-1),即(N-1)个请求、 (N-1)个应答。
- 客户延迟:1 round-trip (multicast);
- 同步延迟:1个消息的传输时间(无exit,vs round-trip)。
-
Maekawa投票算法:进程进入临界区不需要所有进程同意(部分即可)
- 满足安全性,活性和顺序性。
- 带宽消耗:
- enter:需要2n2\sqrt{n}2n个消息
- exit:需要n\sqrt{n}n个消息
- Ricard:2(N-1)
- 客户延迟:1 round-trip
- 同步延迟:1 round-trip
-
-
分布式选举:选择一个唯一的进程来扮演特定角色的算法。
-
含义:集群一般是由两个或者两个以上的服务器组建而成,每个服务器都是一个节点。对于一个集群来说,多个节点到底是怎么协调,怎么管理的呢,解决方法是选出一个“领导”来复杂调度和管理其他节点。这个所谓的“领导”,在分布式中叫做“主节点”,而选“领导”的过程叫做“分布式选举”。
-
基本要求:
- 安全性:参与进程PiP_iPi的electedi=⊥elected_i=⊥electedi=⊥或electedi=Pelected_i=Pelectedi=P(有效进程 pid最大值)。
- 活性:所有进程PiP_iPi都参加并且最终置electedi≠⊥elected_i≠⊥electedi=⊥或进程PiP_iPi崩溃。
-
基于环的选举算法:
- 目的:在异步系统中选举具有 最大标识符 的进程作为协调者。
- 基本思想:按逻辑环排列一组进程, id 不必有序。
- 性能
- 最坏情况:启动选举算法的逆时针邻居具有最大标识符,共计需要3N-1个消息,周转时间为3N-1
- 最好情况:周转时间为2N

-
霸道算法:
- 同步系统,使用超时检测进程故障。
- 通道可靠,但允许进程崩溃。
- 每个进程知道哪些进程具有更大的标识符
- 每个进程均可以和所有其它进程通信
- 性能:
- best:N−2N-2N−2
- worst:N2N^2N2

-
-
组播通讯:发送一个消息给进程组中的每个进程。
-
基本组播:B-multicast(g, m):对每个进程p∈g,send(p, m);进程p receive(m)时:p执行B-deliver(m)。

-
可靠组播:
- 协定:如果一个正确的进程投递消息m,那么group中其它正确的进程终将投递m。
- 区别:基本组播只将消息发送给每个进程,而可靠组播保证了消息的完整性、有效性与协定。

-
实现可靠组播的方法:协定表明了 B-Multicast 不能再基于一对一的send来实现,因为组播进程在send中途出现故障时,会导致剩余进程无法Deliver该消息。可行方案如下:
- 用基本组播实现可靠组播:满足完整性,满足有效性,满足协定,但是效率低。

- 用IP组播实现可靠组播:将IP组播、捎带确认法、否定确认结合起来,实现可靠的Multicast和Deliver。
-
-
共识、交互一致性及拜占庭将军问题含义:这三类问题统称为协定,即在一个或多个进程提议了一个值应当是什么后,使系统内所有进程对这个值达成一致的意见。
- 共识问题:一个或多个进程提议一个值后,应达成一致意见。
- 基本要求:
- 终止性:每个正确的进程最终设置它的决定变量。
- 协定性:如果PiP_iPi和PjP_jPj是正确的且已进入决定状态,那么di=djd_i=d_jdi=dj。
- 完整性:如果正确的进程都提议了同一个值,那么处于决定状态的任何正确进程都已选择该值。
- 共识算法:每个进程组播它的提议值;每个进程收集其它进程的提议值每个进程计算V=majority(v1,v2,…,vN)V = majority(v_1, v_2, …, v_N)V=majority(v1,v2,…,vN)。其中majority()majority()majority()函数为抽象函数,可以是max()max()max()、min()min()min()等。
- 基本要求:
- 拜占庭将军问题:3个或更多将军协商是进攻还是撤退;1个将军(司令)发布命令,其他将军(中尉)决定进攻或撤退;一个或多个将军可能会叛变;所有未叛变的将军执行相同的命令 。
- 拜占庭将军问题要求:
- 终止性:每个正确进程最终设置它的决定变量。
- 协定性:所有正确进程的决定值都相同。
- 完整性:若司令正确,则所有正确进程采用司令提议的值。
- 与共识问题的区别:一个独立的进程提供一个值,其他进程决定是否采用。
- 拜占庭将军问题要求:
- 交互一致性:每个进程提议一个值,就向量达成一致。决定向量: 向量中的每个分量与一个进程的值对应。
- 交互一致性的要求:
- 终止性:每个正确进程最终设置它的决定变量。
- 协定性:所有正确进程的决定向量都相同。
- 完整性:如果进程pi是正确的,那么所有正确的进程都把vi作为他们决定向量中第i个分量。
- 交互一致性的要求:
- 共识问题:一个或多个进程提议一个值后,应达成一致意见。
第五章:事务和并发控制
- 事务:由客户定义的针对服务器对象的一组操作(操作序列),它们组成一个不可分割的单元,由服务器执行。
- 事务的目标:在多个事务访问对象以及服务器面临故障的情况下,保证所有由服务器管理的对象始终保持一个一致的状态。
- 事物的特征:
- 持久性:一旦事务完成,它的所有效果将被保存到持久存储中,文件中的数据不受服务器崩溃的影响持久性。
- 一致性:事务将系统从一个一致性状态转换到另一个一致性状态。
- 原子性:事务的数据就修改操作要么全部执行,要么全部不执行。
- 隔离性:事务执行过程中的中间效果对其它事务不可见。
- 串行等价性的概念、充要条件及应用
-
串行等价:如果并发事务交错执行操作的效果等同于按某种次序 一次执行一个事务的效果,那么这种交错执行是一种串行等价的交错执行。
-
使用串行等价作为并发执行的判断标准,可防止更新丢失和不一致检索问题。
-
冲突操作:如果两个操作的执行效果和他们的执行次序相关,称这两个操作相互冲突。

-
串行等价的充要条件:两个事务中所有的冲突操作都按相同的次序在它们访问的对象上执行。
-
- 事务的三种基本控制方法:锁、乐观方法、时间戳,它们的原理、实现、比较
-
锁:
-
两阶段加锁:每个事务的第一阶段是一个“增长”阶段,事务不断地获取新锁;在第二个阶段,事务释放它的锁(“收缩阶段”)。考虑的问题是如果并发控制不事先将所有需要的锁申请好,而是释放锁后还允许再次申请,很有可能导致事务之间出现死锁。
-
严格的两阶段加锁:所有在事务执行过程中获取的新锁必须在事务提交或放弃后才能释放。目的是防止事务放弃导致的脏数据读取、过早写入等问题。

-
死锁:死锁是一种状态,在该状态下一组事务中的每一个事务都在等待其它事务释放某个锁。
-
锁超时:每个锁都有一个时间期限,超过时间期限的锁成为可剥夺锁。如果没有其它事务竞争被锁住的对象,那么具有可剥夺锁的对象会被继续锁住;一旦有一个事务正在等待可剥夺锁保护的对象,这个锁将被等待事务剥夺(对象被解锁)。
-
锁机制的缺点:维护开销大;会引起死锁;并发度低。
-
-
乐观并发控制:
-
其假设大多数事务可以在互不干扰的情况下完成。当事务运行时,事务不需要申请资源的锁,便可以使用这些资源。OCC通过维护本地数据集,并在验证阶段检查是否存在冲突,若存在冲突则回滚。所以通常用于低数据争夺的场景。
-
当冲突较少时事务的完成将会没有管理锁的消耗,并且不需要令事务等待其他的事务锁释放,相比基于悲观锁的并发控制,具有更好的并发效率。然而,如果数据资源争夺较为频繁,反复回滚和重启事务的花费将会极大地降低性能,通常认为在这种情况下,其他并发控制方法拥有更好的性能。
-
OCC事务验证:每个事务在进入验证阶段前(执行 closeTransaction 时)被赋予一个事务号,有如下两种验证方式
-
向后验证:检查当前事务和其它较早的重叠事务之间的冲突,即当前事务的读集和其它事务的写集是否冲突。(即当前事务要读之前事务写的内容)。如果失败则放弃当前进行验证的事务。


-
向前验证:检查当前事务和其它较晚的重叠事务之间的冲突,即当前事务的写集和其它事务的读集是否冲突(当前事务要写的内容可能被之后事务读到)。向前验证的验证阶段不允许启动新事物。


-
-
区别:
- 向前验证处理冲突的方式更加灵活,向后验证只能放弃当前事务;
- 向后验证将 较大的读集合 和较早事务的写集合进行比较;
- 向前验证将 较小的写集合 和活动事务的读集合进行比较;
- 向后验证要保存其早期事务的写集和,需要额外开销;
- 向前验证不允许在验证过程中开始新的事务。
-
-
时间戳:
- 基本思路:事务中的每个操作在执行前先进行验证,如果验证不通过则事务被立即废弃。
- 定义:每个事务在启动时被赋予一个唯一的时间戳,时间戳定义了该事务在事务时间序列中的位置。
- 冲突规则:
- 只有当对象上的最后一次读/写操作是由一个较早的事务执行的,当前事务对该对象的写操作才是有效的
- 只有在对象上的最后一次写操作是由一个较早的事务执行的,当前事务对该对象的读操作才是有效的

-
并发控制方法的比较:
- 两阶段加锁——事务执行中
- 乐观并发控制——事务执行后
- 时间戳排序——事务执行前

-
第六章:分布式事务
-
分布式事务:
- 分布式事务:访问由多个服务器管理的对象(事务在多个节点上更新数据)的平面事务或嵌套事务。
- 平面事务:所有事务参与者都位于同一个平面,可以直接通信而不需要事务管理器或协调者,客户给多个服务器发送请求。一个平面客户事务完成一个请求后才发起下一个请求。因此,每个事务顺序访问服务器上的对象。当服务器使用加锁机制时,事务一次只等待一个对象。
- 嵌套事务:顶层事务可以创建子事务,子事务可以进一步以任意深度嵌套子事务。同一层的子任务可以并发执行。
-
原子提交协议:
- 当一个分布式事务结束时,事务的原子特性要求所有参与该事务的服务器必须全部提交或全部放弃该事务。
- 原子提交协议允许服务器之间相互通信,以便共同决定提交或放弃。

-
单阶段原子提交协议:
- 概念:协调者向事务所有的参与者发送Commit或者Abort请求;协调者不断地发送请求直至所有参与者都确认。
- 缺陷:
- 不允许参与者单方面决定放弃事务。
- 可能有一些并发控制问题(死锁、乐观并发控制验证失败、崩溃)会阻止参与者提交,协调者可能不知道这种变化。
-
两阶段提交协议:(设计动机、基本思想、基本操作、过程描述、通信、性能、缺陷)
-
设计动机:允许任意一个参与者自行放弃他自己的那部分事务。
-
基本思想:

-
基本操作:



-
失效情况:
- 参与者与协调者崩溃:通过事务恢复来保证服务器上对象的持久性并保证服务提供故障原子性。
- 消息丢失:
- canCommit:超时后参与者可能会决定单方面放弃(协调者最终会放弃)
- Yes/No:协调者在超时后放弃事务(悲观)。它必须向那些投票者宣布 doAbort。
- doCommit:参与者可以等待超时,发送 getDecision 请求(重试直到收到答复) 在投票“ Yes ”之后但在接收 doCommit/doAbort之前无法放弃!
-
两阶段提交协议的恢复:
- 意图列表:两阶段提交协议使用意图列表记录该服务器上的所有服务事务用来记录该服务器上的所有活动事务,每个事务的意图列表都记录了该事务修改的对象的值和引用列表 <ObjectID,Pi>。
- 日志:恢复文件包含该服务器执行的所有事务的历史,历史由对象值、事务状态和意图列表组成。

-
两阶段提交协议的性能:
- 无服务器崩溃、通信异常等情况下:N×canCommit+N×Yes/No+N×doCommit。
- 最坏情况下,可能出现任意多次服务器和通信异常。
- 可能造成参与者长时间处于“不确定”状态。
-
两阶段提交协议的问题:
- 同步阻塞:在投票Yes与doCommit之间,所有参与者处于阻塞状态无法进行其他任何操作。若协调者在发起提议后崩溃,那么投Yes票的参与者阻塞至协调者恢复后发送决议。
- 单点故障:协调者存在性能瓶颈及单点失效问题。
- 数据不一致:doCommit发送过程中发生了局部网络异常或协调者自身崩溃,则部分参与者不提交事务,造成数据不一致。
-
-
分布式死锁产生原因及检测方法(集中、分布式)
- 产生原因:在分布式事务中,某个对象的锁总是本地持有的,原子提交协议进行时对象始终被锁住,其它事务不能访问这些对象。由于不同服务器上的锁管理器独立设置对象锁,所以对不同的事务,它们的加锁次序可能不一致。这种不同的事务次序导致事务间循环依赖,从而引起分布式死锁。
- 检测方法:
- 集中式:其中的一个服务器担任全局死锁检测器,全局死锁检测器收集局部等待图构造全局等待图,一旦发现环路,通知各服务器放弃相应事务解除死锁。(可靠性差、缺乏容错、无可伸缩性、收集代价高)
- 分布式:无需构建全局等待图,服务器通过转发探询(Probe)消息发现环路。


第七章:复制
-
复制:
- 在多个节点上保存相同数据的一个副本。一个拥有数据拷贝的节点称为副本管理器。
- 复制的动机——容错:如果一些副本不能被访问(异常、更新),另外一些仍能够被访问。
- 可用性:在合理的响应时间内获得服务的次数所占比例应该接近100%。
- 正确性:允许一定数量和类型的故障。
- 复制的需求:数据在同一个域中的多个服务器之间进行资源缓存和透明复制。
- 透明性:客户不需要知道存在多个物理副本。
- 一致性:不同应用一致性强度有所不同。
- 复制的系统模型:

- 前端:接收客户请求,通过消息传递与多个副本管理器进行通信。
- 为了保证复制的透明性,不让客户直接进行通信,而是通过前端通信。
- 副本管理器:接收前端请求。为了保证复制的一致性,副本管理器对副本执行原子性操作,其执行等价于以某种严格顺序执行。
- 副本操作:
- 请求:前端将请求发送至一个或多个副本管理器。方式一是前端和某个副本管理器通信,此管理器再和其它副本管理器通信,方式二是前端将请求组播到各个副本管理器。
- 协调:保证执行的一致性,对不同请求进行排序。
- 执行:副本管理器执行请求,包括试探性执行,即执行效果可以去除。
- 协定:对于要提交的请求的执行结果达成一致,副本管理器可共同决定放弃或者提交事务。
- 响应:根据应用需要,一个或多个副本管理器响应前端
- 单拷贝串行化的概念、“读一个/写所有”方案原理、适用条件及本地验证方法
-
客户在复制对象上执行的事务的效果应该与它们在一个对象集上逐一执行相同。(即每个对象 1 个副本)
-
“读一个/写所有”:单拷贝串行化可以通过“读一个/写所有”实现复制方案。Read请求可以由单个副本管理器执行,Write 请求必须由组中所有副本管理器执行。

-
适用条件:
- 读一个/写所有在副本管理器崩溃或者通讯故障时不是一个现实的方案(无法写所有)
- 可用副本复制方案允许某些副本管理器暂时不可用。
-
本地验证:确保任何故障或恢复不会在事务执行中发生。事务提交前检查已访问的副本管理器集是否变化(故障和恢复)
-
- 闲聊系统的两个保证、体系结构(含关键数据结构)及基本操作:
- Gossip算法又被称为反熵(Anti-Entropy),熵是物理学上的一个概念,代表杂乱无章,而反熵就是在杂乱无章中寻求一致。
- 特点:在一个有界网络中,每个节点都随机地与其他节点通信,经过一番杂乱无章的通信,最终所有节点的状态都会达成一致。每个节点可能知道所有其他节点,也可能仅知道几个邻居节点,只要这些节点可以通过网络连通,最终他们的状态都是一致的。
- 体系结构:
-
前端可以选择副本管理器(可用且响应时间合理)
-
提供两种基本操作:查询+更新
-
副本管理器定期通过gossip消息来传递客户的更新

-
前端的版本时间戳:
- 为了控制操作处理次序,每个前端维持了一个向量时间戳,用来反映前端访问的最新数据值的版本。
- 将其放入每一个请求中,与更新或者查询操作的描述一起发送给副本管理器。
- 前端也可以将时间戳直接发送给其他的前端。
-
两个保证:
- 随着时间的推移,每个用户总能获得一致服务.
- 副本之间松弛的一致性.
-
第八章:分布式文件系统
- 分布式文件系统的需求:
- 透明性:
- 访问透明性:客户无需了解文件分布性,通过一组文件操作访问本地/远程文件。需要支持相同的一组文件操作,程序要如同本地文件系统一样在分布式文件系统上工作。
- 位置透明性:客户使用单一的文件命名空间。路径不变,多个文件应该可重定位。所有用户看到同样的命名空间。
- 移动透明性:当文件移动时,客户的系统管理表不必修改。如果文件移动到另一个服务器,不应该让用户可见。
- 性能透明性:负载在一个特定范围内变化时,性能可接受。系统提供合理的一致性能。
- 伸缩透明性:文件服务可扩充,以满足负载和网络规模增长的需要。系统可以通过增加服务器逐步扩展。
- 并发的文件更新:并发控制,客户改变文件操作不影响其他客户。
- 文件复制:分担文件服务负载,更好的性能和系统容错能力。
- 硬件和操作系统的异构性:接口定义明确,在不同操作系统和计算机上实现同样服务。
- 容错:为了处理瞬时通信故障,设计可以基于最多一次的调用语义。
- 幂等操作:支持最少一次语义,重复执行的效果与执行一次的相同。
- 无状态服务器:在崩溃后无恢复重启。
- 一致性:单个拷贝更新语义,多个进程并发访问或修改文件时,它们只看到仅有一个文件拷贝存在。
- 安全性:客户请求需要认证,访问控制基于正确的用户身份。
- 效率:性能满足一定要求。
- 文件服务体系结构
-
服务器——目录服务、平面文件服务;客户端——客户模块

-
作用:
- 平面文件服务:对文件内容进行操作,提供唯一的文件标识(UFID)
- 目录服务:提供文件名到 UFID 的映射
- 客户端模块:提供应用程序对远程文件服务透明存取的支持,如对目录的迭代请求,缓存文件
-
接口:
- Lookup 操作执行 Name 到 UFID 的转换
- Read(FieId, StartIndex, Length)
- Write(FieId, StartIndex, Data)
- Create():生成长度为 0 的新文件,并为其指定 UFID
- Delete(FieId)
- GetAttributes(FieId)
- SetAttributes(FieId, Attr)
-
设计理念:
- 除了 Create,其它所有的操作都是幂等的
- 无状态服务器设计
- 通过指定下标,设计更加通用的接口
- 不提供打开关闭文件接口,简化设计
-
- NFS
-
为运行在 Unix 和其它系统上的客户程序,提供对远程文件的透明访问。采用对等的客户-服务器体系,即一台机器既可以作为服务器输出自己的文件,也可以作为客户端访问其它机器的文件。但在实际应用中,通常会将某些配置较高的机器作为专用服务器,其它机器作为工作站(客户端)。

-
虚拟文件系统(VFS):在UNIX内核的一个转换层,使文件系统可以插入与共存。VFS跟踪本地和远程可用的文件系统。将请求传递到适当的本地或远程文件系统。区分本地和远程文件。
-
客户集成:将客户端集成到内核,用户可以通过UNIX系统调用访问文件。一个客户模块通过使用一个共享缓存存储最近使用的文件块,为所有的用户级进程服务。用于认证用户 ID 的密钥可以由内核保存,防止用户级客户冒用客户。
-
访问控制与认证:NFS服务器是无状态的,在用户发出每一个新的文件请求时,服务器必须重新比对用户ID与文件访问许可属性,判断是否允许用户进行访问。(Kerberos认证)
-
安装服务:
- 服务器:每一个服务器上都一个具有已知名字的文件(/etc/exports)—— 包含了本地文件系统中可被远程加载的文件名程加载的文件名。
- 客户:使用mount命令请求安装远程文件集系统。
-
路径解析:NFS 服务器不进行路径名转换,需要由客户以交互方式完成路径名的翻译。客户向远程服务器提交多个 lookup 请求,将指向远程安装目录的名字的每一部分转换为文件句柄。
-
缓存机制:
- 服务器缓存:预先读,将最近常用的页面装入内存;写操作有两种选择,写透——在给客户发送应答前将应答写入磁盘;写透,但只在close()——当系统接收到相关文件的commit操作(用于写而打开的文件关闭时)写入磁盘。
- 客户缓存:为了减少传输给服务器的请求数量,NFS客户模块将 read, write, getattr, lookup 和 readdir 操作的结果缓存起来。保持一致性。基于时间戳的缓存块验证。
-
- AFS
-
应用场景:
- 客户机请求打开一个本地缓存不存在的文件,AFS 查找后向客户机传输此文件副本
- 传输后的文件在本地 Unix 文件系统中被打开,文件描述符返回给客户程序
- 客户机进程在本地文件上执行一系列修改操作,在本地文件关闭时,会自动将该修改后的文件传回服务器,服务器更新文件内容和时间戳
- 本地文件则一直被保留,供同一个机器上的其他用户进程使用

-
设计理念:
- 可以使用正常的 Unix 文件原语来访问 AFS 文件,即不需要修改原有 Unix 程序
- 可伸缩性,用以满足更多活动用户的使用需求,其关键是在客户机上缓存整个文件
- 整体文件服务:将整个文件和目录的内容都传输到客户机
- 整体文件缓存:当一个文件或文件块拷贝到被传输的客户机上时,它会存储到本地磁盘缓存中
- 缓存:
- 每个工作站本地磁盘上都有一个文件分区被用作文件的缓存,保存共享空间中的文件拷贝,Venus 进程管理这一缓存;
- 当文件分区已满,并且有新的文件需要从服务器拷贝过来时,它将最近最少使用的文件从缓存中删除;
- 缓存都足够大,当客户缓存已经包含了当前用户文件和经常使用的系统文件时,工作站可以基本独立于 Vice 服务器工作
- 缓存一致性:
- 回调承诺:由管理该文件的 Vice 服务器发送的一种标识,用于保证当其他客户修改此文件时通知 Venus 进程。状态分为有效和取消。当 Vice 服务器执行一个更新文件请求时,它通知所有 Venus进程将回调承诺标识设为取消状态。
- 目标:在不对性能产生严重影响的情况下,近似实现对单个文件拷贝语义。
-
第九章:谷歌文件系统GFS
-
GFS:
-
设计动机:
- 组件失效被认为是常态事件,而不是意外事件。
- 以通常的标准衡量,文件非常巨大。
- 绝大部分文件的修改是采用在文件尾部追加数据,而不是覆盖原有数据的方式。
- 应用程序和文件系统的协同设计以提高整个系统的灵活性。
-
设计思想:
- 文件以数据块(Chunk)的形式存储。数据块的大小固定,每个数据块拥有句柄。
- 利用副本技术保证可靠性。每个数据块至少在三个ChunkServer上保存副本,每个数据库做为本地文件保存在Linux文件系统中。
- Master维护所有文件系统的 元数据(mateData)。每个GFS簇只有一个Master,Master利用周期性的心跳信息向Chunkserver发生命令和收集状态。
- Master 服务器在不同的数据文件里保持元数据 。数据以64MB为单位存储在文件系统中。 Client 与 Master 服务器通讯在文件上做元数据操作并且找到包含用户需要的数据。

-
缓存:无论是 Client 还是 Chunkserver 都不需要缓存文件数据(不过, Client 会缓存元数据)。
-
体系结构:

-
-
Master不存在性能瓶颈原因:

-
操作流程
- 读操作:
- 应用程序发起读取请求。
- Client 从(文件名,字节范围)–>(文件名,组块索引)转换请求,并将其发送到 Master 。
- Master 以块句柄和副本位置(即存储副本的 Chunkserver作为响应。
- Client 选择一个位置,然后将(块句柄,字节范围)请求发送到该位置。
- Chunkserver 将请求的数据发送到 Client 。
- Client 将数据转发到应用程序。
- 互斥操作(写/追加):
- Client 发送请求到 Master
- Master 返回块的句柄和 Replica 位置信息;
- Client 将写数据推送给所有 Replica (可以根据网络拓扑)
- 数据存储在 Replica 的缓存中;
- Client 发送写命令到 Primary
- Primary 给出写的次序(可能请求来自多个 Client)
- Primary 将该次序发送给 Secondaries
- Secondaries 响应 Primary
- Primary 响应 Client
- 添加操作:
- Client 将数据推送给所有 Replica ,然后向 Primary 发送请求。
- Primary检查Append是否会导致该块超过64MB。
- 如果小于64MB,按正常情况处理。
- 如果超过64MB,将该块扩充到最大范围(写0),并要求所有Secondary做同样的操作,同时通知Client该操作需要在下一个块上重新尝试。

- 读操作:
-
一致性:
- 并发的写将导致一致性问题。不同的 Client 对同一文件区域执行写。
- 一致:所有的Client读取相同的数据。
- 确定:所有的Client读取有效的数据。

第十章:P2P、DHT、Chord
- P2P基本结构类型:中心化网络、分布式(结构化、非结构化)、混合式
- 一致性哈希算法:
- 是一种特殊的哈希算法,目的是解决分布式缓存的问题。在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希算法解决了简单哈希算法在分布式哈希表(Distributed Hash Table,DHT)中存在的动态伸缩等问题。
- 特点:
- 平衡性:Hash 的结果平均分配到各个节点,从算法上解决了负载均衡问题
- 单调性:新增或者删减节点时,不影响系统正常运行
- 分散性:数据分散地存放在分布式集群中的各个节点,不必每个节点都存储所有的数据
- 负载:对于 一个特定的缓冲区而言,可能被不同的用户映射为不同的内容
- 分布式哈希表主要思想:
- 分布式哈希表技术(Distributed Hash Table,DHT)是一种分布式存储方法。在不需要服务器的情况下,每个客户端负责一个小范围的路由,并负责存储一小部分数据,从而实现整个 DHT 网络的寻址和存储。DHT 是实现分布式存储和下载的关键技术,现已广泛应用在P2P网络中。
- Chord:
- P2P应用中一个经典问题就是如何高效地找到存储了某个数据条目的节点。Chord协议被设计为用于通过一个给定的 key 映射到一个服务器节点。具体到应用来说,Chord服务器节点可能还需要存储key对应的 value(一般是文件或数据)。
- Chord通过某个哈希算法(如 SHA-1)为每个服务器节点或所存储的 key 计算出一个 m bit 的哈希值,统称为ID。对于服务器节点,其 ID 通过 Hashing IP 得到。所有 ID(不论是节点还是 key)都在模 2 后按顺序排列在一个环上。对于一个 ID 为 k 的 key(即 hash(key) = k),它由环上第一个 ID 不小于 k 的节点负责维护。该节点叫 ID k 的继任节点,记作 successor(k)。再直观一点的讲,successor(k) 是环上从 k 顺时针起(包括 k 本身)遇到的第一个节点。
- Finger Table 是一个列表,最多包含 m 项(m 就是哈希值的比特数),每一项都是节点 ID。假设当前节点的 ID 是 n,那么表中第 i 项的值是(n+22)(n+2^2)(n+22)的继任者。当收到请求(key),就到 Finger Table 中找到最大的且不超过 key 的那一项,然后把 key 转发给这一项对应的节点。有了 Finger Table 之后,时间复杂度可以优化为:O(log N)。

考试题型(2023秋季)
选择:20分
判断题:20分
其他类型合计60分(简答、分析、计算等)
2034





