Sprite缓存策略总结

来源:互联网 发布:拓思软件 编辑:程序博客网 时间:2024/05/16 14:02

Sprite File System是早期比较有特色的分布式文件系统。与NFS相比,Sprite File System在服务器端和客户端都设置缓存,大大提高了系统性能。它通过简单的读写锁保证整个系统的缓存一致性,并且通过和虚拟存储部分交互,尽量多地缓存数据。本文主要调研了Sprite File System缓存的设计方案,以及讲SFS缓存一致性的思想移植到NFS的具体做法。

1 Sprite File System缓存设计

1.1 写回策略

缓存的对磁盘或服务器的写回机制有两个策略可以采用:写直达和延迟写。写直达(write through),就是当数据被缓存的话,就立即写回。它的优势在于稳定性,NFS采用这样的方式,缺点是写性能低下。延迟写(delay write-back),数据被更改时仅写入cache,在以后的某个时间再写回磁盘或服务器。它有两个优势,写的速度快,写回前可能被删除(在某一特定环境下),缺点是可靠性差。Sprite采用的时延迟写策略。

1.2 缓存一致性

1.2.1 NFS策略

NFS采用的策略:当文件关闭时所有的数据都写回服务器端;如果一个客户端打开了被其他客户端缓存的文件,所有的缓存都将被更新为新的版本。在顺序写共享(sequential write sharing)的情况下,一个被多个客户端共享的文件不会同时被不同的客户端进行读和写操作,每个客户端看到的都是文件的最新版本。但是,如果一个NFS或者 Andrew的文件被一些客户端同时打开,并且同时对文件进行了修改,系统将会警告用户不允许这种共享,我们称作实时写共享(concurrent write sharing)。

1.2.2 Sprite策略

Sprite支持两种共享模式。对于实时写共享的处理是,系统通过锁和其他机制的操作,使得所有客户端的读和写操作以一个合理的方式进行。

实时写共享:当一个文件被不同的用户打开,并且至少有一个用户对此文件进行写操作,那么这个文件被多个客户端实时写共享。Sprint通过禁止用户缓存此文件来解决这个问题,使得所有对此文件进行读和写的操作必须经过服务器。当服务器识别到某个文件非实时写共享即将发生时,它采取两项操作:(1)、它通知所有打开这个文件进行那个写操作的用户,告诉它们将所有的脏数据写回服务器。这样的客户端至多有一个。(2)、服务器通知所有已打开文件的用户,这个文件的缓存失效,这将使得用户将这个文件的块从他们的缓存中移除。

(1)没有用户对文件进行写操作时,这个文件可以被很多用户同时缓存。

(2)如果没有其他并行的客户端对文件进行读或写操作,那么这个文件可以被正在写它的客户端缓存。

(3)当一个文件被通知不可被缓存,只有那些打开这个文件的用户得到消息;如果其他用户在他们的缓存仍然保留有该文件的数据,当他们下次打开这个文件时将会对该文件进行一致性操作。

(4)当一个不可被缓存的文件不再进行实时写共享时,它可以被重新缓存。

顺序性写共享:当一个文件被一个用户更改、关闭然后再被其他用户打开时,那么这个文件被客户端连续性写共享。连续性写共享存在两个潜在问题:

(1)当一个用户打开一个文件时,它的缓存中可能存在过时的块,服务器为每个文件保持一个版本号,每次文件写后关闭时版本号会增加,每个用户保持所有的文件版本号在它的缓存中。当一个文件被打开时,用户将服务器的文件版本号和它缓存中的文件版本号比较。如果改变,文件将更新它缓存中的文件副本。

(2)连续性写共享第二个潜在的问题是文件当前的数据或许在其他用户的缓存中(最后一个写文件的用户当关闭文件时不需要将脏块写回服务器)。服务器解决这个问题通过跟踪每个文件的最后一个写用户的动作,这个用户是唯一个可能在它的缓存中保留脏块的用户。当一个用户打开一个文件时,服务器查询最后一个写用户(如果存在写用户并且它和打开文件的用户不同),并等待它将脏块刷回服务器。

1.3 缓存特点的总结

总结下来,客户端与服务器模型主要有以下几种:

实时写共享(concurrentwrite sharing):当一个客户端正在对文件进行写操作时,有其他的客户端同时打开对文件进行写或者读。NFS采用的措施是禁止。Sprite采用的措施是关闭后刷回服务器。

顺序写共享(sequentialwrite sharing):文件可以被多个客户端共享读或者写,但是客户端写的时候仅有一个,不允许其他读或写操作同时进行。Sprite采用的措施是为文件分配一个版本号,每一次写就将版本号递增。当客户端访问缓存时,会和服务器上的版本号比较,如果不同,就从服务器取得数据。NFS采用write through。

非写共享(nonwrite shared):包含两种情况,read only和single writer。对于这种情况,文件被缓存在客户端是很安全的。“打开”操作,服务器返回信息说明文件是否可以被缓存。NFS采用write through。

2 Sprite缓存一致性到NFS的移植

NFS的缓存策略一致性策略一律都是write through。将Sprite缓存一致性移植到NFS主要采用的措施是添加“打开”和“关闭”操作。对于非写共享的文件,采用一致性策略使得不必每次缓存都要刷回。对于写共享的文件,仍采用write through,提供了一些序列化操作,并提过了回调机制。

通过“打开”和“关闭”操作,Sprite的一致性操作变成了有状态的。没一个操作之后文件都会处于一个状态,并通过该状态判断文件可否被缓存

2.1 NFS的修改

2.1.1 客户端对服务器的调用

在没有修改的NFS中,所有的RPC调用都是由客户端发起的。在新的NFS协议中,加入了“打开”和“关闭”操作。

打开操作的RPC调用报文包括文件句柄和一个表明客户端是否打算写的标志位。1.服务器返回一个是否允许缓存的标志位,以告知客户端是否允许缓存这个文件的数据。2.服务器为每个文件保存一个版本号,每一次读引起的打开操作都会使版本号增加,打开操作返回给服务器最近的版本号和之前的版本号。如果最近返回的版本号和缓存中的版本号匹配的话,那么缓存时生效的。如果客户端正在打开一个文件进行写操作,并且它的版本号和之前的版本号匹配的话,缓存也是生效的,这是因为版本号的改变是有当前正在进行的写操作引起的。服务器返回的信息还包括getattr操作返回的信息,因为NFS进行打开操作时同时也进行了getattr操作。

关闭操作通知服务器,客户端不再使用之前的文件句柄。客户端传递给服务器和之前打开操作对应的写模式标志位,这个标志位是必须提供的因为打开操作可能使用相同的文件句柄以不同的模式调用了多次。

2.1.2 服务器对客户端的调用

当SNFS服务器需要通知客户端某个文件不可再被缓存的时候,它会发送一个回调操作。回调操作有两个标志位说明客户端要采取怎样的操作:一个指明客户端缓存中的所有脏块需要写回到服务器,另一个指明任何缓存的块都要置无效并且不允许继续对它进行缓存。

如果一个回调操作包括写回操作,那么客户端需要等待RPC调用直到所有的脏块写回到服务器。

 

2.2 客户端修改

2.2.1 缓存策略

两种信息被缓存在客户端:文件数据块和文件属性。在SNFS中,如果文件时读共享的话,那么它的缓存不需要刷新。如果文件时写共享的,SNFS定时向服务器检查缓存是否过时。

NFS通过检查文件的修改记录来保证缓存信息的一致性,当发现文件的修改记录改变的话就会将缓存置无效。在SNFS中,缓存一致性协议为文件保留一个缓存标志位,如果文件不可缓存,那么它的数据块不可能进入到缓存中。

2.2.2 回调机制

在NFS中,所有的RPC调用都是由客户端发起的。在SNFS中,服务器发起回调操作RPC调用,所以客户端需要能够为RPC提供服务。

回调的信息是用来定位文件数据块在客户端缓存中的位置,同时会进行一定的操作。缓存的置无效操作在客户端本地执行,如果服务器需要进行写回,客户端会再次发起一个将数据块写回服务器的RPC操作。

2.2.3 延迟写策略

为了避免一次服务器故障带来数据丢失,所有延迟写回的数据块都会周期性地刷回磁盘。在Sprite中,脏块会在它们的存在时间达到30秒时刷回,这样的机制相对于传统做法较为保守。

因为一个临时文件在它被创建后的几秒钟内删除的情况在Unix应用中是相对常见的,所以当一个文件被删除时,Sprite和SNFS采用了取消延迟写的策略

2.3 服务器修改

2.3.1 服务器状态表

与NFS服务器不同的是,SNFS服务器需要保存RPC调用期间文件的状态。在SNFS的实现中,服务器维持了一个哈希状态表,用来保存每个打开的文件和上一个写用户仍然保存缓存的关闭的文件条目。

对原本NFS服务器代码的修改仅仅加入了两个新的RPC服务。“打开”操作和目前的“getattr”操作类似,但是它同时还进行状态表的记录操作,这将引起回调操作。“关闭”的内容仅仅通知状态表管理器。

2.3.2 状态表条目

状态表中每个条目包括相应文件的句柄,这是对文件进行查询的关键字。另外,表中也包括文件的当前版本号,当前的信息(例如是只读还是写共享的),打开文件的客户端列表,以及可能有这个文件脏块的客户端。

客户端信息块包括客户端的网络地址,作为客户端的标识和RPC目标地址。客户端数据块还包括这个客户端读用户和写用户的数量,以及一些RPC调用用来定位文件的其他附加信息。

2.3.3 版本号

服务器为每个文件分配一个版本号,每次文件被打开写时版本号都会增加。这样客户端就可以决定对文件响应时它的缓存是否生效。

2.3.4 状态转换

每个文件可能有很多状态。在SNFS的实现中,有以下几种状态:

CLOSED              文件没有被任何客户端打开。

CLOSED_DIRTY   文件没有被打开,但是最近的一个写用户保存有脏块。

ONE_READER     文件被一个客户端只读打开。

ONE_RDRDIRTY  文件被一个客户端只读打开,但是这个文件被之前的一个打开操作缓存脏块。

MULT_READERS 文件被两个或更多的客户端只读打开。

ONE_WRITER      文件被一个客户端写打开。

WRITE_SHARED 文件被两个或更多的客户端打开,至少有一个写用户。

表中2.1给出了可能的状态转换。


表2.1 SNFS服务器状态转换

 

 

ps.主要参考了Spritely NFS. Experiments with Cache-Consistency Protocols和Caching in the Sprite Network FileSystem

原创粉丝点击