1. 客户端正在写的文件,被另外一个客户端删除了会怎样?
会出错,但不会立马出错。
这里简单介绍一下写的流程,一些create为例:
- 客户端向namenode发送create rpc请求,namenode的NameNodeRpcServer提供create服务,在namespace中建立文件路径以及对应inode,赋予client lease,这个时候并没有为文件分配block
- 客户端开始写出data,第一次写、以及后面每一次block写满之后都会向namenode申请新的block(当然如果输出过程中出现异常也可能会申请新的block)。申请block时rpc服务端会检查文件是否存在、检查client是否依然持有lease且在lease有效期内。到这里如果一切没有问题,client申请到了新的block,后面只需要和datanode通信,不停的往datanode写data就行了。
上面可以看出,正在写一个datanode时,client是不需要和namenode通信的。
再看看delete做了什么:
- namenode的NameNodeRpcServer作为rpc服务端响应delete请求,从namespace中删除对应的文件的inode,删除inode对应的lease。并不会检查文件是否被打开,是否有client持有文件对应inode 的lease,删除操作是容许的。
所以当client正在写block的client,由于不需要和namenode交互,即便文件被删除也不会立马出错,而是要等待当前block写满,请求新的block时和namenode通信才会发现文件被删除。此外如果client端调用fsync或者close也需要和namenode通信,此时也会抛出异常。
2. 客户端正在写的文件,被另外一个客户端rename了是否会有影响?
答案是不会造成任何影响。
先看看创建文件的过程,每一个创建的文件都有一个inode与之对应(这个和linux/unix文件系统类似),inode中记录了如下信息:
1. id, long类型的值
2. name,文件名的byte[]表示
3. permission, 访问权限
4. modificationTime,最近一次修改时间
5.accessTime,最近一次访问时间
此外对于普通文件inode(使用类INodeFile表示)还使用了一个blocks数组保存了这个文件所有的block信息
当client写一个文件 f 时,namenode还会为期创建新的lease,namenode保存client到lease, 还会保存f的inode到lease的映射。通过client获得的lease和通过inode获得的lease一样,就表示client持有inode的lease,其他client不可以再写该文件。
当client写完一个block,向namenode请求新的block时,会使用inode的id去请求,namenode的rpc服务端‘NameNodeRpcServer’会使用这个id去检索inode(namenode有一个map可以根据id去快速检索inode),然后创建新的block,并将block追加到inode的blocks数组里。
看看rename做了什么,rename不会检查是否有client持有文件的lease,其次rename尝试将f1 修改到 f2时,它会拿到f1的inode,然后将inode的的name从f1改成f2。此外rename还需要修改的是FSDirectory(文件目录树的类),将inode从f1的父inode(对应类INodeDirectory)启动到新 f2 的父inode下。
从上面过程中可以看出,inode的id一直不会改变,对于client写文件来说,有id足够。因此rename不会对写文件造成影响,数据依然会写到rename之后的新的名称的文件里。