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. 【强烈推荐】ok-admin 一个好看又好用的后台模版!!!

    ok-admin 一个很赞的,扁平化风格的,响应式布局的后台管理模版,旨为后端程序员减压! 目前一共有两个版本:ok-admin v1.0和ok-admin v2.0可自由选择! 源码地址:https ...

  2. JAVA基础之事务

    世界万事无简单一说, 每个事情基本上由多个小的事情来完成.有的事情会存在若小的事情不能同时完成的情况就取消所有的小的事情,直至都完成达到预期的效果才算完成!这样就用到了事务操作.在所有的sql语句完成 ...

  3. Java 之 Response 文件下载案例

    文件下载需求: 1. 页面显示超链接 2. 点击超链接后弹出下载提示框 3. 完成图片文件下载 分析过程: 1. 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框 ...

  4. npm 安装、卸载 模块或包的命令(转载)

    npm安装卸载命令 来源:https://www.jianshu.com/p/e6ee00ea03cd npm安装模块 [npm install xxx]利用 npm 安装xxx模块到当前命令行所在目 ...

  5. 计算地图上两点间的距离PHP类

    计算地图上两点间的距离,使用的是谷歌地图 <?php class GeoHelper { /** * @param int $lat1 * @param int $lon1 * @param i ...

  6. 常用docker管理UI

    1. HumpBacks 特性 Web UI Supporting, Easy to use. Container Grouping and Isolation. Container Upgrades ...

  7. 在CentOS 7上修改主机名的方法

    这次我们来讲解一下如何在CentOS 7环境上修改主机名 1.从VMware上登录CentOS 7的虚拟机,并以root用户登录. 2.查看未修改前的主机名 1>.我们可以通过文件hostnam ...

  8. Docker-compose(创建容器)

    Docker-compose(创建容器) 本文原始地址:https://sitoi.cn/posts/23955.html 样例 version: "2" services: sp ...

  9. Codeforces I. Vessels(跳转标记)

    题目描述: Vessels time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  10. Charles 4.2.1 HTTPS抓包

    Charles 4.2.1 HTTPS抓包 Charles iPhone抓包 Mac必须与iPhone连接同一WiFi Proxy -> SSL Proxying Settings ->  ...