http://zhangjun5965.iteye.com/blog/2377005
概述
hdfs的内部的文件和目录是如何以树的结构存储的,每个文件对应的块是如何存储的,每个块对应的怎么对应到每一个datanode的,这些结构在hdfs的内部源码是用哪些变量存储的,整体结构是怎么连接起来的,下面我们通过Hadoop的最新稳定版代码(2.7.3)来学习一下。
命名空间Namesystem
org.apache.hadoop.hdfs.server.namenode.FSNamesystem类是hdfs的核心,存储了hdfs的命名空间相关的很多东西,具体来说就是为DataNode做簿记工作,所有datanode的请求都经过FSNamesystem类来处理。
具体他做了哪些重要的工作,我们来看相关注释
/***************************************************
* FSNamesystem does the actual bookkeeping work for the
* DataNode.
*
* It tracks several important tables.
*
文件名 -> 数据块(存放在磁盘,也就是FSImage和日志中)
* 1) valid fsname --> blocklist (kept on disk, logged)
合法的数据块列表(上面关系的逆关系)
* 2) Set of all valid blocks (inverted #1)
数据块 -> DataNode(只保存在内存中,根据DataNode发过来的信息动态建立)
* 3) block --> machinelist (kept in memory, rebuilt dynamically from reports)
DataNode上保存的数据块(上面关系的逆关系)
* 4) machine --> blocklist (inverted #2)
通过LRU算法保存最近发送过心跳信息的DataNode
* 5) LRU cache of updated-heartbeat machines
***************************************************/
文件目录管理
/** The namespace tree. */
FSDirectory dir;
private final BlockManager blockManager;
在namenode中,对hdfs的目录以及下面的子目录、文件的操作相当的复杂,会涉及到内存、硬盘的相关操作,还需要和很多对象打交道,FSDirectory主要就是对这个内部的复杂的操作做了一个简单的封装,对外提供一个简单的操作接口。
FSDirectory中很多重要的操作都和ClientProcotol协议中定义的相关方法一一对应,如addBlock等.
FSDirectory对象中有一个非常重要的INodeDirectory类型的变量rootDir,这个变量在内存中保存这个整个hdfs的目录树,下面我们对INode相关的知识做一下介绍。
i-node介绍
linux i-node介绍
在Linux中,inode是一个非常重要的设计,具体我这里就不介绍了,大家可以参考下这个文章。
http://www.ruanyifeng.com/blog/2011/12/inode.html
hdfs的 INode介绍
org.apache.hadoop.hdfs.server.namenode.INode类是整个文件的一个抽象,其子类INodeDirectory和INodeFile分别表示目录和相应的文件,我们来看下具体的类之间的关系
其中,INode的直接子类INodeWithAdditionalFields存储了一个文件或者目录共有的一些东西,如id、名字、访问权限、访问时间等
/** The inode id. */
final private long id;
/**
* The inode name is in java UTF8 encoding;
* The name in HdfsFileStatus should keep the same encoding as this.
* if this encoding is changed, implicitly getFileInfo and listStatus in
* clientProtocol are changed; The decoding at the client
* side should change accordingly.
*/
private byte[] name = null;
/**
* Permission encoded using {@link PermissionStatusFormat}.
* Codes other than {@link #clonePermissionStatus(INodeWithAdditionalFields)}
* and {@link #updatePermissionStatus(PermissionStatusFormat, long)}
* should not modify it.
*/
private long permission = 0L;
/** The last modification time*/
private long modificationTime = 0L;
/** The last access time*/
private long accessTime = 0L;
INodeFile
在INodeFile类的内部,有一个非常重要的变量blocks,以一个数组的的形式保存着这个文件对应的块,具体的BlockInfoContiguous的相关信息将在下节来讲述。
private BlockInfoContiguous[] blocks;
INodeDirectory
INodeDirectory重要就是表示的hdfs中的目录树,和其他文件系统类似,一个目录最重要的就是他的子目录,在该类中,用一个INode类型的集合变量children表示。
private List<INode> children = null;
块管理
hdfs中所有块的管理通过FSNamesystem中的BlockManager变量来管理,主要可以提供一些常用的的服务,比如通过blockid查询块,某一个块位于哪个datanode等等
private final BlockManager blockManager;
BlockManager通过BlocksMap来存储信息
private final Namesystem namesystem;
private final DatanodeManager datanodeManager;
/**
* Mapping: Block -> { BlockCollection, datanodes, self ref }
* Updated only in response to client-sent information.
*/
final BlocksMap blocksMap;
数据块BlockInfoContiguous
接下来我们说说hdfs中块的最重要的 一个类,这个类里最核心的变量是一个Object的数组triplets。
/**
* This array contains triplets of references. For each i-th storage, the
* block belongs to triplets[3*i] is the reference to the
* {@link DatanodeStorageInfo} and triplets[3*i+1] and triplets[3*i+2] are
* references to the previous and the next blocks, respectively, in the list
* of blocks belonging to this storage.
*
* Using previous and next in Object triplets is done instead of a
* {@link LinkedList} list to efficiently use memory. With LinkedList the cost
* per replica is 42 bytes (LinkedList#Entry object per replica) versus 16
* bytes using the triplets.
*/
private Object[] triplets;
/**
* Construct an entry for blocksmap
* @param replication the block's replication factor
*/
public BlockInfoContiguous(short replication) {
this.triplets = new Object[3*replication];
this.bc = null;
}
我们通过代码看到,object数组的长度就是3*replication(3乘以block的副本数),
triplets[i]:存储DatanodeStorageInfo对象,Block所在的DataNode;
triplets[i+1]:存储BlockInfoContiguous对象,该DataNode上该block前一个Block;
triplets[i+2]:存储BlockInfoContiguous,该DataNode上该block后一个Block;
这样通过存储块在DataNode上的上一个和下一个块实现了一个双向链表。就能快速的遍历该datanode上的所有的block,其实就是一个linkedlist,但是按照注释中的说法,要比linkedlist节省空间,对于hdfs这些一个巨大的文件系统来说,每个块存储多一点空间,整体上将会是巨大的开销。
集群中所有的块的管理
集群中所有的块的管理通过BlockManager中BlocksMap类型的对象blocksMap来管理
BlocksMap通过GSet存储映射
private GSet<Block, BlockInfoContiguous> blocks;
GSet是自定义的一个set集合,如下代码所示,E必须是K的子类
/**
* A {@link GSet} is set,
* which supports the {@link #get(Object)} operation.
* The {@link #get(Object)} operation uses a key to lookup an element.
*
* Null element is not supported.
*
* @param <K> The type of the keys.
* @param <E> The type of the elements, which must be a subclass of the keys.
*/
@InterfaceAudience.Private
public interface GSet<K, E extends K> extends Iterable<E>
保存hdfs的块的管理用的是GSet的子类LightWeightGSet.
DatanodeStorageInfo 数据节点存储
在介绍BlockInfoContiguous的时候,我们知道object数组第一项存储的是该块所在的datanode信息,即DatanodeStorageInfo类型的对象。
/**
* A Datanode has one or more storages. A storage in the Datanode is represented
* by this class.
*/
public class DatanodeStorageInfo{
........................
private final DatanodeDescriptor dn;
private final String storageID;
private StorageType storageType; //存储类型,disk,ssd等
private State state;
private long capacity;
private long dfsUsed;
private volatile long remaining;
private long blockPoolUsed;
private volatile BlockInfoContiguous blockList = null;
private int numBlocks = 0;
// The ID of the last full block report which updated this storage.
private long lastBlockReportId = 0;
/** The number of block reports received */
private int blockReportCount = 0;
..............................
}
通过注释,我们了解到一个datanode有不止一个存储,该类所表示的是datanode相关的存储信息。
其中DatanodeDescriptor对象是namenode对datanode的抽象,里面封装了一些datanode基本信息.
DatanodeDescriptor相关的类的继承关系如上图,DatanodeID封装了datanode相关的一些基本信息,如ip,host等。
private String ipAddr; // IP address
private String hostName; // hostname claimed by datanode
private String peerHostName; // hostname from the actual connection
private int xferPort; // data streaming port
private int infoPort; // info server port
private int infoSecurePort; // info server port
private int ipcPort; // IPC server port
private String xferAddr;
总结
通过上面的学习,我们基本捋请了整个hdfs的目录和文件是如何存储的,每个文件包含了哪些数据块,每个数据块存储在哪个datanode上,具体的host和port是多少。
还简单了解了下hdfs是如何通过blockmanage来管理hdfs中所有的数据块
相关推荐
### Hadoop源码分析知识点概览 #### 一、Hadoop概述与背景 - **Google核心技术**:Hadoop的设计理念很大程度上受到了Google一系列核心技术的影响,包括Google File System (GFS)、BigTable以及MapReduce等。这些...
本文将基于“Hadoop学习总结和源码分析”这一主题,结合提供的文档资源,深入探讨Hadoop的核心组件HDFS(Hadoop Distributed File System)和MapReduce。 首先,我们从“Hadoop学习总结之一:HDFS简介.doc”开始,...
本篇文章将围绕"Hadoop源码"这一主题,深度探讨HDFS的底层实现机制,帮助读者从源码层面理解其工作原理。 一、HDFS概述 HDFS是基于Google发表的GFS论文设计的分布式文件系统,旨在处理和存储大量数据。它采用了主从...
### Hadoop源码分析知识点详解 ...综上所述,通过对Hadoop源码的深入分析,我们可以更加全面地了解这一分布式计算平台的内部工作原理和设计理念。这对于实际应用Hadoop解决大规模数据处理问题具有重要意义。
《Hadoop源码分析》是一本深度探讨Hadoop核心组件HDFS和MapReduce的书籍,提供了高清版的PDF格式供读者学习。这本书共分为55章,其中41章专门致力于HDFS(Hadoop分布式文件系统)的解析,剩余14章则详细剖析了...
3. **Hadoop源码结构** Hadoop源码主要分为以下几个部分: - `hadoop-common`:包含了Hadoop的通用工具和库,如网络通信、配置管理、安全认证等。 - `hadoop-hdfs`:实现HDFS的模块,包括NameNode、DataNode和...
二、Hadoop源码结构 Hadoop源代码的组织结构严谨,按照模块和功能进行划分。"org"目录下,包含了Hadoop的主要模块,如hadoop-common(通用模块)、hadoop-hdfs(HDFS模块)、hadoop-mapreduce(MapReduce模块)等。...
第2章 HDFS元数据解析 2.1 概述 2.2 内存元数据结构 2.2.1 INode 2.2.2 Block 2.2.3 BlockInfo和DatanodeDescriptor 2.2.4 小结 2.2.5 代码分析——元数据结构 2.3 磁盘元数据文件 2.4 Format情景分析 2.5 元数据...
Hadoop的核心组件包括HDFS(Hadoop Distributed File System)和MapReduce,前者提供高容错性的分布式文件系统,后者则是一种编程模型,用于大规模数据集的并行计算。在这个课程设计中,学生将学习如何利用Hadoop来...
学习Hadoop源码不仅有助于理解其内部工作原理,还能帮助你在遇到性能问题时进行调优,或者在设计新的分布式系统时借鉴其设计理念。在分析源码的过程中,可以关注类的继承关系、接口实现、线程同步机制等方面,同时...
《Hadoop实战第二版》是由陆嘉恒编著的一本深度解析Hadoop技术的专业书籍,其源码的提供为读者提供了亲自动手实践Hadoop的机会,增强了学习效果。Hadoop作为大数据处理领域的基石,它的核心在于分布式存储系统HDFS...
- **HDFS作为基础**:HDFS是Hadoop生态中的核心组件之一,它是HBase等其他组件的基础,因此深入理解HDFS对于理解整个Hadoop生态系统至关重要。 #### 二、Hadoop项目架构分析 - **包结构及其依赖关系**:Hadoop项目...
2. hadoop-hdfs:实现了HDFS,包括NameNode(元数据管理)、DataNode(数据存储)和Secondary NameNode(元数据备份)的源码。 3. hadoop-mapreduce:实现了MapReduce计算框架,包括JobTracker(任务调度)、...
三、Hadoop源码结构 Hadoop 3.2.4的源代码包含多个模块,如hadoop-common、hadoop-hdfs、hadoop-mapreduce等,每个模块都有其特定的功能。例如: - hadoop-common:包含了Hadoop的公共库,包括网络通信、配置管理...
【标题】"Hadoop简单示例源码"揭示了如何使用Hadoop框架处理大数据的案例。这个示例可能包括从原始数据中计算每年的最高气温,这是Hadoop在数据分析领域中的一个常见应用。 Hadoop是Apache软件基金会开发的一个开源...
### Hadoop源代码分析知识点详解 #### 一、Hadoop背景与关键技术介绍 Hadoop作为一款开源的大数据处理框架,其设计灵感源自Google的一系列核心论文。这些论文详细阐述了Google构建其基础设施的方法论和技术原理,...
二、Hadoop 2.10.0源码结构 源码文件"hadoop-2.10.0-src"包含了许多子项目和模块,如hadoop-common、hadoop-hdfs、hadoop-yarn、hadoop-mapreduce等,这些模块分别对应Hadoop的核心组件和服务。每个模块下都有各自的...
- **HDFS(Hadoop Distributed File System)**:作为Hadoop的核心组件之一,HDFS提供了高吞吐量的数据访问能力,适合处理大量数据集的应用场景。其设计目标是在商用硬件上构建大规模数据集的分布式存储系统,通过...
《Hadoop 3.0.1源码解析与大数据处理技术探析》 Hadoop作为开源的大数据处理框架,自2006年诞生以来,便在大数据领域扮演着核心角色。本文将针对"Hadoop-3.0.1-src.tar.gz"这个压缩包文件进行深入探讨,揭示其背后...