Hadoop-HDFS原理及操作(小实验)

HDFS原理:HDFS(Hadoop Distributed File System)是一个分布式文件系统,是谷歌的GFS山寨版本。它具有高容错性并提供了高吞吐量的数据访问,非常适合大规模数据集上的应用,它提供了一个高度容错性和高吞吐量的海量数据存储解决方案。HDFS文件系统的角色分为三种(Master和Slave的结构,主从节点结构),分为NameNode、Secondary NameNod...
摘要由CSDN通过智能技术生成

HDFS原理:

HDFS(Hadoop Distributed File System)是一个分布式文件系统,是谷歌的GFS山寨版本。它具有高容错性并提供了高吞吐量的数据访问,非常适合大规模数据集上的应用,它提供了一个高度容错性和高吞吐量的海量数据存储解决方案。

HDFS文件系统的角色分为三种(Master和Slave的结构,主从节点结构),分为NameNode、Secondary NameNode和DataNode三种角色:

NameNode:在Hadoop1.X中只有一个主节点,管理HDFS的名称空间和数据块映射信息、配置副本策略和处理客户端请求;在hadoop后续版本中,可以支持多个主节点,若一个出错了整个集群还可以继续运行。

Secondary NameNode:我们可以将它理解为namenode的秘书,辅助NameNode,分担NameNode工作,定期合并fsimage和fsedits并推送给NameNode,紧急情况下可辅助恢复NameNode;

DataNode:Slave节点,实际存储数据、执行数据块的读写并汇报存储信息给NameNode;
HDFS分布式文件存储原理:

HDFS读操作:

在这里插入图片描述
1.客户端发出读取文件的指令(我们常在namenode节点上执行客户端操作),这个指令会先发HDFS的分布式文件系统,分布式文件系统会从主节点上获取该文件各个分块的位置,然后根据算法去得到该文件每一份所处的离文件管理系统最近(网络上最近,最快)的那个datanode的位置。
2.上一步会返回一个文件流对象,这个对象用来管理 datanode 和 namenode 数据流。
3.然后这个对象会调用read()方法去读取相应datanode中的文件,并且将数据从 DataNode 传输到客户端。
4.到达块的末端时,文件流对象会关闭与该 DataNode 的连接,然后寻找下一个块的最佳 DataNode,从客户端的角度来看只是读一个持续不断的流。
5.一旦客户端完成读取,就对 文件流就会关闭文件读取。

HDFS 写操作:

在这里插入图片描述
详细步骤解析:
1、client发起文件上传请求,通过RPC与NameNode建立通讯,NameNode检查目标文件是否已存在,父目录是否存在,返回是否可以上传;
2、client请求第一个block该传输到哪些DataNode服务器上;
3、NameNode根据配置文件中指定的备份数量及机架感知原理进行文件分配,返回可用的DataNode的地址如: A, B, C;
注: Hadoop 在设计时考虑到数据的安全与高效,数据文件默认在HDFS.上存放三份,存储策略为本地一份,同机架内其它某一节点上一份,不同机架的某一节点上一份。
4、client 请求3台DataNode中的一台A上传数据(本质上是一个RPC调用,建立pipeline(管道)),A收到请求会继续调用B,然后B调用C,将整个pipeline(管道)建立完成,后逐级返回client;
5、client开始往A上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位(默认64K), A收到一个packet就会传给B,B传给C; A每传一个packet会放入一个应答队列等待应答。
6、当读完列表的block 后,若文件读取还没有结束,客户端会继续向NameNode获取下一批的block列表;
7、读取完一个block都会进行chefksum验证,如果读取DataNode时出现错误,客户端会通知NameNode, 然后再从下一个拥有该block副本的DataNode继续读。
8、read 方法是并行的读取block信息,不是一块一块的读取; NameNode只是返回Client请求包含块的DataNode地址,并不是返回请求块的数据;
9、最终读取来所有的block会合并成一个完整的最终文件。

HDFS 中的常用命令:

hadoop hdfs指令与我们linux指令基本相同,我们需要注意一下put、get、copyFromLocal这几个指令。
关于指令的查看可以到hadoop官方中文网站(写得很清楚):
http://hadoop.apache.org/docs/r1.0.4/cn/hdfs_shell.html

实验操作:

对hdfs文件操作都大同小异,无非是上传、下载、对文件进行分析处理(采用java,更复杂的操作其实也就是相关java代码的编写)。这里我们只进行一个实验:编译java文件,读取 HDFS 文件内容。
关于HDFS实验操作的网站(大家可以在这个网站上进行操作,初步了解):https://www.shiyanlou.com/courses/237

相关环境:
hadoop 2.7.1(完全分布式)
ubuntu16.04
具体环境配置方法在我上一篇博客中已经给出:Hadoop集群搭建教程(完全分布式)

实验过程

1.创建代码目录
使用如下命令启动 Hadoop:

start-dfs.sh	
star-yarn.sh		//启动资源管理系统
jps	//查看启动的进程,确保 NameNode 和 DataNode 都有启动

在 hadoop主目录下使用如下命令建立 myclass 和 input 目录:

mkdir -p myclass input	// -p 一次可以创建多级文件夹

在这里插入图片描述

2.建立例子文件上传到 HDFS 中
进入 /hadoop/input 目录,在该目录中创建 quangle.txt 文件。

cd input
touch quangle.txt
vi quangle.txt

内容为:

On the top of the Crumpetty Tree
The Quangle Wangle sat,
But his face you could not see,
On account of his Beaver Hat.

使用如下命令在 hdfs 中建立目录 /class4。

hadoop fs -mkdir /class4
hadoop fs -ls /

在这里插入图片描述
注意:我们在hadoop hdfs创建、上传的文件在主机目录上是找不到的,它被hdfs文件系统储存到了各个datanode中,该文件已经被编码成其它格式。我们可以通过hadoop fs -ls /目录或网页客户端形式查看。

把创建好的txt例子文件上传到 hdfs 的 /class4 文件夹中

cd /app/hadoop-1.1.2/input
hadoop fs -copyFromLocal quangle.txt /class4/quangle.txt
hadoop fs -ls /class4

在这里插入图片描述

3.配置本地环境:

3.1 对 /hadoop/ect/hadoop 目录中的 hadoop-env.sh 进行配置,如下所示:

cd etc/hadoop/
sudo vi hadoop-env.sh

加入 HADOOP_CLASPATH 变量值,值为 /xxx/hadoop/myclass,设置完毕后编译该配置文件,使配置生效。
这个文件设置的意思是指定我们要执行的java编译文件的目录,当我们后续使用hadoop java编译文件 hdfs目标文件去对dfs中的文件进行操作时,会自动调用myclass目录下的ava编译文件,否则它会提示找不到。
在这里插入图片描述
3.2.配置java依赖包
我们知道,java文件的编译是需要导入该.java文件import的各种包,而这些包从哪里来呢?
我们的hadoop已经为我们准备了操作hdfs基本的jar包,如果需要进行更复杂的操作,可能得在专业java平台上进行编译。

下面的方案来自http://dblab.xmu.edu.cn/blog/hadoop-build-project-by-shell/

Hadoop 2.x 版本中的依赖 jar(与1.x版本有所不同,这里需要注意一下)
Hadoop 2.x 版本中 jar 不再集中在一个 hadoop-core*.jar 中,而是分成多个 jar,如使用 Hadoop 2.6.0 运行 WordCount 实例至少需要如下三个 jar:

$HADOOP_HOME/share/hadoop/common/hadoop-common-2.6.0.jar
$HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-core-2.6.0.jar
$HADOOP_HOME/share/hadoop/common/lib/commons-cli-1.2.jar

实际上,通过命令 hadoop classpath 我们可以得到运行 Hadoop 程序所需的全部 classpath 信息。
我们将 Hadoop 的 classhpath 信息添加到 CLASSPATH 变量中,在 ~/.bashrc 中增加如下几行:

export HADOOP_HOME=/usr/local/hadoop	//这里是hadoop的安装位置,如果之前配置过可以不用管
export CLASSPATH=$($HADOOP_HOME/bin/hadoop classpath):$CLASSPATH

执行 source ~/.bashrc 使变量生效,接着就可以通过 javac 命令编译java文件了。

4.编写代码
进入 /hadoop/myclass 目录,在该目录中建立 FileSystemCat.java 代码文件,命令如下:

cd /hadoop/myclass/
vi FileSystemCat.java

输入代码内容(学过java的话,可以简单看一下该代码,非常简单):

import java.io.InputStream;

import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;

public class FileSystemCat {
    public static void main(String[] args) throws Exception {
        String uri = args[0];
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem. get(URI.create (uri), conf);
        InputStream in = null;
        try {
            in = fs.open( new Path(uri));
            IOUtils.copyBytes(in, System.out, 4096, false);
        } finally {
            IOUtils.closeStream(in);
        }
    }

5.编译代码
在 /hadoop/myclass 目录中,使用如下命令编译代码:

javac FileSystemCat.java
//因为我们之前已经导入了classpath jar包,所以不用像这样javac -classpath ../hadoop-xxx.jar FileSystemCat.java

执行完成会生成编译好的class文件
在这里插入图片描述
6.使用编译代码读取 HDFS 文件
使用如下命令读取 HDFS 中 /class4/quangle.txt 内容:

hadoop FileSystemCat /class4/quangle.txt

在这里插入图片描述
关于实验操作部分,我这里采用了https://www.shiyanlou.com/courses/237该课程的hdfs实验之一,该课程所用的hadoop版本为1.xx,在我们2.x或3.x上执行会出错,所以部分步骤进行了改变,以上的实验步骤便是我在hadoop2.7.1上的执行过程。

参考:
使用命令行编译打包运行自己的MapReduce程序 Hadoop2.6.0
shiyanlou Hadoop 基础入门

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值