wordpress网站漏洞/软文如何推广
由于多个客户端可以挂载同一个文件系统,如何在多个客户端之间保持数据一致性是个非常麻烦的问题,NFSv2和NFSv3没有规定具体的方法,一般的做法是客户端不定期检查文件是否发生了冲突,比如读操作中在发起READ请求前可能要发起GETATTR请求,判断本地缓存是否有效。在大规模系统中以及当客户端和服务器分布比较遥远时就会影响系统性能,因为GETATTR操作需要一定的执行时间。
NFSv4引入了一种机制保持文件缓存一致性,这种机制称为delegation。这种机制的基本原理是客户端A打开文件时服务器给客户端A颁发一个凭证,只要客户端A持有这个凭证就可以认为没有与其他客户端发生冲突,读写操作中就不需要发起GETATTR请求了。当客户端B试图访问同一个文件时,这两个客户端就发生了冲突。服务器先暂时不响应客户端B的请求,而是向客户端A发送RECALL请求。客户端A接收到RECALL请求后将缓存中的数据刷新到服务器中,然后将凭证交还给服务器。这时服务器再响应客户端B的请求。以后两个客户端就按照NFSv2、NFSv3中的方法检查文件冲突。因此,这种机制适用于只读文件系统,或者客户端对数据修改不频繁的文件系统。
1.反向通道
如果一个客户端持有delegation,当文件访问发生冲突时,服务器需要向客户端发送RECALL请求,收回delegation,这是请求是在一个反向通道上进行的。也就是说:客户端和服务端之间有两个RPC通道,正常的NFS请求在正向通道中传输,与delegation相关的请求在反向通道中传输。在反向通道中,NFS服务器是反向通道的RPCK客户端,NFS客户端是反向通道的RPC服务器端,NFS客户端监听NFS服务器端发送过来的请求。正向通道是在客户端挂载NFS文件系统时创建的,反向通道在必要时才创建。什么叫"必要时"呢?简单说来,就是当客户端和服务器端需要建立状态时。具体来说,反向通道是在SETCLIENTID请求中创建。客户端发起SETCLIENTID时,会将反向通道的相关信息发送给服务器端。服务器检查是否可以创建反向通道,如果可以,将创建。后面的文章中会详细讲解SETCLIENTID请求的处理过程。
2.获取delegation
如果反向通道可用,那么当客户端打开文件时,服务器会给客户端分配一个delegation。只要客户端持有delegation,就可以认为本地文件和服务器端同步,文件没有发生冲突。所以,客户端可以直接向服务器发送数据而不用担心与其他客户端冲突。
3.冲突访问冲突
当另一个客户端Client2与Client1访问同一个文件,并且访问方式发生冲突时,服务器会检测到这种冲突情况。这时,服务器会暂时停止Client2的请求,转而向Client1发送CB_RECALL请求,Client1接收到这个请求后会通过DELEGRETURN请求将delegation返还给服务器。这时,服务器继续响应Client2的OPEN请求。这之后,如果Client1再向服务器发送数据,就必须小心检查文件是否冲突了。
4.反向通道故障
上一小节讲到:当Client2和Client1对文件访问发生冲突时,服务器会通过反向通道向Client1发送CB_RECALL请求回收delegation,回收delegation后再响应Client2的OPEN请求。这里还存在一个问题,假设服务器和Client1之间的反向通道发生故障了,Client1无法接收到服务器发送的请求,服务器是否要一直延迟Client2的OPEN请求?这是Client2来说不公平。因此服务器会设置一个过期时间。如果在规定的时间内Client1没有交回delegation,那么服务器会强制删除delegation,然后马上相应Client2的请求。假设后来Client1又向服务器发起了I/O请求,服务器必须检测到Client1中的delegation已经删除了,然后将这一信息通知Client1,这样Client1就不能使用delegation了。