设为首页 收藏本站
查看: 817|回复: 0

[经验分享] Hadoop-0.1版本FSNamesystem类笔记

[复制链接]

尚未签到

发表于 2016-12-11 10:12:34 | 显示全部楼层 |阅读模式
  这个类维护了系统中多个重要的表:
   1.dir

     FSDirectory dir;
  文件的目录结构,也就是传说中的元数据,具体是由iNode组成,可以理解为文件到块的映射,保存在NameNode的本地内存和硬盘中。
 初始化:在FSNamesystem类的构造函数中,调用FSDirectory类构造函数,其参数dir是xml配置文件  中"dfs.name.dir"所对应的值,其默认值为"/tmp/hadoop/dfs/name"。


     this.dir = new FSDirectory(dir);
  FSDirectory类构造函数:

     public FSDirectory(File dir) throws IOException {
File fullimage = new File(dir, "image");
if (! fullimage.exists()) {
throw new IOException("NameNode not formatted: " + dir);
}
File edits = new File(dir, "edits");
if (loadFSImage(fullimage, edits)) {
saveFSImage(fullimage, edits);
}
synchronized (this) {
this.ready = true;
this.notifyAll();
this.editlog = new DataOutputStream(new FileOutputStream(edits));
}
}
  FS_IMAGE是给内存中的FSDirectory类实例做备份的,image是FS_IMAGE所存储的路径,也就是说如果这个路径不存在,说明NameNode还没有格式化,换句话说在格式化的函数中一定能找到类似下面这样的代码

     File image = new File(dir, "image");
image.mkdirs();
  接着FSDirectory类构造函数会读logEdit,目录的添加,删除,重命名,创建路径这四个操作会记录到logEdit,logEdit隔一段时间就会把这些修改作用到FS_IMAGE上,也就是说,对读到的FS_IMAGE做logEdit会得到最新的目录结构。至于从本地文件系统读FS_IMAGE和logEdit的过程,等讲到hdfs io时再说。也就是说,现在内存中的FSDirectory类实例已经是最新的了。至此FSDirectory类实例化结束。
   在下列情况下其值发生变化:
  (1)在调用ClientProtocol接口中的create()函数时,文件需要覆盖时会调用delete()函数,同样对应于logEdit的删除。
  (2)在调用ClientProtocol接口中的complete()函数时,要把完成的文件添加到FSDirectory类实例中去,包括所包含的块(从pendingCreates中该文件对应的Vecor中获取的)。对应于logEdit的添加。
  (3)在调用ClientProtocol接口中的rename()函数时,对应于logEdit的重命名。
  (4)在调用ClientProtocol接口中的delete()函数时,对应于logEdit的删除。
  (5)在调用ClientProtocol接口中的mkdir()函数时,对应于logEdit的创建路径。
  2.datanodeMap

     TreeMap datanodeMap = new TreeMap();
  记录节点到块的映射,Key是UTF8类的实例(DataNode的Name),Value是DatanodeInfo类的实例。
  DatanodeInfo类的成员变量有:

     private UTF8 name;
private long capacityBytes, remainingBytes, lastUpdate;
private volatile TreeSet blocks;
  在下列情况下其值发生变化:
  (1)在调用DatanodeProtocol接口中的sendHeartbeat()函数时,如果该节点未被datanodeMap所记录,则增加该节点信息。当然这里不包含该节点的块信息,也就是说其存储DatanodeInfo类的实例并没有其所对应块信息。 
  (2)在调用DatanodeProtocol接口中的blockReport()函数时,如果Datanode所报告的块datanodeMap中没有,则添加,否则删除。这里增加了datanodeMap的块信息,也就是DatanodeInfo类的实例中所对应的块信息。
  (3)在调用DatanodeProtocol接口中的blockReceived()函数时和ClientProtocol接口中的reportWrittenBlock()函数时,这里增加了datanodeMap的块信息,也就是DatanodeInfo类的实例中所对应的块信息。
  (4)当心跳监视器监视到某个节点对应的心跳过期时,则把该心跳对应的节点从datanodeMap中删除。
  3.heartbeats

    TreeSet heartbeats = new TreeSet(new Comparator() {
public int compare(Object o1, Object o2) {
DatanodeInfo d1 = (DatanodeInfo) o1;
DatanodeInfo d2 = (DatanodeInfo) o2;            
long lu1 = d1.lastUpdate();
long lu2 = d2.lastUpdate();
if (lu1 < lu2) {
return -1;
} else if (lu1 > lu2) {
return 1;
} else {
return d1.getName().compareTo(d2.getName());
}
}
});
  记录当前活跃的节点,保存DatanodeInfo类的实例。与datanodeMap同步增删其对应的DatanodeInfo类的实例。
  在下列情况下其值发生变化:
  (1)在调用DatanodeProtocol接口中的sendHeartbeat()函数时,如果该节点未被heartbeats所记录,则增加该节点信息,当然这里不包含该节点的块信息,也就是说其存储DatanodeInfo类的实例并没有其所对应块信息。
  (2)当心跳监视器监视到某个节点对应的心跳过期时,则把该节点对应的心跳从heartbeats中删除。
  4.blocksMap

    TreeMap blocksMap = new TreeMap();
  块到节点的映射,KEY是Block类实例,Value是DatanodeInfo类实例的TreeSet。可看作与datanodeMap记录相反的信息。与datanodeMap同步增删其对应的DatanodeInfo类实例中的块信息。
  在下列情况下其值发生变化:
  (1)在调用DatanodeProtocol接口中的 blockReport()函数时,如果该块以前记录过(通过和datanodeMap的对比),而报告中没有,则删除blocksMap中该块所对应的现在这个报告节点。如果以前没有记录过,而报告中有,则添加blocksMap中该块所对应的现在这个报告节点。
  (2)在调用DatanodeProtocol接口中的 blockReceived()函数时和ClientProtocol接口中的reportWrittenBlock()函数时,添加映射到blocksMap中。
  (3)当心跳监视器监视到某个节点对应的心跳过期时,从blocksMap中删除该节点所对应的块。
   5.recentInvalidateSets

     TreeMap recentInvalidateSets = new TreeMap();
  节点到需要删除的块的映射,通过Command形式发给DataNode节点以删除。Key是UTF8类的实例(DataNode)Value是block的类实例的Vector。
   在下列情况下其值发生变化:
  (1)在调用DatanodeProtocol接口中的 blockReport()函数时,如果该块以前没有记录过,而报告中有,则添加blocksMap中该块所对应的现在这个报告节点。如果该块在FSDirectory类实例中依然存在并且该块没有在excessReplicateMap节点所对应得多余块中(我再并且)存有该快的节点数大于了系统设定的块最大复制数,则随机的选一个节点,加上该多余的块添加到excessReplicateMap中,再加到recentInvalidateSets中。
  (2)在调用DatanodeProtocol接口中的 blockReceived()函数时和ClientProtocol接口中的reportWrittenBlock()函数时,添加映射到blocksMap中。如果该块在FSDirectory类实例中依然存在并且该块没有在excessReplicateMap节点所对应得多余块中(我再并且)存有该快的节点数大于了系统设定的块最大复制数,则随机的选一个节点,加上该多余的块添加到excessReplicateMap中,再加到recentInvalidateSets中。
  (3)在调用DatanodeProtocol接口中的 getBlockwork()函数时,如果是删除命令,从recentInvalidateSets删除该节点所对应的块。
  (4)在调用ClientProtocol接口中的create()函数时,文件需要覆盖时会调用delete()函数,添加信息到recentInvalidateSets。
  6. neededReplications

     private TreeSet neededReplications = new TreeSet();
  没有达到需要的复制块的数量,就把该块加入到neededReplications中。neededReplications中存储的是Block类的实例。
   在下列情况下其值发生变化:
  (1)在调用DatanodeProtocol接口中的 blockReport()函数时,如果该块以前记录过(通过和datanodeMap的对比),而报告中没有,则删除blocksMap中该块所对应的现在这个报告节点。同时如果该块在FSDirectory类实例中依然存在且现在块数小于需要复制的块数,说明该块不是通过ClientProtocol接口中的delete()函数删除的,所以导致该块没有被报告,是该DataNode节点本身的故障问题,所以需要另复制该块到其他节点,故添加该Block到neededReplications。
  (2)在调用DatanodeProtocol接口中的 blockReport()函数时,如果该块以前没有记录过,而报告中有,则添加blocksMap中该块所对应的现在这个报告节点。同时,如果该块在FSDirectory类实例中依然存在且现在块数大于需要复制的块数,则从neededReplications删除该块。(可能失效的节点恢复了过来)否则,则添加该Block到neededReplications。
  (3)在调用DatanodeProtocol接口中的 blockReceived()函数时和ClientProtocol接口中的reportWrittenBlock()函数时,添加映射到blocksMap中。同时,如果该块在FSDirectory类实例中依然存在且现在块数大于需要复制的块数,则从neededReplications删除该块。(可能失效的节点恢复了过来)否则,则添加该Block到neededReplications。
  (4)在调用DatanodeProtocol接口中的 getBlockwork()函数时,在制定复制命令时,首先检查是否块在FSDirectory类实例中依然存在,如果不存在,从neededReplications中把块删除。如果该块在neededReplications中,则把该块从neededReplications中删除。
  (5)在调用ClientProtocol接口中的complete()函数时,如果块所对应的节点数小于需要复制的块数时,添加该块到neededReplications中。这里还不太明白,再调用complete()前,dfsclient应该已经调用过reportWrittenBlock()了,所以datanodeMap已经被修改了,为什么还会出现这种情况呢?)
  (6)当心跳监视器监视到某个节点对应的心跳过期时,则删除节点所对应的块。同时如果该块在FSDirectory类实例中依然存在且现在块数小于需要复制的块数,则添加该块到neededReplications。
  7. pendingReplications

     private TreeSet pendingReplications = new TreeSet();
  pendingReplications中存储的是Block类的实例。
   在下列情况下其值发生变化:
  (1)在调用DatanodeProtocol接口中的 blockReport()函数时,如果该块以前没有记录过,而报告中有,则添加blocksMap中该块所对应的现在这个报告节点。同时如果该块在FSDirectory类实例中依然存在且现在块数大于需要复制的块数,则从pendingReplications删除该块。
  (2)在调用DatanodeProtocol接口中的 blockReceived()函数时和ClientProtocol接口中的reportWrittenBlock()函数时,添加映射到blocksMap中。同时如果该块在FSDirectory类实例中依然存在且现在块数大于需要复制的块数,则从pendingReplications删除该块。
  (3)在调用DatanodeProtocol接口中的 getBlockwork()函数时,在制定复制命令时,首先检查是否块在FSDirectory类实例中依然存在,如果不存在,从neededReplications中把块删除。如果该块在neededReplications中,则把该块从neededReplications中删除,添加该块至pendingReplications。
  8.excessReplicateMap(它的作用现在不是很清楚,和recentInvalidateSets有什么联系和区别呢?)

     TreeMap excessReplicateMap = new TreeMap();
  Key是UTF8类的实例(DataNode的Name),Value是Block类实例的TreeSet. 
  在下列情况下其值发生变化:
  (1)在调用DatanodeProtocol接口中的 blockReport()函数时,如果该块以前记录过(通过和datanodeMap的对比),而报告中没有,则删除blocksMap中该块所对应的现在这个报告节点。因为报告中没有该块,说明该块已经不再该DataNode,所以也就谈不上该块在该节点是多余的了,故从excessReplicateMap中删除。
  (2)在调用DatanodeProtocol接口中的 blockReport()函数时,如果该块以前没有记录过,而报告中有,则添加blocksMap中该块所对应的现在这个报告节点。如果该块在FSDirectory类实例中依然存在并且该块没有在excessReplicateMap节点所对应得多余块中(我再并且)存有该快的节点数大于了系统设定的块最大复制数,则随机的选一个节点,加上该多余的块添加到excessReplicateMap中。
  (3)在调用DatanodeProtocol接口中的 blockReceived()函数时和ClientProtocol接口中的reportWrittenBlock()函数时,添加映射到blocksMap中。如果该块在FSDirectory类实例中依然存在并且该块没有在excessReplicateMap节点所对应得多余块中(我再并且)存有该快的节点数大于了系统设定的块最大复制数,则随机的选一个节点,加上该多余的块添加到excessReplicateMap中。
  (4)当心跳监视器监视到某个节点对应的心跳过期时,则节点所对应的块。该块已经不再该DataNode,所以也就谈不上该块在该节点是多余的了,故从excessReplicateMap中删除。
  9.pendingCreates

     TreeMap pendingCreates = new TreeMap();
  正在创建的文件,Key是UTF-8的实例(文件名),Value是该文件包含的块(Block类的实例的Vector)。
  在下列情况下其值发生变化:
  (1)在调用ClientProtocol接口中的create()函数时,把文件加入到pendingCreates,创建空的Vector 。
  (2)在调用ClientProtocol接口中的abandonBlock()函数时,把块从pendingCreates中的Vector中删除,文件不删除。
  (3)在调用ClientProtocol接口中的addBlock()函数时,如果文件正在被创建,则增加一个块到Vector中。
  (4)在调用ClientProtocol接口中abandonFileInProgress()函数时,把文件从pendingCreates中删除。
  (5)在调用ClientProtocol接口中complete()函数时,NameNode通过节点或客户上报块的信息把块的长度这个字段在pendingCreates中的Vector中存的Block加上,然后在FSDirectory类的实例修改过后,把文件从从pendingCreates中删除。
  (6)如果锁监视器监视到锁过期且持有锁的文件正在被创建,则把文件从pendingCreates中删除。
  10.pendingCreateBlocks

     TreeSet pendingCreateBlocks = new TreeSet();
  正在创建的块,存储的是Block类的实例。
  (1)在调用ClientProtocol接口中的create()函数时,把文件对应的块加入到pendingCreateBlocks。
  (2)在调用ClientProtocol接口中的abandonBlock()函数时,把文件对应的块从pendingCreateBlocks中删除。
  (3)在调用ClientProtocol接口中的addBlock()函数时,如果文件正在被创建,则增加一个块到pendingCreateBlocks中。
  (4)在调用ClientProtocol接口中abandonFileInProgress()函数时,把该文件对应的所有块从pendingCreateBlocks 中删除。
  (5)在调用ClientProtocol接口中complete()函数时,把该文件对应的块从pendingCreateBlocks中删除。
  (6)如果锁监视器监视到锁过期且持有锁的文件正在被创建,则把文件对应的块从pendingCreateBlocks中删除。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-312669-1-1.html 上篇帖子: Hadoop 单节点的部署(来自翻译官方文档和自我实践) 下篇帖子: hadoop学习2——DistributedCache的部分用法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表