2021年山东大学软件工程应用与实践项目——Hadoop源码分析(九)

2021SC@SDUSC

Hadoop源码分析(九)——Datanode实现(1)

Datanode分析

Hadoop 中关于 Datanode 的代码被放在了 org.apache.hadoop.hdfs.server.Datanode 中,主要的三个类是 Datanode、 FSDataSet 和 DataBlockScanner。其中,Datanode 类就是一个 Datanode 运行实例的抽象,FSDataSet 类 用来表示Datanode节点上关于磁盘配置的信息和一些处理接口,而DataBlockScanner类是一个线程, 用来不断检查该Datanode上的blocks信息。当Datanode启动的时候,会初始化许多的信息,如和 Namenode通信的Socket信息,从Hadoop配置文件中读取的配置信息,并利用这些配置信息初始化该 Datanode类的instance。每个Datanode中都会有多个内部线程在循环作一些操作,其中有一个为 DataTransfer,用来向其他Datanode传输block数据。
Datanode启动过程中同样会把这个线程启动。启动Datanode时,同样还会将DataBlockScanner 线程启动,这个线程用来keep track Datanode上的block和更新信息。Datanode中还保存了一个 FSDataset的实例,它用来记录当前Datanode上关于磁盘的配置信息,以及这些磁盘或者路径下中保 存的HDFS分布式文件系统中的信息。通过对Hadoop配置文件的读取,Datanode也会初始化这个 FSDataset类的instance» Datanode本身也是一个线程类,它的run。中会间歇调用一个服务方法: offerService(),这个方法里记录处理的就是Datanode的核心处理逻辑。
这当中的处理包括:每隔3秒钟向namenode发送一次自己的heartbeat信息,这些信息被namenode 接收到以后会根据对该 Heartbeat的分析向 Datanode返回一个 Datanode需要的操作 (DatanodeCommand ),并根据从namenode返回的这个 DatanodeCommand来作自己相应的操作<, 然后 会检查本Datanode是否接收到新的block,并作相应的处理,然后检查上一次向namenode进行block report的时间,如果超过一定的时间(默认为1小时)就向namenode发送一次block report,以便让 namenode上记录的信息保持更新。每一次接收到来自namenode的操作信息(DatanodeCommand), Datanode都会作相应的操作。

1.Block数据块

Block所在的包为org.apache.hadoop.hdfs.protocol. Block是HDFS文件系统的最小组成单元,它通 过一个long整数被唯一的标识。默认情况下,数据Block的大小为64MB。Block实现了 Writable接口, 从而可以实现序列化,同时也实现了 Comparable接口,说明它可以比较大小。Block的源代码如下:

1.1成员变量

private long blockid;
//该变量代表数据块的唯一标示符Id。
private long numBytes;
//该变量代表组成块的字节数。
private long generationStamp;
//该变量代表此数据块的生成标记,从1000L开始。

1.2 成员方法

static long filename2id(String name) {
return Long.parseLong(name.substring("blk_".length()));
}

该方法用于将块文件名转化成块的ID。

public static boolean isBlockFilename(File f) {
String name = f.getName();
if ( name.startsWith( "blk_" ) &&
name.indexOf( "." ) < 0 ) {
return true;
} else {
return false;
}
}

该方法用于判断一个文件是否为块文件,块文件的命名规则是以“blk_”开头,后面跟块Id即一个 长整数,而且名称中不含有“.”。
Block中的其他方法都是与上面的成员变量相对应的set和get方法,以及Writable接口和Comparable 接口的实现方法。

2 DatanodeID类

DatanodelD 所在的包为 org.apache.hadoop.hd&protocol,该类用于唯一标识一个 Datanode。Datanode 的源代码如下:

2.1 成员变量

public String name;
//该变量使用主机名:端口号的格式来表示Datanode的ID名称。
public String storagelD;
//该变量代表存储介质ID。不同的集群会有不同的存储介质ID.
protected int infoPort;
//该变量代表infbserver服务器运行时所使用的的端口号。
public int ipcPort;
//该变量代表ipcserver服务器运行时所使用的的端口号。NameNode和Datanode进行连接时,或者是 Datanode之间通讯的时候会使用这个端口号。

2.2 成员方法

这个类主要定义了这个Datanode的HostName、Port, infoPort和ipcPort这些变量相关的set和get 方法。

public int hashCode() {
return name.hashCode()^ storageID.hashCode();
}

hashCode 是通过 name.hashCode()与 storagelD.hashCode()直接的异或来生成的。

public int compareTo(DatanodelD that) {
return name.compareTo(that.getName());
}

当进行两个DatanodelD的比较的时候,主要是比较他们的name.

public void updateRegInfo(DatanodeID nodeReg) {
name = nodeReg.getName();
infoPort = nodeReg.getInfoPort();
ipcPort = nodeReg.getIpcPort();
}

从该方法可以看出DatanodelD对象的域的更新只能更新它的Name和它的infoPort两项内容,而 storagelD是不可更新的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值