如何进行HDFS的特性和JavaAPI源码分析

58次阅读
没有评论

共计 6418 个字符,预计需要花费 17 分钟才能阅读完成。

如何进行 HDFS 的特性和 JavaAPI 源码分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

1.HDFS 概览

HDFS 是一个 Apache Software Foundation 项目,是 Apache Hadoop 项目的一个子项目。Hadoop 非常适于存储大型数据(比如 terabytes 和 petabytes),并使用 HDFS 作为其存储系统。HDFS 允许您连接多个集群中包含的节点(普通个人计算机),那些集群上分布着一些数据文件。然后您可以将那些数据文件作为一个无缝文件系统来进行访问和存储。对数据文件的访问通过一种流线型(streaming)方式进行处理,这意味着应用程序或命令通过 MapReduce 处理模型直接执行(参见 参考资料)。HDFS 是容错的,且提供对大数据集的高吞吐量访问。

HDFS 与其他分布式文件系统有许多相似点,但也有几个不同点。一个明显的区别是 HDFS 的“一次写入、多次读取(write-once-read-many)”模型,该模型降低了并发性控制要求,简化了数据聚合性,支持高吞吐量访问。

HDFS 的另一个独特的特性是下面这个观点:将处理逻辑放置到数据附近通常比将数据移向应用程序空间更好。

HDFS 将数据写入严格限制为一次一个写入程序。字节总是被附加到一个流的末尾,字节流总是以写入顺序存储。

HDFS 有许多目标,下面是一些最明显的目标:

通过检测故障和应用快速、自动的恢复实现容错性

通过 MapReduce 流进行数据访问

简单可靠的聚合模型

处理逻辑接近数据,而不是数据接近处理逻辑

跨异构普通硬件和操作系统的可移植性

可靠存储和处理大量数据的可伸缩性

通过跨多个普通个人计算机集群分布数据和处理来节约成本

通过分布数据和逻辑到数据所在的多个节点上进行平行处理来提高效率

通过自动维护多个数据副本和在故障发生时自动重新部署处理逻辑来实现可靠性

HDFS 应用程序接口(API)

您可以以多种不同的方法访问 HDFS。HDFS 提供了一个原生 Java™ 应用程序编程接口(API 重点介绍)和一个针对这个 Java API 的原生 C 语言封装器。另外,您可以使用一个 web 浏览器来浏览 HDFS 文件. 例外还有以下可以来访问 HDFS:

如何进行 HDFS 的特性和 JavaAPI 源码分析

2.HDFS 的 SHELL 操作

既然 HDFS 是存取数据的分布式文件系统,那么对 HDFS 的操作,就是文件系统的基本操作,比如文件的创建、修改、删除、修改权限等,文件夹的创建、删除、重命名等。对 HDFS 的操作命令类似于 lLinux 的 shell 对文件的操作,如 ls、mkdir、rm 等。我们执行以下操作的时候,一定要确定 hadoop 是正常运行的,使用 jps 命令确保看到各个 hadoop 进程。SHELL 操作较多,简介见文档 Hadoop-Shell.pdf 还有该链接 http://hadoop.apache.org/docs/r1.0.4/cn/hdfs_shell.html,就不一个一个介绍啦。

3.HDFS 的体系结构和基本概念

我们通过 hadoop shell 上传的文件是存放在 DataNode 的 block 中,通过 linux shell 是看不到文件的,只能看到 block。可以一句话描述 HDFS:把客户端的大文件存放在很多节点的数据块中。在这里,出现了三个关键词:文件、节点、数据块。HDFS 就是围绕着这三个关键词设计的,我们在学习的时候也要紧抓住这三个关键词来学习。

HDFS 由一些互联的节点集群组成,文件和目录驻留在那些节点上。一个 HDFS 集群包含一个节点,称为 NameNode,该节点管理文件系统名称空间并规范客户端对文件的访问。另外,Data node(DataNodes)将数据作为块存储在文件中。HDFS 的架构图如下:

如何进行 HDFS 的特性和 JavaAPI 源码分析

由上图可知: 在  HDFS  中,一个给定的 NameNode 是整个文件系统的管理节点。它维护着整个文件系统的文件目录树,文件 / 目录的元信息和每个文件对应的数据块列表两套数据,Namenode 还将数据块映射到 Data node,处理来自  HDFS  客户端的读写请求。 Data node  还根据  Name node  的指令创建、删除和复制数据块。

3.1 NameNode

  其中的文件放在指定目录(有配置文件 core-site.xml 的 dfs.name.dir 属性决定). 在该目录下包括:

fsimage: 元数据镜像文件。存储某一时段 NameNode 内存元数据信息。在内存 …

edits: 操作日志文件。

fstime: 保存最近一次 checkpoint 的时间

    这些的文件保存在 linux 系统下的文件系统下.HDFS 的客户端所有的操作必须经过 NameNode

3.2 DataNode

      提供真实文件的存储服务.

文件块(Block): 最基本的存储单位。对于文件内容而言,一个文件的长度大小是 size,那么从文件的0偏移开始,按照固定的大小,顺序对文件进行划分并编号,划分好的每一个块称一个 Block。HDFS 默认 Block 大小是 128MB(可配置),以一个 256MB 文件,共有 256/128= 2 个 Block.block 本质上是一个逻辑概念,意味着 block 里面不会真正的存储数据,只是划分文件的. 不同于普通文件系统的是,HDFS 中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间.

        在每台主机 Linux 文件系统中都能找到:

     如何进行 HDFS 的特性和 JavaAPI 源码分析

副本(replication): 多副本,默认是三个. 可配置:hdfs-site.xml 中 dfs.replication 的属性. 机柜意识:

通常,大型  HDFS  集群跨多个安装点(机柜)排列。一个安装中的不同节点之间的网络流量通常比跨安装点的网络流量更高效。一个  Name node  尽量将一个块的多个副本放置到多个安装上以提高容错能力。但是,HDFS  允许管理员决定一个节点属于哪个安装点。因此,每个节点都知道它的机柜  ID,也就是说,它具有机柜意识。

3.3 NameNode 元数据的存储信息

      见下图: 就不做解释啦.

如何进行 HDFS 的特性和 JavaAPI 源码分析

3.4 NameNode 和 DataNode 之间的通信机制

Data node 持续循环,询问 Name node 的指令。Name node 不能直接连接到 Data node,它只是从 Data node 调用的函数返回值。每个 Data node 都维护一个开放的服务器套接字,以便客户端代码或其他 Data node 能够读写数据。Name node 知道这个服务器的主机或端口,将信息提供给有关客户端或其他 Data node。所有 HDFS 通信协议都构建于 TCP/IP 协议之上。HDFS 客户端连接到 Name node 上打开的一个 Transmission Control Protocol (TCP) 端口,然后使用一个基于 Remote Procedure Call (RPC) 的专有协议与 Name node 通信。Data node 使用一个基于块的专有协议与 Name node 通信。Hadoop 整个生态系统都是基于 RPC 协议之上的。‍‍‍‍‍‍关于 RPC 的通信原理将例外写一篇博客. 链接。。。‍‍‍‍‍‍

3.5 HDFS 非纯 HA 的一个解决方案 Secondary Name node

实际上, 为了提高整个集群的可靠性和可维护性, 各大公司和社区都提出来很多改进 HDFS 的方案, 在这里, 我就暂时介绍 HDFS 其中的一种, 以后博客会详细描述 HDFS HA 的解决方案,并且进行总结.

Secondary NameNode 通过定期下载 NameNode 的元数据和日志文件, 并进行合并更新, 来对 NameNode 进行备份。当 NameNode 故障时, 可以通过 Secondary NameNode 进行恢复, 但是不足之处在于 Secondary NameNode 的备份知识 NameNode 的 Checkpoint, 并没有与 NameNode 实时同步, 恢复后的数据存在一定的元信息丢失, 由于在恢复过程中存在一段系统不可用的时间, 该方案只能是一种备份方案, 并不是真正意义上的 HA 方案. 该流程图如下:

如何进行 HDFS 的特性和 JavaAPI 源码分析

  NameNode 的执行:

Namenode 始终在内存中保存 metedata,用于处理“读请求”.
等到有“写请求”到来时,namenode 会首先写 editlog 到磁盘,即向 edits 文件中写日志,成功返回后,才会修改内存,并且向客户端返回。Hadoop 会维护一个 fsimage 文件,也就是 namenode 中 metedata 的镜像,但是 fsimage 不会随时与 namenode 内存中的 metedata 保持一致,而是每隔一段时间通过合并 edits 文件来更新内容。有谁来合并呢??---- Secondary namenode 就是用来合并 fsimage 和 edits 文件来更新 NameNode 的 metedata 的。

   Secondary namendoe 的工作流程:

1.secondary 通知 namenode 切换 edits 文件(这时 NameNode 会生成 newedits 文件)
2.secondary 从 namenode 获得 fsimage 和 edits(通过 http)
3.secondary 将 fsimage 载入内存,然后开始合并(以一定的算法)edits
4.secondary 将新的 fsimage 发回给 namenode
5.namenode 用新的 fsimage 替换旧的 fsimage

4.HDFS 中 Java 应用程序接口访问

直接上代码:

HadoopUtil.java
package com.codewatching.hadoop.service;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
 * Hadoop 简单工具类
 * @author LISAI
 */
public class HadoopUtil {public static FileSystem getFileSystem(){
 try {Configuration conf = new Configuration();
 URI uri = new URI( hdfs://yun10-0:9000/ 
 FileSystem fileSystem = FileSystem.get(uri, conf,  lisai 
 return fileSystem;
 } catch (Exception e) {e.printStackTrace();
 return null;
}
HadoopBasicAPIService.java
package com.codewatching.hadoop.service;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
 * Hadoop API 的操作
 * @author LISAI
 */
public class HadoopBasicAPIService {private FileSystem fileSystem = HadoopUtil.getFileSystem();
  *  传统方式 --- 下载
  */
 @Deprecated
 public void downLoadTraditional(String uri,String dest) throws Exception{FSDataInputStream dataInputStream = fileSystem.open(new Path(uri));
 OutputStream outputStream = new FileOutputStream(dest);
 IOUtils.copyBytes(dataInputStream, outputStream, fileSystem.getConf());
  *  常用方式 --- 下载(windows 环境下注意事项)
  */
 public void downLoadSimple(String src,String dest) throws Exception{fileSystem.copyToLocalFile(new Path(src), new Path(dest));
  *  上传  
  * @param src
  * @param dest
  * @throws Exception
  */
 public void upload(String src,String dest) throws Exception{fileSystem.copyFromLocalFile(new Path(src),new Path(dest));
  *  创建文件夹
  * @param makeDir
  * @throws Exception
  */
 public void mkdir(String makeDir) throws Exception{fileSystem.mkdirs(new Path(makeDir));
  *  删除文件夹
  */
 public void deldir(String delDir) throws Exception{fileSystem.delete(new Path(delDir),true);
}

5.HDFS 中 读 文件源码分析

1. 初始化 FileSystem,然后客户端 (client) 用 FileSystem 的 open()函数打开文件
2.FileSystem 用 RPC 调用元数据节点,得到文件的数据块信息,对于每一个数据块,元数据节点返回保存数据块的数据节点的地址。3.FileSystem 返回 FSDataInputStream 给客户端,用来读取数据,客户端调用 stream 的 read()函数开始读取数据。4.DFSInputStream 连接保存此文件第一个数据块的最近的数据节点,data 从数据节点读到客户端(client)
5. 当此数据块读取完毕时,DFSInputStream 关闭和此数据节点的连接,然后连接此文件下一个数据块的最近的数据节点。6. 当客户端读取完毕数据的时候,调用 FSDataInputStream 的 close 函数。7. 在读取数据的过程中,如果客户端在与数据节点通信出现错误,则尝试连接包含此数据块的下一个数据节点。8. 失败的数据节点将被记录,以后不再连接。

如何进行 HDFS 的特性和 JavaAPI 源码分析 

 如何进行 HDFS 的特性和 JavaAPI 源码分析

如何进行 HDFS 的特性和 JavaAPI 源码分析

如何进行 HDFS 的特性和 JavaAPI 源码分析

如何进行 HDFS 的特性和 JavaAPI 源码分析

如何进行 HDFS 的特性和 JavaAPI 源码分析

如何进行 HDFS 的特性和 JavaAPI 源码分析

如何进行 HDFS 的特性和 JavaAPI 源码分析

以下几步,就是如何获取创建和代理对象的过程.. 只有拿到客户端的代理对象,我们才能对 HDFS 进行相关操作。RPC 过程的原理, 以后的博客会有大幅边幅谈论.

如何进行 HDFS 的特性和 JavaAPI 源码分析

如何进行 HDFS 的特性和 JavaAPI 源码分析

如何进行 HDFS 的特性和 JavaAPI 源码分析

如何进行 HDFS 的特性和 JavaAPI 源码分析

如何进行 HDFS 的特性和 JavaAPI 源码分析

dfs===========DFSClient[clientName=DFSClient_NONMAPREDUCE_1386880610_1, ugi=lisai (auth:SIMPLE)]
fs===========DFS[DFSClient[clientName=DFSClient_NONMAPREDUCE_1386880610_1, ugi=lisai (auth:SIMPLE)]]

初始化完毕。。。。。。

如何进行 HDFS 的特性和 JavaAPI 源码分析

如何进行 HDFS 的特性和 JavaAPI 源码分析

如何进行 HDFS 的特性和 JavaAPI 源码分析

如何进行 HDFS 的特性和 JavaAPI 源码分析

如何进行 HDFS 的特性和 JavaAPI 源码分析

中间省略几个方法调用 ……….

如何进行 HDFS 的特性和 JavaAPI 源码分析

这下就拿到了 FSDataInputStream 流到客户端。接下来的步骤就是 COPY 的事啦。

看完上述内容,你们掌握如何进行 HDFS 的特性和 JavaAPI 源码分析的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注丸趣 TV 行业资讯频道,感谢各位的阅读!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-25发表,共计6418字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)