文件读取是一个的过程,一个客户端,只需要与一个数据服务器联系,就可以获得所需的内容。但是,写入操作,则是一个一对多的流程。一次写入,需要在所有存放相关数据块的数据服务器都保持同步的更新,有任何的差池,整个流程就告失败。。。
在分布式系统中,一旦涉及到写入操作,并发处理难免都会沦落成为一个变了相的串行操作。因为,如果不同的客户端如果是任意时序并发写入的话,整个写入的次序无法保证,可能你写半条记录我写半条记录,最后出来的结果乱七八糟不可估量。在HDFS中,并发写入的次序控制,是由主控服务器来把握的。当创建、续写一个文件的时候,该文件的节点类,由INodeFile升级成为INodeFileUnderConstruction,INodeFileUnderConstruction是INodeFile的子类,它起到一个锁的作用。如果当一个客户端想创建或续写的文件是INodeFileUnderConstruction,会引发异常,因为这说明这个此处有爷,请另寻高就,从而保持了并发写入的次序性。同时,INodeFileUnderConstruction有包含了此时正在操作它的客户端的信息以及最后一个数据块的数据服务器信息,当追加写的时候可以更快速的响应。java分布式文件系统。。
与读取类,DFSClient也有一个DFSClient.DFSOutputStream类,写入开始,会创建此类的实例。DFSOutputStream会从NameNode上拿一个LocatedBlock,这里面有最后一个数据块的所有数据服务器的信息。这些数据服务器每一个都需要能够正常工作(对于读取,只要还有一个能工作的就可以实现...),它们会依照客户端的位置被排列成一个有着最近物理距离和最小的序列(物理距离,是根据机器的位置定下来的...),这个排序问题类于著名旅行商问题,属于NP复杂度,但是由于服务器数量不多,所以用最粗暴的算法,也并不会看上去不美。。。
当一个数据块写满了之后,客户端需要向主控服务器申请追加新的数据块。这个会引起一次数据块的分配,成功后,会将新的数据服务器组返还给客户端。然后重新回到上述流程,继续前行。。。
关于写入的流程,还可以参见这里。此外,写入涉及到租约问题,后续会仔细的来说。。。
IV. 分布式支持
如果单机的文件系统是田里勤恳的放牛娃,那么分布式文件系统就是刀尖上讨饭吃的马了。在分布式环境中,有太多的意外,数据随时传输错误,服务器时刻准备牺牲,很多平常称为异常的现象,在这里都需要按照平常事来对待。因此,对于分布式文件系统而言,仅仅是满足了正常状况下文件系统各项服务还不够,还需要保证分布式各种意外场景下健康持续的服务,否则,将一无是处。。。
在分布式环境中,哪台服务器牺牲都是常见的事情,牺牲不可怕,可怕的是你都没有时刻准备好它们会牺牲。作为一个合的分布式系统,HDFS当然时刻准备好了前赴后继奋勇向前。HDFS有三类服务器,每一类服务器出错了,都有相应的应急策略。。。
a. 客户端
生命最轻如鸿毛的童鞋,应该就是客户端了。毕竟,做为一个文件系统的使用者,在整个文件系统中的地位,难免有些归于三流。而作为客户端,大部分时候,牺牲了就牺牲了,没人哀悼,无人同情,只有在在辛勤写入的时候,不幸辞世(机器挂了,或者网络断了,诸如此类...),才会引起些恐慌。因为,此时此刻,在主控服务器上对应的文件,正作为INodeFileUnderConstruction活着,仅仅为占有它的那个客户端服务者,做为一个专一的文件,它不允许别的客户端染指。这样的话,一旦占有它的客户端服务者牺牲了,此客户端会依然占着茅坑不拉屎,让如花玉INodeFileUnderConstruction孤孤单单守寡终身。这种事情当然无法容忍,因此,必须有办法解决这个问题,办法就是:租约。。。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/tongxinshuyu/article-40093-5.html
航行自由只是美国霸权的一种借口
超喜欢千玺