1.概述

  这篇博客接着《Hadoop2源码分析-RPC机制初识》来讲述,前面我们对MapReduce、序列化、RPC进行了分析和探索,对Hadoop V2的这些模块都有了大致的了解,通过对这些模块的研究,我们明白了MapReduce的运行流程以及内部的实现机制,Hadoop的序列化以及它的通信机制(RPC)。今天我们来研究另一个核心的模块,那就是Hadoop的分布式文件存储系统——HDFS,下面是今天分享的内容目录:

  • HDFS简述
  • NameNode
  • DataNode

  接下来,我们开始今天的分享内容。

2.HDFS简述

  HDFS全称Hadoop Distributed File System,在HDFS中有几个基本的概念,首先是它的数据块(Block),HDFS的设计是用于支持大文件的。运行在HDFS上的程序也是用于处理大数据集的。这些程序仅写一次数据,一次或多次读数据请求,并且这些读操作要求满足流式传输速度。HDFS支持文件的一次写多次读操作。HDFS中典型的块大小是64MB,一个HDFS文件可以被被切分成多个64MB大小的块,如果需要,每一个块可以分布在不同的数据节点上。HDFS 中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间。

  HDFS提供了一个可操作文件系统的抽象类org.apache.hadoop.fs.FileSystem,该类被划分在Hadoop-Common部分,其源码地址为:hadoop-2.6.0-src/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java,如下是FileSystem的部分源码,如下所示:

@InterfaceAudience.Public
@InterfaceStability.Stable
public abstract class FileSystem extends Configured implements Closeable {
// 代码内容省略
// ...
}

  我们可以使用着抽象类,去操作HDFS系统上的内容,实现代码如下所示:

private static void dfs() {
FileSystem fs = null;
try {
fs = FileSystem.get(conf);// get file object
FileStatus[] list = fs.listStatus(new Path("/"));// file status list
for (FileStatus file : list) {
LOGGER.info(file.getPath().getName());// print file names
}
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("Get hdfs path has error,msg is " + e.getMessage());
} finally {
try {
if (fs != null) {
fs.close();
}
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("Close fs object has error,msg is " + e.getMessage());
}
}
}

  下面,我们来看另一个概念是元数据节点(Namenode)和数据节点(datanode),这2个是HDFS的核心模块,下面我们分别来看看这2个核心模块。

3.NameNode

  NN节点用来管理文件系统的NameSpace,将所有的文件和文件夹的Meta保存在一个文件系统中,是HDFS中文件目录和文件分配的管理者,保存的重要信息如下所示:

  在HDFS集群上可能包含成百上千个DataNode(简称DN)节点,这些DN节点定时和NameNode(简称NN)节点保持通信,接受NN节点的一些指令,为了减小NN的压力,NN上并不永久存储那个DN上报的数据块信息,而是通过DN上报的状态来更新NN上的映射表信息。DN和NN建立连接后,会和NN保持心跳,心跳返回的信息包含了NN对DN的一些指令信息,如删除数据,复制数据到其他的DN节点。值得注意的是NN不会主动去请求DN,这是一个严格意义上的C/S架构模型,同时,客户端在操作HDFS集群时,DN节点会互相配合,保证数据的一致性。

  NN节点信息存储,部分截图信息如下所示:

4.DataNode

  下面我们来分析一下DN的实现,DN的实现包含以下部分,一部分是对本地Block的管理,另一部分就是和其他的Entity进行数据交互。首先,我们先看本地的Block管理部分。我们在搭建Hadoop集群时,会指定Block的存储路径,我们可以找到配置的存储路径,在hdfs-site.xml文件下,内容路径如下所示:

<property>
<name>dfs.datanode.data.dir</name>
<value>/home/hadoop/data/dfs/data</value>
</property>

  然后,我们进入到DN节点上,找到对应的存储目录,如下图所示:

  这里面in_use.lock的作用是做一个排斥操作,在对应的应用上面加锁。然后current目录存放的是当前有效的Block,进入到current目录后,出现如下图所示的目录:

  VERSION存放着一些文件的Meta,接着还有一系列的Block文件和Meta文件,Block文件是存储了HDFS中的数据的。存储的Block,一个Block在多个DN节点上有备份,其备份参数可以调节,在hdfs-site.xml文件中,属性设置如下所示:

<property>
<name>dfs.replication</name>
<value>3</value>
</property>

  首先,我们来看DateNode的类,部分代码如下所示:

@VisibleForTesting
@InterfaceAudience.Private
public static DataNode createDataNode(String args[], Configuration conf,
SecureResources resources) throws IOException {
DataNode dn = instantiateDataNode(args, conf, resources);// init dn
if (dn != null) {
dn.runDatanodeDaemon();// register to nn and back to dn thread
}
return dn;
}
/** Instantiate a single datanode object, along with its secure resources.
* This must be run by invoking{@link DataNode#runDatanodeDaemon()}
* subsequently.
*/
public static DataNode instantiateDataNode(String args [], Configuration conf,
SecureResources resources) throws IOException {
if (conf == null)
conf = new HdfsConfiguration(); if (args != null) {
// parse generic hadoop options
GenericOptionsParser hParser = new GenericOptionsParser(conf, args);
args = hParser.getRemainingArgs();
} if (!parseArguments(args, conf)) {
printUsage(System.err);
return null;
}
Collection<StorageLocation> dataLocations = getStorageLocations(conf);
UserGroupInformation.setConfiguration(conf);
SecurityUtil.login(conf, DFS_DATANODE_KEYTAB_FILE_KEY,
DFS_DATANODE_KERBEROS_PRINCIPAL_KEY);
return makeInstance(dataLocations, conf, resources);
}
static DataNode makeInstance(Collection<StorageLocation> dataDirs,
Configuration conf, SecureResources resources) throws IOException {
LocalFileSystem localFS = FileSystem.getLocal(conf);
FsPermission permission = new FsPermission(
conf.get(DFS_DATANODE_DATA_DIR_PERMISSION_KEY,
DFS_DATANODE_DATA_DIR_PERMISSION_DEFAULT));
DataNodeDiskChecker dataNodeDiskChecker =
new DataNodeDiskChecker(permission);
List<StorageLocation> locations =
checkStorageLocations(dataDirs, localFS, dataNodeDiskChecker);
DefaultMetricsSystem.initialize("DataNode"); assert locations.size() > 0 : "number of data directories should be > 0";
return new DataNode(conf, locations, resources);// create dn obejct
}
public void runDatanodeDaemon() throws IOException {
blockPoolManager.startAll(); // start dataXceiveServer
dataXceiverServer.start();
if (localDataXceiverServer != null) {
localDataXceiverServer.start();
}
ipcServer.start();
startPlugins(conf);
}
public static void secureMain(String args[], SecureResources resources) {
int errorCode = 0;
try {
StringUtils.startupShutdownMessage(DataNode.class, args, LOG);
DataNode datanode = createDataNode(args, null, resources);
if (datanode != null) {
datanode.join();
} else {
errorCode = 1;
}
} catch (Throwable e) {
LOG.fatal("Exception in secureMain", e);
terminate(1, e);
} finally {
// We need to terminate the process here because either shutdown was called
// or some disk related conditions like volumes tolerated or volumes required
// condition was not met. Also, In secure mode, control will go to Jsvc
// and Datanode process hangs if it does not exit.
LOG.warn("Exiting Datanode");
terminate(errorCode);
}
}
  • Main函数入口

  下面给出DN类的Main函数入口,代码片段如下所示:

 public static void main(String args[]) {
if (DFSUtil.parseHelpArgument(args, DataNode.USAGE, System.out, true)) {
System.exit(0);
} secureMain(args, null);
}

5.总结

  在研究HDFS的相关模块时,这里需要明白各个模块的功能及作用,这里为大家介绍了DN类的部分代码片段,以及给代码片段重要部分添加了代码注释,若是大家需要了解详细的相关流程及代码,可以阅读Hadoop的HDFS部分的源代码。

6.结束语

  这篇博客就和大家分享到这里,如果大家在研究学习的过程当中有什么问题,可以加群进行讨论或发送邮件给我,我会尽我所能为您解答,与君共勉!

Hadoop2源码分析-HDFS核心模块分析的更多相关文章

  1. Mybatis源码学习第六天(核心流程分析)之Executor分析

    今Executor这个类,Mybatis虽然表面是SqlSession做的增删改查,其实底层统一调用的是Executor这个接口 在这里贴一下Mybatis查询体系结构图 Executor组件分析 E ...

  2. 【源码解析】Sharding-Jdbc模块分析

    最新的2.0版本的Sharding-Jdbc版本,由于需要支持动态配置加载,所以最新的模块信息如下: |-sharding-jdbc |-sharding-jdbc-core |-api |-cons ...

  3. Mybatis源码学习第六天(核心流程分析)之Executor分析(补充)

    补充上一章没有讲解的三个Executor执行器; 还是贴一下之前的代码吧;我发现其实有些分析注释还是写在代码里面比较好,方便大家理解,之前是我的疏忽,不好意思 @Override public < ...

  4. Hadoop2源码分析-MapReduce篇

    1.概述 前面我们已经对Hadoop有了一个初步认识,接下来我们开始学习Hadoop的一些核心的功能,其中包含mapreduce,fs,hdfs,ipc,io,yarn,今天为大家分享的是mapred ...

  5. Hadoop2源码分析-Hadoop V2初识

    1.概述 在完成分析Hadoop2源码的准备工作后,我们进入到后续的源码学习阶段.本篇博客给大家分享,让大家对Hadoop V2有个初步认识,博客的目录内容如下所示: Hadoop的渊源 Hadoop ...

  6. Hadoop2源码分析-YARN 的服务库和事件库

    1.概述 在<Hadoop2源码分析-YARN RPC 示例介绍>一文当中,给大家介绍了YARN 的 RPC 机制,以及相关代码的演示,今天我们继续去学习 YARN 的服务库和事件库,分享 ...

  7. Hadoop2源码分析-RPC机制初识

    1.概述 上一篇博客,讲述Hadoop V2的序列化机制,这为我们学习Hadoop V2的RPC机制奠定了基础.RPC的内容涵盖的信息有点多,包含Hadoop的序列化机制,RPC,代理,NIO等.若对 ...

  8. Hadoop2源码分析-YARN RPC 示例介绍

    1.概述 之前在<Hadoop2源码分析-RPC探索实战>一文当中介绍了Hadoop的RPC机制,今天给大家分享关于YARN的RPC的机制.下面是今天的分享目录: YARN的RPC介绍 Y ...

  9. Hadoop2源码分析-RPC探索实战

    1.概述 在<Hadoop2源码分析-RPC机制初识>博客中,我们对RPC机制有了初步的认识和了解,下面我们对Hadoop V2的RPC机制做进一步探索,在研究Hadoop V2的RPC机 ...

随机推荐

  1. Django-ConttentType

    一 content-type 在django中,有一个记录了项目中所有model元数据的表,就是ContentType,表中一条记录对应着一个存在的model,所以可以通过一个ContentType表 ...

  2. 线程的使用方法start run sleep join

    今天回顾了Java的线程的一些知识 例1:下面代码存有详细的解释 主要是继承Thread类与实现Runnable接口 以及start()和run()方法 package com.date0607; / ...

  3. How to configure Samba Server share on Debian 9 Stretch Linux

    Lubos Rendek Debian 13 June 2017 Contents 1. Objective 2. Operating System and Software Versions 3.  ...

  4. centos7 安装maven

    进入指定目录 cd /usr/local/src/   下载maven 包 wget http://mirrors.hust.edu.cn/apache/maven/maven-3/3.1.1/bin ...

  5. Vue post提交

    vue中的axios 是不直接支持post方法的,所以我们得绕一下路,我目前在登录的时候运用到了,服务器端用php,可以收到数据 let param = new URLSearchParams(); ...

  6. 79、iOS 的Cocoa框架、Foundation框架以及UIKit框架

    Cocoa框架是iOS应用程序的基础 1. Cocoa是什么? Cocoa是 OS X和ios 操作系统的程序的运行环境. 是什么因素使一个程序成为Cocoa程序呢?不是编程语言,因为在Cocoa开发 ...

  7. 1-学习tecplot360

    FETRIANGLE(3节点三角形), FEQUADRILATERAL(4节点四边形),FETETRAHEDRON(4节点四面体), FEBRICK(8节点六面体) 参考:https://wenku. ...

  8. JAVA 8 主要新特性 ----------------(一)总纲

    一.版本中数据结构的修改浅析 二.JDK1.8优点概括 三.新功能Lambda表达式入门 四.Lambda函数式接口 五.Lambda方法引用与构造器引用 六.集合Stream API 七.新时间日期 ...

  9. Unity全面的面试题(包含答案)

    一:什么是协同程序? 在主线程运行的同时开启另一段逻辑处理,来协助当前程序的执行,协程很像多线程,但是不是多线程,Unity的协程实在每帧结束之后去检测yield的条件是否满足. 二:Unity3D中 ...

  10. InstallShield 创建 visual studio 工程的时候 指向 任意 visual studio 版本 方法 (修改 计算机 默认 visual studio shell 版本)

    这需要 修改 计算机 默认 visual studio shell 版本 注册表 HKEY_CLASSES_ROOT VisualStudio.DTE 配置节点 描述的是 默认的 visual stu ...