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

[经验分享] 第七章:小朱笔记hadoop之源码分析-hdfs分析 第四节:namenode-DecommissionManager

[复制链接]

尚未签到

发表于 2016-12-13 09:43:23 | 显示全部楼层 |阅读模式
第七章:小朱笔记hadoop之源码分析-hdfs分析

第四节:namenode分析

4.6 namenode任务线程之DecommissionManager$Monitor

       DecommissionManager主要是负责节点退役或者说节点停用,Monitor负责定时来检测这些节点的退役状态。DataNode节点退役得等该节点上的所有数据块Blocks被复制完成之后,才能允许退役。这就需要Monitor负责定时地检测这些节点中Blocks的状态,当这些Blocks都满足副本因子之后,才能将该DataNode节点置为退役状态。
       DataNode的状态:

enum AdminStates {NORMAL, DECOMMISSION_INPROGRESS, DECOMMISSIONED; }  
//AdminStates.NORMAL:正常态  
//AdminStates.DECOMMISSION_INPROGRESS:表示DataNode节点处于退役处理状态  
//AdminStates.DECOMMISSIONED:后一个变量表示节点处于已退役状态  
(1)NORMAL> DECOMMISSION_INPROGRESS 转换
         NameNode为客户端提供了一个方法refreshNodes(),当客户端调用该接口的时候,NameNode节点会重新加载配置文件中的 dfs.hosts和dfs.hosts.exclude两个选项,更新HostsFileReader,之后根据HostsFileReader的新主 机列表来判断哪些DataNode节点被允许连接到NameNode,哪些不允许被连接,对于不允许连接的DataNode节点,先将其标记为 AdminStates.DECOMMISSION_INPROGRESS
(2) DECOMMISSION_INPROGRESS> DECOMMISSIONED转换
         这正是DecommissionManager$Monitor所做的事情
(3)DECOMMISSIONED>关闭
         当数据节点重启或者重新初始化之后,都会首先向NameNode节点注册,如果此时主节点不允许该数据节点加入集群,那么它就会对该数据节点进行强制退役处理。当DecommissionManager$Monitor线程把一个DataNode节点标记为 AdminStates.DECOMMISSIONED状态之后,NameNode节点会在当该DataNode节点下一次发送heart的时候,就明确的给他一个command,让它shutdown。
         主要属性:

    // 一次轮询检查的时间间隔  
private final long recheckInterval;  
// 每次轮询检查处于正在退役状态的数据节点数量  
private final int numNodesPerCheck;  
// 上一次轮询结束时处理到的最后一个数据节点   
private String firstkey = "";  
           DataNode多并且检测耗时,所以采用迭代的步长检测,每次只检测处于正在退役状态的numNodesPerCheck个数据节点,下次检测时就从上次检测的的最后一个数据节点开始,而这两次检测的时间间隔是recheckInterval s。
    为了保证检测的连续性,所以检测的数据构成一个环形数据结构,然后需要记录每次迭代的起始点,所以有个firstkey属性,然后环形数据结构由hadoop自己实现的CyclicIteration来提供。
    检测逻辑:
    (a)判断节点是否处于DECOMMISSION_INPROGRESS状态;
    (b)如果处于DECOMMISSION_INPROGRESS状态,则检测该节点上的所有数据块是否已经到了复制因子;
    (c)如果已经到了复制因子块的个数则说明这个节点上的所有块都是多余了,也就是说这个节点可以退役了,将节点状态设置为退役即 DECOMMISSIONED
 

    private void check() {  
int count = 0;  
for(Map.Entry<String, DatanodeDescriptor> entry : new CyclicIteration<String, DatanodeDescriptor>(fsnamesystem.datanodeMap, firstkey)) {  
final DatanodeDescriptor d = entry.getValue();  
firstkey = entry.getKey();  
////数据节点处于正在退役状态   
if (d.isDecommissionInProgress()) {  
try {  
//检查数据节点是否可以退役,如果可以则使其退役   
//检测该节点上的所有数据块是否已经到了复制因子  
fsnamesystem.checkDecommissionStateInternal(d);  
} catch(Exception e) {  
LOG.warn("entry=" + entry, e);  
}  
//检查处于正在退役状态的数据节点达到设定的阈值就退出本次轮询   
if (++count == numNodesPerCheck) {  
return;  
}  
}  
}  
}  
}  
    检查存储在它上面的所有数据块Block的副本是否已经满足用户设置的副本值,如果不满足还要讲该数据块Block添加到待复制副本的队列中。

   

    /**
* Change, if appropriate, the admin state of a datanode to  
* decommission completed. Return true if decommission is complete.
*  
*  从上面的检测逻辑可以看出,其实就是为了确定是否这个节点上的数据块已经被完全复制过了到了复制因子,
*  如果完全复制过了,那这个节点其实就没用了,所以就标示为退役了,主要起到一个审查的目的
*  DECOMMISSION_INPROGRESS   
*  DFSAdmin的 -refreshNodes 命令或者说传递这个命令参数的其他调用者例如Balancer ,DFSck等。   
*  refreshNode会依据exclude文件里配置的ip来更新node节点的状态,例如这里是调用setDECOMMISSION_INPROGRESS(datanode)   
*   
*  需要检查存储在它上面的所有数据块Block的副本是否已经满足用户设置的副本值,如果不满足还要讲该数据块Block添加到待复制副本的队列中,这个检查过程是比较耗时的
*/  
boolean checkDecommissionStateInternal(DatanodeDescriptor node) {  
//  
// Check to see if all blocks in this decommissioned  
// node has reached their target replication factor.  
//  
if (node.isDecommissionInProgress()) {  
if (!isReplicationInProgress(node)) {  
node.setDecommissioned();  
LOG.info("Decommission complete for node " + node.getName());  
}  
}  
if (node.isDecommissioned()) {  
return true;  
}  
return false;  
}  

/**
* Return true if there are any blocks on this node that have not
* yet reached their replication factor. Otherwise returns false.
*/  
/**  
* 检查一个数据节点上的每一个数据块的副本数量是否满足设置的值,如果都满足则返回false,否则返回ture;  
* 对于副本数量不满足设置值的数据块,如果还没有对该数据块进行副本复制,则将其挂载到副本复制线程的任务队列中  
*/   
private boolean isReplicationInProgress(DatanodeDescriptor srcNode) {  
boolean status = false;  
int underReplicatedBlocks = 0;  
int decommissionOnlyReplicas = 0;  
int underReplicatedInOpenFiles = 0;  
for(final Iterator<Block> i = srcNode.getBlockIterator(); i.hasNext(); ) {  
final Block block = i.next();  
INode fileINode = blocksMap.getINode(block);  
if (fileINode != null) {  
NumberReplicas num = countNodes(block);  
int curReplicas = num.liveReplicas();  
int curExpectedReplicas = getReplication(block);  
if (curExpectedReplicas > curReplicas) {  
// Log info about one block for this node which needs replication  
if (!status) {  
status = true;  
logBlockReplicationInfo(block, srcNode, num);  
}  
underReplicatedBlocks++;  
if ((curReplicas == 0) && (num.decommissionedReplicas() > 0)) {  
decommissionOnlyReplicas++;  
}  
if (fileINode.isUnderConstruction()) {  
underReplicatedInOpenFiles++;  
}  
//数据块不在待(副本)复制队列中,也不在正在(副本)复制队列中   
if (!neededReplications.contains(block) &&  
pendingReplications.getNumReplicas(block) == 0) {  
//  
// These blocks have been reported from the datanode  
// after the startDecommission method has been executed. These  
// blocks were in flight when the decommission was started.  
//  
neededReplications.add(block,   
curReplicas,  
num.decommissionedReplicas(),  
curExpectedReplicas);  
}  
}  
}  
}  
srcNode.decommissioningStatus.set(underReplicatedBlocks,  
decommissionOnlyReplicas, underReplicatedInOpenFiles);  
return status;  
}  
 

运维网声明 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-313610-1-1.html 上篇帖子: [Hadoop]Sqoop 1.4.2中文文档(三)之SqoopJob与其外的操作 下篇帖子: 一文教你看懂大数据的技术生态圈:Hadoop,hive,spark
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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