• 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。

进入此目录,初始化

cd d:\hdfstest

vagrant init hadoop

启动虚机

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,执行命令:

start-dfs.sh

  • 查看帮助

hdfs dfs –help

显示目录信息

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

创建目录

创建目录/test

hdfs dfs -mkdir /test

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

hdfs dfs -mkdir -p /aa/bb

  • 上传文件

形式

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

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

hadoop fs    -put       ~/mytest.txt /test

  • 显示文件内容

hdfs dfs -cat /test/mytest.txt

  • 合并下载

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

hdfs dfs -put log.* /test

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

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

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

  • 复制

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

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

验证

hdfs dfs -ls /aa

  • 移动文件

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

验证

hdfs dfs -ls /aa/bb

应列出mytest.txt.2。

  • 删除

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

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

验证

hdfs dfs -ls /aa/bb

应为空

  • 修改文件权限

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

-chgrp

-chmod

-chown

示例

hdfs dfs -chmod 666 /test/mytest.txt

hdfs dfs -chown someuser:somegrp /test/mytest.txt

  • 统计文件系统的可用空间

hdfs dfs -df -h /

  • 统计文件夹的大小

hdfs dfs -du -s -h /test

3、Java API操作

(1)环境配置

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

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

1)查看本机IP

ip address

例如IP为:192.168.31.239

2)修改文件:

vi /usr/local/hadoop-2.7.3/etc/hadoop/core-site.xml

<property>

<name>fs.defaultFS</name>

<value>hdfs://localhost:9000</value>

</property>

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

3)重新启动HDFS

#停止

stop-dfs.sh

#启动

start-dfs.sh

(2)搭建开发环境

)新建项目目录hdfstest

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

内容:

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

现在项目目录结构

├── pom.xml

!”” src

│     └── main

│     └── java

(3)示例代码

查看文件列表ls

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

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

2)编译执行

mvn compile

mvn exec:java -Dexec.mainClass=”Ls” -Dexec.cleanupDaemonThreads

=false

创建目录mkdir

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

1)新建文件

src/main/java/Mkdir.java

2)编译执行

mvn compile

mvn exec:java -Dexec.mainClass=”Mkdir” -Dexec.cleanupDaemonThre

ads=false

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

hdfs dfs -ls /mkdir

上传文件put

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

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

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

3)编译执行

mvn compile

mvn exec:java -Dexec.mainClass=”Put” -Dexec.cleanupDaemonThread

s=false

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

hdfs dfs -ls /mkdir

hdfs dfs -cat /mkdir/testfile.txt

下载文件get

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

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

2)编译执行

mvn compile

mvn exec:java -Dexec.mainClass=”Get” -Dexec.cleanupDaemonThread

s=false

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

删除文件delete

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

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

2)编译执行

mvn compile

mvn exec:java -Dexec.mainClass=”Del” -Dexec.cleanupDaemonThread

s=false

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

hdfs dfs -ls /mkdir

重命名rename

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

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

2)编译执行

mvn compile

mvn exec:java -Dexec.mainClass=”Rename” -Dexec.cleanupDaemonThr

eads=false

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

hdfs dfs -ls /mkdir

流方式读取文件部分内容

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

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

123456789abcdefghijklmn

上传到HDFS

hdfs dfs -put test.txt /

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

2)编译执行

mvn compile

mvn exec:java -Dexec.mainClass=”StreamGet” -Dexec.cleanupDaemon

Threads=false

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

6789abcdefghijklmn

前面的12345已经被略过

三、深入了解

1、写入机制

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

具体写入流程:

  1. client向namenode发请求,说想要上传文件
  2. namenode会检查目标文件是否存在、父目录是否存在,检查没有问题后返回确认信息
  3. client再发请求,问第一个block应该传到哪些datanode上
  4. namenode经过衡量,返回3个可用的datanode(A,B,C)
  5. client与A建立连接,A与B建立连接,B与C建立连接,形成一个pipeline
  6. 传输管道建立完成后,client开始向A发送数据包,此数据包会经过管道一次传递到B和C
  7. 当第一个block的数据都传完以后,client再向namenode请求第二个block上传到哪些datanode,然后建立传输管道发送数据
  8. 就这样,直到client把文件全部上传完成

2、读取机制

  1. Client把要读取的文件路径发给namenode,查询元数据,找到文件块所在的datanode服务器
  2. Client直到了文件包含哪几块儿、每一块儿在哪些datanode上,就选择那些离自己进的datanode(在同一机房,如果有多个离着近的,就随机选择),请求简历socket流
  3. 从datanode获取数据
  4. Client接收数据包,先本地缓存,然后写入目标文件
  5. 直到文件读取完成

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的思路和使用方式。如有批评与建议(例如内容有误、不足的地方、改进建议等),欢迎留言讨论。

文章来自微信公众号:DBAplus社群

最通熟易懂的Hadoop HDFS实践攻略的更多相关文章

  1. JVM,Java虚拟机基础知识新手入门教程(超级通熟易懂)

    作者:请叫我红领巾,转载请注明出处http://www.cnblogs.com/xxzhuang/p/7453746.html,简书地址:http://www.jianshu.com/p/b963b3 ...

  2. EJB初识(通熟易懂)

    转载自http://blog.csdn.net/jojo52013145/article/details/5783677,讲的很透彻,佩服,膜拜学习 1. 我们不禁要问,什么是"服务集群&q ...

  3. stl的实现原理简单讲解,通熟易懂

    总结 需要经常随机访问请用vector 2.list list就是双向链表,元素也是在堆中存放,每个元素都是放在一块内存中,它的内存空间可以是不连续的,通过指针来进行数据的访问,这个特点使得它的随机存 ...

  4. C#通熟易懂观察者模式

    观察者模式(有时又被称为模型-视图(View)模式.源-收听者(Listener)模式或从属者模式)是软件设计模式的一种.将观察者(watcher)和被观察者(subject)完美分离. 这里讲一个场 ...

  5. Hadoop安全(1)——————美团Hadoop安全实践

    http://tech.meituan.com/hadoop-security-practice.html 前言 在2014年初,我们将线上使用的 Hadoop 1.0 集群切换到 Hadoop 2. ...

  6. 【转】Hadoop安全实践

    前言 在2014年初,我们将线上使用的 Hadoop 1.0 集群切换到 Hadoop 2.2.0 稳定版, 与此同时部署了 Hadoop 的安全认证.本文主要介绍在 Hadoop 2.2.0 上部署 ...

  7. 我要进大厂之大数据Hadoop HDFS知识点(2)

    01 我们一起学大数据 老刘继续分享出Hadoop中的HDFS模块的一些高级知识点,也算是对今天复习的HDFS内容进行一次总结,希望能够给想学大数据的同学一点帮助,也希望能够得到大佬们的批评和指点! ...

  8. Hadoop HDFS 用户指南

    This document is a starting point for users working with Hadoop Distributed File System (HDFS) eithe ...

  9. Hadoop HDFS负载均衡

    Hadoop HDFS负载均衡 转载请注明出处:http://www.cnblogs.com/BYRans/ Hadoop HDFS Hadoop 分布式文件系统(Hadoop Distributed ...

随机推荐

  1. PAT 甲级 1015 Reversible Primes(20)

    1015 Reversible Primes(20 分) A reversible prime in any number system is a prime whose "reverse& ...

  2. andorid UI事件 监听器

    gridlayout.xml <?xml version="1.0" encoding="utf-8"?> <GridLayout xmlns ...

  3. hdu 1541 (基本树状数组) Stars

    题目http://acm.hdu.edu.cn/showproblem.php?pid=1541 n个星星的坐标,问在某个点左边(横坐标和纵坐标不大于该点)的点的个数有多少个,输出n行,每行有一个数字 ...

  4. PhpStorm 不停地 updating indices

    问题描述: 环境:PhpStorm 框架: Laravel 5.0, php artisan make:test bar.foo 之后,PhpStorm 一直不停地 Updating indices ...

  5. APICloud开发

    2018-06-16 今天在看房角石APPIOS版本闪退的问题,后来定位到了 elements.find("video").attr("preload", &q ...

  6. apicloud模块开发知识点

    1. 没有加模块的时候dex里面的包 \android\support\annotation \android\support\v4 \com\uzmap\pkg \compile 2. 不能混淆的类 ...

  7. rap2与postman自动化测试

    rap2的接口数据可以全部导入postman: 在collections集合里面点击run;

  8. centos7构建python2.7常用开发环境

    把下面的代码保存到一个sh文件中执行即可 yum -y install epel-release yum -y install python-pip yum -y install mysql-deve ...

  9. jsp页面错误的全局处理

    网上搜索spring mvc项目全局异常处理: 大致可以找到两种方案 : 方案1: ExceptionHandlerResolver . spring 提供了两种默认实现,当然你也可以自己实现.. 方 ...

  10. JDK8集合类源码解析 - HashSet

    HashSet 特点:不允许放入重复元素 查看源码,发现HashSet是基于HashMap来实现的,对HashMap做了一次“封装”. private transient HashMap<E,O ...