巧妙的状态追踪, NFSv4.1的SEQUENCE变革
自NFSv3开始支持错误容忍机制(Fault Tolerance), 使得NFS协议从此具有了高可靠性的光环,在其协议具体设计中,依靠DRC (Deduplicate Request Cache) 来避免非幂等(no-idempotent)操作对数据完整性的影响,但有预NFS所依赖的RPC协议具有无序性,所以,DRC不可能缓存所有的请求,理论上导致仍然有可能出现数据完整性收到影响的风险,并且DRC对于服务的内存要求也会相对较高。
幂等操作
为何非幂等操作的会对数据完整性带来威胁? 首先我们要弄清楚何谓幂等操作,简单来说就是后续N次相同重复操作所产的结果和首次操作后的结果一致,再直白一点地说,就是这个操作只有在第一次完成以后的结果和随后的第N次操作完成后的结果一样。就像对自然数1最幂运算,1的N次幂永远是1,所以这个运算就是幂等的,而对2做幂运就是非幂等操作。
回到NFS协议中来看,一个读操作可以认为是一个幂等操作,而一个删除(Remove)操作就是一个,非幂等操作,因为同一个文件不能被删除两次。不管是NFSv3的DRC还是NFSv4.1的SEQUENCE, 都是为了消除非幂等操作操作在网络断连(Network Partition)的情况下所带来的影响。
重复请求缓存(DRC)
看上图,如果一个非幂等操作,这里就以删除为例,在NFS客户端发出删除请求并到达服务器的以后,服务器删除了目标文件 并将回复(Reply)缓存到DRC但是还没来得及发送回复的时候,服务器出现了网络故障,或者服务器重启,此时客户端在等不到回复的时候会在超时条件满足是重传之前的删除请求。此时重传的删除请求会直接在DRC里面命中之前缓存的回复,从而避免了再次去删除一个已经不存在文件!
那么如果由于某种原因删除文件的回复并未被进入DRC,那么结果将会如何?看图说话:
回复缓存失败
可以看到,如果DRC未命中的情况下,服务器会再次执行删除操作,但此时由于目标文件早已不存在,所以会出现ERR_NOENT的操作, 这样的情况还不算最坏的情况,因为删除一个已经被删除的文件至少不会对数据本身完整性产生影响,试想如果我们重传的不是删除操作,而是写操作的话,那么会出现什么情况?
SEQUENCE
从NFSv4.1开始,一种新的处理非幂等操作的方式被引入进来,这就是SEQUENCE,这种新的机制非常巧妙,在满足缓存重复操作的同时,还能极大的节省服务器的内存资源。
SEQUENCE机制里会在服务器内存中维护一个Slot表格,表格中每一行会追踪一个组数据,这组数据由slot id, sequence id,对应被缓存的回复(reply)组成。每一个slot id会追通过sequence id来追踪以一个序列操作中的最近一次操作,Sequence id会在每一次请求/回复后加1,如果过服务器收到了的slot id 对应的sequence id和缓存的sequence id一致,说明此此时收到的请求是一个重复请求,那么服务器会值节回复slot id所对应已经缓存的Reply,下图演示了在网络断连的情况下,重传请求从Slot表格获取缓存回复的过程:
通过Sequence处理重复请求
未完待续。。。