这是一篇最通熟易懂的Hadoop HDFS实践攻略!

大数据 Hadoop
以下是HDFS的基础内容,希望可以帮助您快速熟悉HDFS的思路和使用方式。

[[191824]]

本文主要帮您解决一下几个问题:

  • HDFS是用来解决什么问题?怎么解决的?
  • 如何在命令行下操作HDFS?
  • 如何使用Java API来操作HDFS?
  • 在了解基本思路和操作方法后,进一步深究HDFS具体的读写数据流程

学习并实践本文教程后,可以对HDFS有比较清晰的认识,并可以进行熟练操作,为后续学习Hadoop体系打好基础。

目录:

理论部分

  1. HDFS 基本原理
  2. 文件读取、写入机制
  3. 元数据管理思路

实践部分

  1. 安装实践环境
  2. Shell 命令行操作方式
  3. Java API操作方式

一、HDFS基本原理

HDFS(Hadoop Distribute File System)是一个分布式文件系统,是Hadoop的重要成员。

1、文件系统的问题

文件系统是操作系统提供的磁盘空间管理服务,只需要我们制定把文件放到哪儿,从哪个路径读取文件就可以了,不用关心文件在磁盘上是如何存放的。

当文件所需空间大于本机磁盘空间时,如何处理呢?

一是加磁盘,但是加到一定程度就有限制了;二是加机器,用远程共享目录的方式提供网络化的存储,这种方式可以理解为分布式文件系统的雏形,可以把不同文件放入不同的机器中,空间不足了可继续加机器,突破了存储空间的限制。但这个方式有多个问题:

  • 单机负载可能极高例如某个文件是热门,很多用户经常读取这个文件,就使得次文件所在机器的访问压力极高。
  • 数据不安全如果某个文件所在的机器出现故障,这个文件就不能访问了,可靠性很差。
  • 文件整理困难例如想把一些文件的存储位置进行调整,就需要看目标机器的空间是否够用,并且需要自己维护文件位置,如果机器非常多,操作就极为复杂。

2、HDFS的解决思路

HDFS是个抽象层,底层依赖很多独立的服务器,对外提供统一的文件管理功能,对于用户来讲,感觉就像在操作一台机器,感受不到HDFS下面的多台服务器。

例如用户访问HDFS中的/a/b/c.mpg这个文件,HDFS负责从底层相应服务器中读取,然后返回给用户,这样用户只需和HDFS打交道,不关心这个文件是怎么存储的。

例如用户需要保存一个文件/a/b/xxx.avi。

HDFS首先会把这个文件进行分割,例如分为4块,然后分别放到不同服务器上。

这样做有个好处,不怕文件太大,并且读文件的压力不会全部集中在一台服务器上。但如果某台服务器坏了,文件就读不全了。

HDFS为保证文件可靠性,会把每个文件块进行多个备份:

块1:A B C

块2:A B D

块3:B C D

块4:A C D

这样文件的可靠性就大大增强了,即使某个服务器坏了,也可以完整读取文件。

同时还带来一个很大的好处,就是增加了文件的并发访问能力,比如多个用户读取这个文件时,都要读块1,HDFS可以根据服务器的繁忙程度,选择从那台服务器读块1。

3、元数据的管理

HDFS中存了哪些文件?

文件被分成了哪些块?

每个块被放在哪台服务器上?

……

这些都叫做元数据,这些元数据被抽象为一个目录树,记录了这些复杂的对应关系。这些元数据由一个单独的模块进行管理,这个模块叫做NameNode。存放文件块的真实服务器叫做DataNode,所以用户访问HDFS的过程可以理解为:

用户-> HDFS -> NameNode -> DataNode

4、HDFS优点

容量可以线性扩展

有副本机制,存储可靠性高,吞吐量增大

有了NameNode后,用户访问文件只需指定HDFS上的路径

二、HDFS实践

经过上面介绍,可以对HDFS有个基本的了解,下面开始进行实际操作,在实践中更好的认识HDFS。

1、安装实践环境

您可以选择自己搭建环境,也可以使用打包好的Hadoop环境(版本2.7.3)

这个Hadoop环境实际上是一个虚机镜像,所以需要安装virtualbox虚拟机、vagrant镜像管理工具,和我的Hadoop镜像,然后用这个镜像启动虚机就可以了,下面是具体操作步骤:

1)安装virtualbox

下载地址:https://www.virtualbox.org/wiki/Downloads

2)安装vagrant

因为官网下载较慢,我上传到了云盘

Windows版

链接: https://pan.baidu.com/s/1pKKQGHl

密码: eykr

Mac版

链接: https://pan.baidu.com/s/1slts9yt

密码: aig4

安装完成后,在命令行终端下就可以使用vagrant命令。

3)下载Hadoop镜像

链接: https://pan.baidu.com/s/1bpaisnd

密码: pn6c

4)启动

加载Hadoop镜像

vagrant box add {自定义镜像名称} {镜像所在路径}

例如您想命名为Hadoop,镜像下载后的路径为d:\hadoop.box,加载命令就是这样:

vagrant box add hadoop d:\hadoop.box

创建工作目录,例如d:\hdfstest。

进入此目录,初始化

  1. cd d:\hdfstest 
  2. vagrant init hadoop 

启动虚机

  1. vagrant up 

启动完成后,就可以使用SSH客户端登录虚机了

IP 127.0.0.1

端口 2222

用户名 root

密码 vagrant

登录后使用命令ifconfig 查看本虚机的IP(如192.168.31.239),可以使用此IP和端口22登录了

IP 192.168.31.239

端口 22

用户名 root

密码 vagrant

Hadoop服务器环境搭建完成。

2、Shell命令行操作

登录Hadoop服务器后,先启动HDFS,执行命令:

  1. start-dfs.sh 

查看帮助

  1. hdfs dfs –help 

显示目录信息

-ls 后面是要查看的目录路径

创建目录

创建目录/test

  1. hdfs dfs -mkdir /test 

一次创建多级目录/aa/bb

  1. hdfs dfs -mkdir -p /aa/bb 

上传文件

形式

hdfs dfs -put {本地路径} {hdfs中的路径}

实例(先创建好一个测试文件mytest.txt,内容随意,然后上传到/test)

  1. hadoop fs -put ~/mytest.txt /test 

显示文件内容

  1. hdfs dfs -cat /test/mytest.txt 

下载文件

  1. hdfs dfs -get /test/mytest.txt ./mytest2.txt 

合并下载

先创建2个测试文件(log.access, log.error),内容随意,使用-put上传到/test目录下

  1. hdfs dfs -put log.* /test 

然后把2个log文件合并下载到一个文件中

  1. hdfs dfs -getmerge /test/log.* ./log 

查看本地log文件内容,应该包含log.access与log.error两个文件的内容。

复制

从HDFS的一个路径拷贝HDFS的另一个路径

  1. hdfs dfs -cp /test/mytest.txt /aa/mytest.txt.2 

验证

  1. hdfs dfs -ls /aa 

移动文件

  1. hdfs dfs -mv /aa/mytest.txt.2 /aa/bb 

验证

  1. hdfs dfs -ls /aa/bb 

应列出mytest.txt.2。

删除

  1. hdfs dfs -rm -r /aa/bb/mytest.txt.2 

使用-r参数可以一次删除多级目录。

验证

  1. hdfs dfs -ls /aa/bb 

应为空

修改文件权限

与Linux文件系统中的用法一样,修改文件所属权限

  1. -chgrp 
  2.  
  3. -chmod 
  4.  
  5. -chown 

示例

  1. hdfs dfs -chmod 666 /test/mytest.txt 
  2.  
  3. hdfs dfs -chown someuser:somegrp /test/mytest.txt 

统计文件系统的可用空间

  1. hdfs dfs -df -h / 

统计文件夹的大小

  1. hdfs dfs -du -s -h /test 

3、Java API操作

(1)环境配置

因为需要在本机链接Hadoop虚机服务器,所以需要配置Hadoop,使其可以被外部访问。

先登录Hadoop虚机服务器,然后:

1)查看本机IP

  1. ip address 

例如IP为:192.168.31.239

2)修改文件:

  1. vi /usr/local/hadoop-2.7.3/etc/hadoop/core-site.xml 
  2.  
  3. fs.defaultFS 
  4.  
  5. hdfs://localhost:9000 

把其中的localhost:9000修改为本机IP 192.168.31.239:9000

3)重新启动HDFS

#停止

  1. stop-dfs.sh 

#启动

start-dfs.sh

(2)搭建开发环境

1)新建项目目录hdfstest

2)在项目目录下创建pom.xml

内容:

3)创建源码目录src/main/java

现在项目目录结构

  1. ├── pom.xml 
  2.  
  3. !"" src 
  4.  
  5. │ └── main 
  6.  
  7. │ └── java 

(3)示例代码

查看文件列表ls

1)新建文件src/main/java/Ls.java

列出/下的文件列表,及递归获取所有文件

2)编译执行

  1. mvn compile 
  2.  
  3. mvn exec:java -Dexec.mainClass="Ls" -Dexec.cleanupDaemonThreads 
  4.  
  5. =false 

创建目录mkdir

在HDFS中创建目录/mkdir/a/b

1)新建文件

  1. src/main/java/Mkdir.java 

2)编译执行

  1. mvn compile 
  2.  
  3. mvn exec:java -Dexec.mainClass="Mkdir" -Dexec.cleanupDaemonThre 
  4.  
  5. ads=false 

3)在服务器中使用HDFS命令验证

  1. hdfs dfs -ls /mkdir 

上传文件put

在当前项目目录下新建测试文件,上传到HDFS中的/mkdir

1)在项目目录下创建测试文件testfile.txt,内容随意

2)新建文件src/main/java/Put.java

3)编译执行

  1. mvn compile 
  2. mvn exec:java -Dexec.mainClass="Put" -Dexec.cleanupDaemonThread  
  3. s=false 

4)在服务器中使用HDFS命令验证

  1. hdfs dfs -ls /mkdir 
  2. hdfs dfs -cat /mkdir/testfile.txt 

下载文件get

1)新建文件src/main/java/Get.java

把HDFS中/mkdir/testfile.txt下载到当前项目目录下

2)编译执行

  1. mvn compile 
  2. mvn exec:java -Dexec.mainClass="Get" -Dexec.cleanupDaemonThread 
  3. s=false 

3)查看项目目录下是否存在testfile2.txt及其内容

删除文件delete

删除HDFS上之前上传的/mkdir/testfile.txt

1)新建文件src/main/java/Del.java

2)编译执行

  1. mvn compile 
  2. mvn exec:java -Dexec.mainClass="Del" -Dexec.cleanupDaemonThread 
  3. s=false 

3)在服务器中使用HDFS命令验证,检查testfile.txt是否被删除

  1. hdfs dfs -ls /mkdir 

重命名rename

把HDFS中的/mkdir/a重命名为/mkdir/a2

1)新建文件src/main/java/Rename.java

2)编译执行

  1. mvn compile  
  2. mvn exec:java -Dexec.mainClass="Rename" -Dexec.cleanupDaemonThr  
  3. eads=false 

3)在服务器中使用HDFS命令验证

  1. hdfs dfs -ls /mkdir 

流方式读取文件部分内容

上传一个文本文件,然后使用流方式读取部分内容保存到当前项目目录。

1)在服务器中创建一个测试文件test.txt,内容:

  1. 123456789abcdefghijklmn 

上传到HDFS

  1. hdfs dfs -put test.txt / 

2)在本地项目中新建文件src/main/java/StreamGet.java

2)编译执行

  1. mvn compile 
  2. mvn exec:java -Dexec.mainClass="StreamGet" -Dexec.cleanupDaemon 
  3. Threads=false 

3)执行后查看项目目录下的test.txt.part2

  1. 6789abcdefghijklmn 

前面的12345已经被略过

三、深入了解

1、写入机制

向HDFS中写入文件时,是按照块儿为单位的,client会根据配置中设置的块儿的大小把目标文件切为多块,例如文件是300M ,配置中块大小值为128M,那么就分为3块儿。

具体写入流程:

client向namenode发请求,说想要上传文件

namenode会检查目标文件是否存在、父目录是否存在,检查没有问题后返回确认信息

client再发请求,问***个block应该传到哪些datanode上

namenode经过衡量,返回3个可用的datanode(A,B,C)

client与A建立连接,A与B建立连接,B与C建立连接,形成一个pipeline

传输管道建立完成后,client开始向A发送数据包,此数据包会经过管道一次传递到B和C

当***个block的数据都传完以后,client再向namenode请求第二个block上传到哪些datanode,然后建立传输管道发送数据

就这样,直到client把文件全部上传完成

大数据

2、读取机制

Client把要读取的文件路径发给namenode,查询元数据,找到文件块所在的datanode服务器

Client直到了文件包含哪几块儿、每一块儿在哪些datanode上,就选择那些离自己进的datanode(在同一机房,如果有多个离着近的,就随机选择),请求简历socket流

从datanode获取数据

Client接收数据包,先本地缓存,然后写入目标文件

直到文件读取完成

3、NameNode机制

通过对HDFS读写流程的了解,可以发现namenode是一个很重要的部分,它记录着整个HDFS系统的元数据,这些元数据是需要持久化的,要保存到文件中。

Namenode还要承受巨大的访问量,client读写文件时都需要请求namenode,写文件时要修改元数据,读文件时要查询元数据。

为了提高效率,namenode便将元数据加载到内存中,每次修改时,直接修改内存,而不是直接修改文件,同时会记录下操作日志,供后期修改文件时使用。

这样,namenode对数据的管理就涉及到了3种存储形式:

  1. 内存数据
  2. 元数据文件
  3. 操作日志文件

namenode需要定期对元数据文件和日志文件进行整合,以保证文件中数据是新的,但这个过程很消耗性能,namenode需要快速地响应client的大量请求,很难去完成文件整合操作,这时就引入了一个小助手secondnamenode。

secondnamenode会定期从namenode中下载元数据文件和操作日志,进行整合,形成新的数据文件,然后传回namenode,并替换掉之前的旧文件。

secondnamenode是namenode的好帮手,替namenode完成了这个重体力活儿,并且还可以作为namenode的一个防灾备份,当namenode数据丢失时,secondnamenode上有最近一次整理好的数据文件,可以传给namenode进行加载,这样可以保证最少的数据丢失。

 

小结

HDFS的基础内容介绍完了,希望可以帮助您快速熟悉HDFS的思路和使用方式。

责任编辑:武晓燕 来源: 36大数据
相关推荐

2016-03-25 09:59:38

性能调优LinuxMySQL

2022-07-14 14:18:59

Kubernetes架构

2022-07-06 08:17:50

C 语言函数选型

2019-12-13 16:19:15

戴尔

2021-10-11 11:08:33

HDFS快照系统

2020-03-13 14:20:02

代码开发 Rust

2021-07-29 07:55:20

React实践代码

2024-01-09 12:06:55

MVCC并发控制MySQL

2021-07-08 07:30:13

Webpack 前端Tree shakin

2022-03-04 08:17:53

PageRank网络等级

2020-08-11 10:40:31

装饰者模式Java组件

2022-08-01 08:18:58

网络网络协议

2024-05-11 07:56:07

编程语言Java字节码

2022-09-20 07:33:15

Jenkinshttps://mp

2022-12-05 08:17:51

FramerMotion动画

2019-04-08 20:20:37

2022-04-19 08:25:14

区块链

2021-09-07 09:20:44

Hadoop数据容错

2023-09-01 14:02:25

用户分析攻略

2021-11-12 07:43:34

版本HDFS工具
点赞
收藏

51CTO技术栈公众号