HDFS-基础特性和适用场景

Posted ICT点数成金

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDFS-基础特性和适用场景相关的知识,希望对你有一定的参考价值。

HDFS概述:

1、HDFS是适合在通用硬件上的分布式文件系统。

特点:

1.高容错性:

2.高吞吐量:为大量数据访问应用提供高可吞吐量支持。

3.大文件存储:支持TB-PB级别的数据存储

4.保存多个副本,且提供容量增长机制,副本丢失或者宕机自动修复


2、元数据:元数据(Metadata),又称中介数据、中继数据,为描述数据的数据(data about data),主要是描述数据属性(property)的信息,用来支持如指示存储位置、历史数据、资源查找、文件纪录等功能。

1)第一类是文件和目录自身的属性信息,例如文件名、目录名、父目录信息、文件大小、创建时间、修改时间等。 

2)第二类记录文件内容存储相关信息,例如文件分块情况、副本个数、每个副本所DataNode信息等。 

3)第三类用来记录HDFS中所有DataNode的信息,用于DataNode管理。


3、HDFS适用场景以及不适用那些场景?

HDFS适合做什么?

大文件存储、流式数据访问

HDFS不适合做什么?

大量小文件、随机写入、低延迟读取操作

适用:海量文件存储,1-10亿级别的文件存储;大文件存储,GB以上的存储;流式文件存储,改写较少。如图片、视频、归档数据。

不适用:低时间延迟数据访问的应用,如毫秒级别范围的:因为HDFS是为高数据吞吐量应用优化的,这样就会造成以高延迟为代价。

        大量小文件:因为nameNode将文件系统的元数据存储在内存中,因此文件系统所能存储的文件总数受限于namenode内存容量。每个文件,目录和数据块的存储信息大约占150字节,如果是上十亿个文件,那么需要的内存将是非常大的。

        多用户写入,任意修改文件:因为HDFS文件只有一个writer,而且写操作总是写在文件的末尾。


4、Hadoop不适合用来处理大批量的小文件?
其实这是由namenode的局限性所决定的,如果文件过小,namenode存储的元信息相对来说就会占用过大比例的空间,内存和磁盘开销都非常大。如果一次task的文件处理较大,那么虚拟机启动、初始化等等准备时间和任务完成后的清理时间,甚至shuffle等等框架消耗时间所占的比例就小得多;反之,处理的吞吐量就掉下来了。

5、为什么HDFS不适合大量的小文件?
在HDFS中,namenode将文件系统中的元数据存储在内存中,因此,HDFS所能存储的文件数量会受到namenode内存的限制。一般来说,每个文件、目录、数据块的存储信息大约占150个字节,根据当前namenode的内存空间的配置,就可以计算出大约能容纳多少个文件了。
有一种误解就是,之所以HDFS不适合大量小文件,是因为即使很小的文件也会占用一个块的存储空间。这是错误的,HDFS与其它文件系统不同,小于一个块大小的文件,不会占用一个块的空间。

6、HDFS对于小文件存储的处理方法有哪些?

对于小文件问题,Hadoop自身提供了三种解决方案:Hadoop Archive、 Sequence File 和 CombineFileInputFormat
(1)Hadoop Archive
       归档为bar.har文件
(2)Sequence File
sequence file由一系列的二进制的对组成,其中key为小文件的名字,value的file content。
(3)CombineFileInputFormat
CombineFileInputFormat是一种新的inputformat,用于将多个文件合并成一个单独的split,另外,它会考虑数据的存储位置。

7、Hadoop Archive解决海量小文件存储:
关于HDFS的问题:
1)关于Namenode可扩展性的讨论,目前单台服务器作为Namenode,当文件数量规模不断增大时,元数据的规模增长将是一个需要面对的问题,由于Namenode需要将所有元数据Load到内存中,单台Namenode可能会无法管理海量的元数据。
2)是HDFS中SequenceFile存储方式的讨论,利用Block压缩方式可以很好的解决空间压力。

在HDFS中存在海量的小文件时,会给存储带来的一系列问题 。

HDFS中文件是按Block来存储的,默认一个Block的长度是256MB,当HDFS中存在大量小文件(长度小于256MB)时,不仅占用大量存储空间,而且也占用大量的namespace,给Namenode带来了内存压力。Namenode的压力一般是因为有海量的小文件存在。

解决方法:利用Hadoop Archive(HAR),这个特性从Hadoop 0.18.0版本引入,可以将众多小文件打包成一个大文件进行存储,并且打包后原来的文件仍然可以通过Map-reduce进行操作,打包后的文件由索引和存储两大部分组成,索引部分记录了原有的目录结构和文件状态。
Hadoop Archive
举个例子,原本获取一个文件通过命令

hadoop fs –get hdfs://namenode/foo/file-1 localdir

如果将foo目录打包成bar.har后,获取file-1的命令就变成

hadoop fs –get har://namenode/bar.har#foo/file-1 localdir

通过以下命令可以将文件打包成HAR。

hadoop archive -archiveName  *

但是,目前HAR文件中的源数据只能获取,不能修改。

8、Hadoop支持数据的随机读写。

答案:错,分析:lucene是支持随机读写的,而hdfs只支持随机读。但是HBase可以来补救。HBase提供随机读写,来解决Hadoop不能处理的问题。HBase自底层设计开始即聚焦于各种可伸缩性问题:表可以很“高”,有数十亿个数据行;也可以很“宽”,有数百万个列;水平分区并在上千个普通商用机节点上自动复制。表的模式是物理存储的直接反映,使系统有可能提高高效的数据结构的序列化、存储和检索。


9、hdfs为什么不能任意修改文件,而且只能写在末尾?
从HDFS中存入数据说,HDFS默认的最基本的存储单位是64M的数据块。
和普通文件系统相同的是,HDFS中的文件是被分成64M一块的数据块存储的。
不同于普通文件系统的是,HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间。这样如果修改会重新分数据块导致延迟,所以不能随意修改,读取的HDFS是联系NameNode获取到文件信息(数据块),而每个数据块都是有位置的,是按顺序排列,如果写入数据只能在末尾。


10、集群内是否每个节点都应该配 RAID,这样避免单磁盘损坏,影响整个节点运行?

答案:错误,分析:因为hadoop本身就具有冗余能力,所以如果不是很严格不需要都配备RAID


11、全分布模式有什么注意点?

全分布模式通常被用于生产环境,这里我们使用N台主机组成一个Hadoop集群,Hadoop守护进程运行在每台主机之上。这里会存在Namenode运行的主机,Datanode运行的主机,以及tasktracker运行的主机。在分布式环境下,主节点和从节点会分开。

12、如何重启Namenode?

点击stop-all.sh,再点击start-all.sh。

键入sudohdfs(Enter),su-hdfs(Enter),/etc/init.d/ha(Enter),及/etc/init.d/hadoop-0.20-namenodestart(Enter)。


13、HDFS组件的权限

存在两点缺陷:

1)认证信息需要在多次提供,例如访问HBase时,需要提供访问HBase组件的认证信息,同时需要提供访问ZooKeepr所需的jaas.conf配置文件,经常有发生提供了前面的认证信息,却忘记了后面的jaas.conf文件。

2jaas.conf配置文件的内容,随着JDK类型而变化。在IBM JDKOracle JDK下,jaas.conf配置文件的内容差异很大。

优化:统一认证接口:用户不需要再去关注各个组件各自的认证方式;

优化Zookeeper配置:a.不需再去关注jaas.conf配置文件;b.用户不需关注JDKOracle还是IBM的,所提供API内部主动识别JDK信息,并据此提供所需参数。

注:jaas.conf 不是kerberos必要的,在后面的版本是可以通过api 来生成jaas对象。


14、最新的hadoop版本中HDFS文件块默认大小增大为256M,增大的原因?
1)减轻了namenode的压力
原因是hadoop集群在启动的时候,datanode会上报自己的block的信息给namenode。namenode把这些信息放到内存中。那么如果块变大了,那么namenode的记录的信息相对减少,所以namenode就有更多的内存去做的别的事情,使得整个集群的性能增强。
2)增大会不会带来负面相应。
可以灵活设置,
如果对于数两级别为PB的话,建议可以block设置的大一些。
如果数据量相对较少,可以设置的小一些。
负面效应,如果网络环境不好,可能会造成重新传输。

15、在HDFS里面,
1)、data node上的块大小默认是256MB(或者是128MB或64MB)是最优选择?
为什么不能远少于64MB(或128MB或256MB) ?
a.(普通文件系统的数据块大小一般为4KB)减少硬盘寻道时间(disk seek time)

HDFS设计前提是支持大容量的流式数据操作,所以即使是一般的数据读写操作,涉及到的数据量都是比较大的。

假如数据块设置过少,那需要读取的数据块就比较多。

由于数据块在硬盘上非连续存储,普通硬盘因为需要移动磁头,所以随机寻址较慢,读越多的数据块就增大了总的硬盘寻道时间。当硬盘寻道时间比io时间还要长的时候,硬盘寻道时间就成了系统的一个瓶颈。合适的块大小有助于减少硬盘寻道时间,提高系统吞吐量。

b.减少Namenode内存消耗

对于HDFS,只有一个Namenode节点,它的内存相对于Datanode来说,是极其有限的。

然而,namenode需要在其内存FSImage文件中记录在Datanode中的数据块信息,假如数据块大小设置过少,而需要维护的数据块信息就会过多,会增加Namenode的内存开销。

2)为什么不能远大于64MB(或128MB或256MB)

主要从上层的MapReduce框架来讨论

a.Map崩溃问题:系统需要重新启动,启动过程需要重新加载数据,数据块越大,数据加载时间越长,系统恢复过程越长。

b.监管时间问题:
主节点监管其他节点的情况,每个节点会周期性的把完成的工作和状态的更新报告回来。如果一个节点保持沉默超过一个预设的时间间隔,主节点记录下这个节点状态为死亡,并把分配给这个节点的数据发到别的节点。对于这个“预设的时间间隔”,这是从数据块的角度大概估算的。
假如是对于64MB的数据块,可以假设节点10分钟之内能解决,超过10分钟也没反应,即可认为死亡。
可对于640MB或是1G以上的数据,应该要估算个多长的时间内?估算的时间短了,那就误判死亡了,更糟糕的情况是所有节点都会被判死亡。
估算的时间长了,那等待的时间就过长了。
所以对于过大的数据块,这个“预设的时间间隔”不好估算。

c.问题分解问题:

数据量大小是问题解决的复杂度是成线性关系的。对于同个算法,处理的数据量越大,它的时间复杂度也就越大。

d.约束Map输出:

在Map Reduce框架里,Map之后的数据是要经过排序才执行Reduce操作的。根据归并排序算法的思想,对小文件进行排序,然后将小文件归并成大文件。

16、HDFS数据写入流程:

第一步:业务应用调用HDFS客户端,HDFS client 提供api创建文件,请求写入(调用DistributedFileSystemCreate()方法来请求创建文件)

第二步:HDFS client 告诉namenodenamenode在元数据中创建文件节点。

第三步:业务应用调用writer api写入文件(DistributedFileSystem通过对NameNode发出RPC请求,在NameNodeNamespace里面创建一个新的文件信息。DistributedFileSystem返回一个FSDataOutputStream 给端客户端 , 让它从FSDataOutputStream 中写入数据)

第四步:HDFS client收到数据后,从namenode中获取数据块的编号。位置信息等,然后联系datanode,并将需要写的数据与datanode建立起IO通信。完成后,HDFS client按照自有的协议将数据写入到datanode1,在由它复制到datanode2datanode3

后面:数据写完后,将返回确认信息给HDFS client。所有的数据写完后,业务层调用HDFS client关闭文件。业务调用close flushHDFS client联系namenode确认数据写完,namenode持久化数据。


17、HDFS读文件流程:

 第一步: 业务应用调用HDFS客户端,HDFS client 提供api打开文件(HDFS客户端通过调用DistributedFileSystem对象的open()方法)

 第二步:HDFS client联系namenode获取文件信息(数据块、datanode位置信息)

 第三步:业务层应用调用read api读取文件(DistributedFileSystem通过对NameNode发出RPC请求,确定要读取文件的block的位置。DistributedFileSystem返回一个FSDataInputStreamHDFS户端让 它 从 FSDataInputStream 中 读 取 数 据)

 第四步:HDFS client namenode中获取的信息 联系datanode获取对应的数据块。(client采取的是最近原则);HDFS client会与多个datanode通信获取数据块

 最后:数据读取完后。业务调用close关闭。 


18、Java开发HDFS流程:

初始化配置项加载xml配置文件;

进行安全认证(kerberos);

初始化HDFS filesystem文件操作对象;

使用该对象可以创建、删除文件,目录;

利用DFSinputstreamDFSOutputStream对象进行读写(追加内容)操作。


19、HDFS常用的shell命令

  查看文件内容:dfs -cat ;查看当前目录:dfs -l ;删除文件 dfs -rm 上传文件和目录 dfs -put 下载文件和目录 dfs -get 创建目录 dfs -mkdir 改变文件属组:dfs -chmod/-chown

dfsadmin -safemode 安全模式操作;dfsadmin -report 报告服务状态 balancer -threshold 容量均衡阈值

 

20、HDFS开发规范

   1)对于创建的流对象在用完后要关闭,申请资源需要及时释放

   2)对于一些不可重用的大数据,不要在操作系统的缓存区缓存。可以设置dfs.datanode.drop.cache.behind.reads     dfs.datanode.drop.cache.behindwrites 值为TRUE

   3)不适用HDFS存储大量的小文件,大量小文件元素占用namenode大量的内存

   4HDFS3备份即可(第一个block副本放在和client所在的node里(如果client不在集群范围内,则这第一个node是随机选取的,当然系统会尝试不选择哪些太满或者太忙的node)。  第二个副本放置在与第一个节点不同的机架中的node中(随机选择)。 第三个副本和第二个在同一个机架,随机放在不同的node中。)


21、HDFS操作:


22、HDFS常用API?
通过FileSystem API操作HDFS:
FileSystem.copyFromLocalFile(Path src,Patch dst)--可将本地文件上传到HDFS的指定位置上,src和dst均为文件的完整路径;
FileSystem.open(Path path) --把HDFS上的文件下载到本地;
FileSystem.create(Path f)--在HDFS上创建文件,f为文件的完整路径;
FileSystem.mkdirs(Path f)--在HDFS上创建文件夹,f为文件夹的完整路径;
FileSystem.rename(Path src,Path dst)--为指定的HDFS文件重命名;
FileSystem.delete(Path f,Boolean recursive)--删除指定的HDFS文件,f为需要删除文件的完整路径,recuresive用来确定是否进行递归删除;
FileSystem.exists(Path f)--查看指定HDFS文件是否存在;
FileSystem.getModificationTime() --查看指定HDFS文件的修改时间;
FileStatus.getPath()--查看指定HDFS中某个目录下所有文件;
FileSystem.getFileBlockLocation(FileStatus file,long start,long len)--查找指定文件在HDFS集群上的位置,start和len来标识查找文件的路径;
DatanodeInfo.getHostName()--获取HDFS集群上的所有节点名称


以上是关于HDFS-基础特性和适用场景的主要内容,如果未能解决你的问题,请参考以下文章

Hive基础之Hive是啥以及Hive使用场景

面试HDFS技术原理

Hadoop HDFS 基础使用

Hadoop之HDFS基础

HDFS基础入门

HDFS总结