HDFS(Hadoop Distributed File System)Hadoop分布式文件系统。

一、HDFS产生的背景

随着数据量越来越大,如果大到一台主机的磁盘都存放不下,该如何解决这个问题。一种思路是将数据分片放到多台主机上。如果放到多台主机上,又该怎么去管理,如果有些主机宕机了,数据丢失了该如何解决?

这时,就需要一种系统去解决上述问题,来更好地管理多台主机上的数据文件,这种系统就是分布式文件管理系统。

二、HDFS的特点

(1)流式访问数据

一次写入,多次读取。也就是一条数据插入,会复制分发到不同的节点。对应的理解就是,来一点,处理一点。

非流式的话,就会累积到一定程度,再去复制分发。对应的理解就是,来一点懒得处理,来一堆,再去处理。

(2)运行在廉价的商业机器上

HDFS对硬件的要求小。

(3)适合存储大文件,不适合存储大量小文件

适合处理几百MB、几百TB量级的数据。

HDFS已经可以支持PB级的数据存储。

(4)不适合低延迟要求的数据访问

HDFS的定位是面向大规模数据的数据分析和存储的,关注点是数据的吞吐量。

不能满足低延迟的要求,作为达到低延迟效果的补充方案是,使用HBase。

三、HDFS一些概念

HDFS中的文件是以块的形式进行存储。在Hadoop 2.x版本中数据块的默认大小是128MB,老版本中是64MB。

为什么要使用128MB作为默认值?

HDFS的块比磁盘的块大,其目的是为了最小化寻址开销。

如果寻址时间约为10ms,传输速率为100MB/s,为了使寻址时间仅占传输时间的1%,我们要将块大小设置约为100MB。默认的块大小实际为128MB。 —— 《Hadoop权威指南》

磁盘设置太小,会增加寻址时间,块设置得太大,每个块数据传输的时间会增加,导致程序处理数据,会非常慢。

HDFS块的大小设置主要取决于磁盘传输速率,如果是SSD,可以考虑将块大小设置为256MB。

使用块的好处是:

  • 单个文件的大小,可以超过HDFS集群中单个节点磁盘的大小,单个节点只存储这个文件的部分块。
  • 提高容错性,每个块都有副本,若一个块丢失、损坏,系统可以读取副本中的数据。

四、HDFS架构

NameNode与DataNode的关系就像Eureka和服务的关系。当Client需要查询数据的时候,首先先找NameNode,NameNode告诉它,这个文件有哪些DataBlock,这些DataBlock分别在哪些服务器上。然后Client就去找DataBlock。DataBlock将数据返回给Client。

NameNode

NameNode 是 主节点,DataNode是从节点。

NameNode调度DataNode,DataNode执行底层I/O任务。

NameNode存储元数据、文件到DataBlock的映射。

  • 管理HDFS的命名空间
  • 配置副本策略
  • 管理文件到数据块的映射信息
  • 处理客户端读写请求

DataNode

存储DataBlock的机器,就是DataNode。负责接收client写的文件,以及将client读取的文件传给client。

  • 存储实际的DataBlock
  • 执行数据块的读写操作

客户端

用户通过与NameNode、DataNode交互来访问整个文件系统。

  • 文件切分。将文件切分成DataBlock
  • 与NameNode进行交互,获取文件的位置信息
  • 与DataNode交互,读取或者写入数据
  • 通过命名管理HDFS、访问HDFS

SecondNameNode

  • 辅助NameNode,分担其工作量
  • 紧急情况下,辅助恢复NameNode

联邦NameNode

解决NameNode内存的问题,提出的解决方案是联邦NameNode,每个NameNode都保存一个命名空间信息如 /a ,会有多个NameNode。

五、HDFS高可用

如何解决NameNode不可用的问题,这里就设置一个备份NameNode。DataNode会向这两个NameNode上报心跳,而且这两个NameNode有一套共享存储机制,这个共享存储机制主要是QJM,QJM有点类似Zk,会有3个或多个节点,只有写入多数,才算成功。如果活动的NameNode挂掉了,在Zk上的临时节点就会消失,取代的是备用节点继续主节点的工作。

QJM

NFS

机架感知机制

为什么要关注rack(机架)呢?

机架内的机器之间的网络速度 高于 跨机架机器之间的网络速度机架之间的网络通信通常受上层交换机之间的网络带宽的限制

关注了又能起到什么作用?

HDFS默认存3份,第一个副本放在Client上传的DataNode,第二个副本放在与第一个副本相同机架的不同的DataNode,第三个副本放在与第二个副本不同相同机架的DataNode上

如果本地数据损坏,可以从同机架的另一个节点获取数据,为了降低带宽消耗和读取延时,HDFS会尽量取它最近的副本。默认情况,机架感知是没有开启的。

六、Shell操作

HDFS shell里面的很多操作,都和我们操作Linux文件的命令是一样的。

启动HDFS

执行脚本

./bin/hdfs namenode -format

下面两种方式是等价的

./sbin/start-dfs.sh

#### 启动namenode进程
./sbin/hadoop-daemon.sh start namenode #### 启动datanode进程
./sbin/hadoop-daemon.sh start datanode

namenode是什么?datanode是什么?为什么必须要格式化namenode才能启动成功?

访问 http://127.0.0.1:50070/dfshealth.html#tab-overview

看到DFS的面板。

创建文件夹

./hdfs dfs -mkdir -p /usr/fonxian/input

添加文件到HDFS

将文件上传的HDFS中的input目录下:

从图中可以看出HDFS默认的块大小为128MB,而文件使用的大小为1.33KB。


./hdfs dfs -put README.txt /input/

hadoop fs -mkdir -p /fonxian/mydata
hadoop fs -moveFromLocal NOTICE.txt /fonxian/mydata

追加文件内容

hadoop fs -appendToFile README.txt /fonxian/mydata/NOTICE.txt

将本地文件复制到HDFS

hadoop fs -copyFromLocal version.txt /fonxian/mydata/

将HDFS文件拷贝到本地

hadoop fs -copyToLocal /fonxian/mydata/version.txt  /usr/local/

查看HDFS文件夹中的文件大小

hadoop fs -du -h  /fonxian/mydata/

七、Java API操作

引入依赖

配置pom.xml文件

			<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.3</version>
</dependency>

添加文件


public class HdfsClient { public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
conf.set("fs.defaultFS","hdfs://localhost:9000"); // 1.获取hdfs客户端对象
FileSystem fs = FileSystem.get(conf); // 2.在hdfs上创建路径
fs.mkdirs(new Path("/test/hdfs/client")); // 3.关闭资源
fs.close(); System.out.println("over"); } }

如何提示没有权限,说明当前于用户testhadoop,没有操作hdfs的权限,该权限是root用户才有。

AccessControlException: Permission denied: user=testhadoop, access=WRITE, inode="/test/hdfs/client1":root:supergroup:

解决方法一:需要增加VM参数,来解决这个问题

-DHADOOP_USER_NAME=root

解决方案二:在代码中指定user


Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://localhost:9000"),conf,"root");

上传文件


public static void uploadFile(FileSystem fs) throws IOException {
fs.copyFromLocalFile(new Path("/usr/local/hadoop/etc/hadoop/hdfs-site.xml"),new Path("/hdfs-test.xml"));
}

参数优先级

在项目resource下创建hdfs-site.xml


<configuration>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
</configuration>

运行上面上传文件的程序,会发现副本数为客户端这边配置的值。

Configuration conf = new Configuration();
conf.set("dfs.replication","1");

再在代码中增加参数配置,会发现优先级:客户端代码中的参数 > 客户端resource配置的参数 > 服务器配置的参数

下载文件

    public static void uploadFile(FileSystem fs) throws IOException {
fs.copyFromLocalFile(new Path("/usr/local/hadoop/etc/hadoop/hdfs-site.xml"), new Path("/test-config.xml"));
}

若要剪切HDFS的文件到本地,则可以加上delSrc参数,第一个参数为delSrc参数。

fs.copyToLocalFile(true,new Path("/test-config.xml"), new Path("/usr/local/hadoop/etc/hadoop/hdfs-site-test.xml"),true);

删除文件

第二个参数设置为false,若删除的是文件夹,则会抛出异常,而设置为true,则会删除文件夹。

Path若是文件的路径,则设置成true或false都可以。

    public static void deleteFile(FileSystem fs)throws IOException {
fs.delete(new Path("/fonxian"),true);
}

文件更名


public static void renameFile(FileSystem fs) throws IOException{
fs.rename(new Path("/hdfs-test.xml"),new Path("/hdfs-test123456.xml"));
}

查看文件详情


public static void getFileDetail(FileSystem fs) throws IOException{
RemoteIterator<LocatedFileStatus> remoteIterator = fs.listFiles(new Path("/"),true);
while(remoteIterator.hasNext()){
LocatedFileStatus status = remoteIterator.next();
System.out.println(status.getPath().getName());//文件名称
System.out.println(status.getPermission());//文件权限
System.out.println(status.getLen());//文件长度 BlockLocation[] locations = status.getBlockLocations();
for(BlockLocation location:locations){
String[] hosts = location.getHosts();
for(String host:hosts){
System.out.println(host);
}
}
System.out.println("------------------");
}
}

参考文档

《Hadoop实战》

5分钟深入浅出 HDFS

HDFS高可用性之QJM & NFS

Hadoop之HDFS面试题整理

hdfs 机架感知

Hadoop(二)—— HDFS的更多相关文章

  1. hadoop(二):hdfs HA原理及安装

    早期的hadoop版本,NN是HDFS集群的单点故障点,每一个集群只有一个NN,如果这个机器或进程不可用,整个集群就无法使用.为了解决这个问题,出现了一堆针对HDFS HA的解决方案(如:Linux ...

  2. Hadoop集群(二) HDFS搭建

    HDFS只是Hadoop最基本的一个服务,很多其他服务,都是基于HDFS展开的.所以部署一个HDFS集群,是很核心的一个动作,也是大数据平台的开始. 安装Hadoop集群,首先需要有Zookeeper ...

  3. Hadoop之HDFS文件操作常有两种方式(转载)

    摘要:Hadoop之HDFS文件操作常有两种方式,命令行方式和JavaAPI方式.本文介绍如何利用这两种方式对HDFS文件进行操作. 关键词:HDFS文件    命令行     Java API HD ...

  4. Hadoop入门--HDFS(单节点)配置和部署 (一)

    一 配置SSH 下载ssh服务端和客户端 sudo apt-get install openssh-server openssh-client 验证是否安装成功 ssh username@192.16 ...

  5. Hadoop基础-HDFS的API常见操作

    Hadoop基础-HDFS的API常见操作 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本文主要是记录一写我在学习HDFS时的一些琐碎的学习笔记, 方便自己以后查看.在调用API ...

  6. Hadoop基础-HDFS安全管家之Kerberos实战篇

    Hadoop基础-HDFS安全管家之Kerberos实战篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们都知道hadoop有很多不同的发行版,比如:Apache Hadoop ...

  7. Hadoop基础-Hdfs各个组件的运行原理介绍

    Hadoop基础-Hdfs各个组件的运行原理介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.NameNode工作原理(默认端口号:50070) 1>.什么是NameN ...

  8. Hadoop基础-HDFS的读取与写入过程剖析

    Hadoop基础-HDFS的读取与写入过程剖析 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客会简要介绍hadoop的写入过程,并不会设计到源码,我会用图和文字来描述hdf ...

  9. 深入理解Hadoop之HDFS架构

    Hadoop分布式文件系统(HDFS)是一种分布式文件系统.它与现有的分布式文件系统有许多相似之处.但是,与其他分布式文件系统的差异是值得我们注意的: HDFS具有高度容错能力,旨在部署在低成本硬件上 ...

  10. Hadoop基础-HDFS的读取与写入过程

    Hadoop基础-HDFS的读取与写入过程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 为了了解客户端及与之交互的HDFS,NameNode和DataNode之间的数据流是什么样 ...

随机推荐

  1. 【面试突击】-SpringBoot面试题(一)

    Spring Boot 是微服务中最好的 Java 框架. 我们建议你能够成为一名 Spring Boot 的专家. 问题一 Spring Boot.Spring MVC 和 Spring 有什么区别 ...

  2. Leetcode刷题python

    Two Sum 两数==target 方法二更好 题1,对时间复杂度有要求O(n),所以维护一个字典,遍历过的数值放在字典中,直接遍历时候查找字典中有没有出现差,查找字典时间复杂度是O(1),所以O( ...

  3. 继 首次使用DoNetCore EFCore DbFirst 更新数据实体

    //EFCore DB First 步骤 //第一步:Install-Package Microsoft.EntityFrameworkCore.SqlServer -version 2.1.1 // ...

  4. tmp-scmj

    1.apk下载 http://app6.wpf2x4.cn/?downloadfrom=sichuan 麻将图: Big_mahjonghn_tiles_sr.png

  5. Java开发环境之RabbitMQ

    查看更多Java开发环境配置,请点击<Java开发环境配置大全> 捌章:RabbitMQ安装教程 1)下载安装Erlang 官网下载:http://www.erlang.org,有时比较难 ...

  6. node基础学习——操作文件系统fs

    操作文件系统fs 1.在Node.js中,使用fs模块来实现所有有关文件及目录的创建.写入及删除.在fs模块中,所有对文件及目录的操作都可以使用同步与异步两种方法,具有Sync后缀的方法均为同步方法. ...

  7. CSS制作华为mate8手机模型示例

    CSS制作华为mate8手机模型效果图 1.HTML代码 <!DOCTYPE html> <html> <head> <meta charset=" ...

  8. 《BUG创造队》第三次作业:团队项目原型设计与开发

    项目 内容 这个作业属于哪个课程 2016级软件工程 这个作业的要求在哪里 实验六 团队作业3:团队项目原型设计与开发 团队名称 BUG创造队 作业学习目标 ①掌握软件原型开发技术:②学会使用软件原型 ...

  9. 《The One 团队》:第九次团队作业:BETA冲刺与团队项目验收

    项目 内容 作业所属课程 所属课程 作业要求 作业要求 团队名称 < The One !> 作业学习目标 (1)掌握软件黑盒测试技术:(2)学会编制软件项目总结PPT.项目验收报告:(3) ...

  10. 我理解的Linux内存管理

    众所周知,内存管理是Linux内核中最基础,也是相当重要的部分.理解相关原理,不管是对内存的理解,还是对大家写用户态代码都很有帮助.很多书上.很多文章都写了相关内容,但个人总觉得内容太复杂,不是太容易 ...