大数据-hadoop-分布式文件系统_第1页
大数据-hadoop-分布式文件系统_第2页
大数据-hadoop-分布式文件系统_第3页
大数据-hadoop-分布式文件系统_第4页
大数据-hadoop-分布式文件系统_第5页
已阅读5页,还剩45页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Hadoop分布式文件系统

——HDFS详解Hadoop的文件系统HDFS简介HDFS体系结构HDFS的基本操作HDFS常用JavaAPI详解HDFS中的读写数据流HDFS命令详解1.何为分布式文件系统?当数据集的大小超过一台独立物理计算机的存储能力时,可以将它进行分区并存储到多台计算机上,而管理网络中跨多台计算机存储的文件系统称为分布式文件系统。2.HDFSHDFS(HadoopDistributedFileSystem)是Hadoop项目的核心子项目,是Hadoop主要应用的一个分布式文件系统。注:HDFS只是Hadoop抽象文件系统的一个实例,还包括本地文件系统、HFTP、S3等。基本概念一、Hadoop文件系统1.Hadoop文件系统(1)Hadoop提供了许多文件系统的接口,用户可以选取合适的文件系统实现交互。例如,可以通过命令行接口和HDFS文件系统进行交互:比如,列出本地文件系统根目录下的文件,执行以下shell命令即可:hadoopfs-lsfile:///(2)运行的MapReduce程序可以访问以上任何文件系统,但是在处理大数据集时,需要选择一个具有数据本地化优化的分布式文件系统,常用的如HDFS或KFS。注:Hadoop在存储有输入数据(如,HDFS中的数据)的节点上运行map任务时可以获得最佳性能,这就是数据本地化优化。2.Hadoop文件系统的接口Hadoop使用Java编写的,通过JavaAPI可以调用所有Hadoop文件系统的交互操作。例如,HDFS的命令解释器就是一个Java应用,它使用Java的FileSystem类来提供文件系统操作。(1)ThriftHadoop文件系统的接口是通过JavaAPI提供的,所以其他非Java应用程序访问Hadoop文件系统会比较麻烦。Thrift分类单元中的ThriftAPI通过把Hadoop文件系统包装一个ApacheThrift服务来弥补这个不足,从而使任何具有Thrift绑定(binding)的语言都能轻松地与Hadoop文件系统(比如HDFS)进行交互。要ThriftAPI,首先要运行提供Thrift服务的Java服务器,并以代理的方式访问Hadoop文件系统。注:ThriftAPI包含很多其他语言生成的stub(存根),包括C++、Perl、PHP、Python等。(2)C语言Hadoop提供了一个C语言库—libhdfs,该语言库是JavaFileSystem接口类的一个镜像,它被编写成访问HDFS的C语言库。(3)FUSE用户空间文件系统(FilesysteminUserspace,FUSE)允许文件系统整合为一个Unix文件系统并在用户空间中执行。通过使用Hadoop的Fuse-DFS功能模块,任意一个Hadoop文件系统(一般为HDFS)都可以作为一个标准文件系统进行挂载;便可以使用UNIX的工具(如,ls和cat)与该文件系统交互,还可以通过任意一种编程语言使用POSIX库来访问文件系统。注:Fuse—DFS是用C语言实现的,可以使用libhdfs作为HDFS的接口。(4)WebDAVWebDAV是一系列支持编辑和更新文件的HTTP的扩展。在大部分操作系统中,WebDAV共享都可以作为文件系统进行挂载,因此通过WebDAV向外提供HDFS(或其他Hadoop文件系统)的访问接口,可以将HDFS作为一个标准的文件系统进行访问。(5)HDFS特定的接口HTTP:HDFS定义了一个只读接口,它以HTTP方式检索目录列表和数据。嵌入在namenode运行在50070端口的Web服务器,以XML格式提供目录列表服务;而嵌入在datenode运行在50075端口的Web服务器,提供文件数据传输服务。用户可以利用HTTP协议编写从不同版本的HadoopHDFS集群中读取数据的客户端。HFTPFileSystem就是其中一种:它是一个通过HTTP协议与HDFS交互的Hadoop文件系统接口。FTPHDFS还有一个FTP接口,该接口允许使用FTP协议与HDFS进行交互,即使用FTP客户端和HDFS进行交互。二、HDFS简介1.HDFSHDFS是基于流数据模式访问和处理超大文件的需求而开发的,它可以运行于廉价的商用服务器上。2.HDFS的主要特点:(1)处理超大文件实际应用中,HDFS已经用来存储PB级的数据了。(2)流式的访问数据运行在HDFS上的应用程序必须流式地访问他们的数据集。HDFS的设计适合批量处理,而不是用户交互式的。重点是数据吞吐量(通常分析任务都会涉及数据集的大部分数据),而不是数据访问的反应时间。(3)运行于廉价的商用机器集群上Hadoop设计对硬件需求比较低,只需运行在廉价的商用硬件集群上。但这也意味着对于庞大的集群,节点出现故障的概率非常高,因此在设计HDFS是需要充分考虑数据的可靠性、安全性和高可用性。(4)硬件故障硬件故障是常态,而不是异常。整个HDFS系统由大量存储着文件数据片断的服务器组成,每个组成部分都很可能出现故障,因此,故障的检测和自动快速恢复是HDFS一个很核心的设计目标。3.HDFS的局限性:(1)不适合低延迟数据访问HDFS是为了处理大型数据集分析任务,主要是为了达到高的数据吞吐量而设计的,这就要求可能以高延迟为代价。注:对于低延迟的访问需求,HBase是更好地选择。(2)无法高效存储大量小文件Hadoop中由namenode负责将文件系统中的元数据存储在内存中,因此文件系统存储的文件总数受限于namenode的内存容量。当存储大量的小文件时,会大大增加namenode的工作压力,检索处理元数据所需的时间就会很长。(3)不支持多用户写入和任意修改文件HDFS的一个文件中只有一个writer,而且写操作只能在文件的末尾完成,即只能执行追加操作。目前,HDFS还不支持多个用户对同一文件的写操作以及在文件的任意位置进行修改。三、HDFS体系结构1.HDFS相关概念(1)块(block)HDFS中的文件也被分成块进行存储,它是文件存储处理的基本单元。比传统操作系统的文件块要大得多,在配置hadoop系统时,我们可以知道它的默认块大小是64MB。与其他文件系统不同,HDFS中小于一个块大小的文件不会占据整个块的空间。注:1)HDFS中块的大小:HDFS中块的大小既要考虑数据吞吐量,又要兼顾MapReduce的作业运行速度。块太小,会增加文件的寻址时间开销;块太大时,会造成map任务数太少,不能充分利用集群的datanode,导致作业的运行速度会比较慢。2)HDFS使用抽象的块带来好处:可以存储任意大的文件而不会受到网络中单一节点的磁盘大小的限制;使用抽象块作为存储单元,可以简化存储子系统;HDFS中块的大小固定,可简化存储管理。同时也消除了对元数据的顾虑,由于元数据信息可以和文件块内容分开存储,其他系统就可以单独的管理元数据。块更有利于分布式文件系统中复制容错的实现。在HDFS中,为了处理节点故障,默认文件块副本数是3,分别存储在集群的不同节点。3)HDFS中获得文件和块信息的命令:(fsck工具)

hadoopfsck

/-files–blocks

将列出文件系统中组成各个文件的块信息。(2)namenode和datanodeHDFS体系结构中有两类节点:一类是namenode,另一类是datanode;分别承担master和worker任务。

1)namenode:管理集群中的执行调度。namenode的作用:管理文件系统的命名空间(namespace),并维护整个文件系统的文件目录树及这些文件的索引目录;这些信息以命名空间镜像文件和编辑日志文件两种形式永久的存储在本地磁盘上。记录每个文件中各个块所在的datanode信息;这些信息不是永久保存的,namenode会在每次系统重启时动态的重建。

管理客户端对文件的访问。当运行任务时,客户端通过namenode获取元数据信息,并与datanode进行交互以访问整个文件系统。2)datanode:文件系统的具体任务的工作节点。datanode的作用:存储并检索数据块,受客户端或namenode调度;定期向namenode发送它们所存储的文件块信息。注:namenode和datanode之间通过HeartBeat通信。2.namenode的两种容错机制(1)备份那些组成文件系统元数据持久状态的文件一般设置是,将持久状态的文件写入本地磁盘的同时,写入一个远程的网络文件系统(NFS)。(2)运行一个辅助的namenode—Snamenode

辅助namenode的作用:定期通过编辑日志合并命名空间镜像,以防止编辑日志过大辅助namenode一般在另一台单独的物理计算机上运行,

它会保存合并后的命名空间镜像的副本,并在namenode发生故障时启用。注:缺点是辅助namenode的状态总是滞后于主节点,因此namenode失效时难免部分数据会丢失。通常namenode使用两种机制的结合进行容错处理。3.HDFS的体系结构HDFS采用master/slave架构对文件系统进行管理。一个HDFS集群是由一个namenode和一定数目的datanode组成。HDFS的体系结构如下:从内部看,一个文件其实被分成一个或多个数据块,这些块存储在一组datanode上。namenode执行文件系统的名字空间操作,比如打开、关闭、重命名文件或目录;它也负责确定数据块到具体datanode节点的映射。datanode负责处理文件系统客户端的读/写请求,并在namenode的统一调度下进行数据块的创建、删除和复制。(1)副本存放策略—机架感知策略目前HDFS采用的策略是将副本存放在不同的机架上,这样可以有效防止整个机架失效时数据的丢失。大多数情况下,副本系数是3,即将一个副本存放在本地机架的节点上,另外一个副本放在同一机架的另一个节点上,第三个副本放在不同机架的节点上。缺点:由于一个写操作需要传输数据块到多个机架,增加了写操作的成本。(2)读取数据策略读取数据时,HDFS会尽量读取离客户端最近的副本。如,首先读取本地数据中心的副本。(3)安全模式namenode启动后会进入一个称为安全模式的特殊状态。namenode从所有的datanode接收心跳信号和块状态报告,数据块被namenode检测确认安全后,namenode退出安全模式状态。(4)文件安全—namenode容错机制四、HDFS的基本操作1.HDFS命令行操作可以通过命令行接口和HDFS进行交互。(1)下面以单机上运行Hadoop、执行单机伪分布为例:在单机伪分布中需要修改两个配置属性:修改属性:

令=hdfs://localhost/注:hadoop默认使用HDFS文件系统;在本机localhost运行HDFS,其端口默认采用8020.修改属性:dfs.replication用于设置块的副本数。由于此处采用单机伪分布,需要将默认的副本数3改为1。(2)命令行访问HDFS文件系统复制本地文件到HDFS:hadoopfs–copyFromLocal本地文件路径> hdfs://localhost/文件路径注:使用fs命令时,可以省略URI中的访问协议和主机名(由于在core-site.xml中已指定hdfs://localhost),则以上命令可以简化为:hadoopfs–copyFromLocal本地文件路径HDFS保存路径将HDFS中文件复制到本机:hadoopfs-copyToLocalHDFS下文件路径本机保存路径在HDFS中创建文件夹:hadoopfs-mkdir目录名查看HDFS某目录的文件列表:hadoopfs-lsr目录名2.HDFS的Web界面集群部署好后,可直接通过htttp://namenodeip:50070访问HDFS的Web界面,如上图。点击链接Browsethefilesystem,HDFS的文件结构会通过目录的形式展现出来,增加了对文件系统的可读性。五、HDFS常用的JavaAPI详解主要是Hadoop的Fielsystem类与Hadoop文件系统进行交互的API。1.使用HadoopURL读取数据从Hadoop文件系统中读取文件,最简单的方法是使用.URL对象打开数据流,进而从中读取数据。具体格式如下:InputStreamin=null;try{in=newURL("hdfs://host/path").openStream();//processin}finally{IOUtils.closeStream(in);}为了使Java程序能够识别Hadoop的hdfsURL,通过FsUrlStreamHandlerFactory实例来调用URL中的setURL-StreamHandlerFactory方法。如,URL.setURLStreamHandlerFactory(newFsUrlStreamHandlerFactory());注:使用Hadoop的IOUtils类来关闭finally子句中的数据流。查看运行结果:hadoopURLCathdfs://localhost/文件路径2.使用FileSystem

API读取数据当不能使用URLSteamHandlerFactory时,就需要FileSystemAPI来打开一个文件的输入流:(1)FileSystem是一个高层抽象的文件系统接口,首先要找到文件系统的实例,如HDFS。取得FileSystem实例的两种静态工厂方法:publicstaticFileSystemget(Configurationconf)throwsIOExceptionpublicstaticFileSystemget(URIuri,Configurationconf)throwsIOException如,FileSystemfs=FileSystem.get(URI.create(uri),conf);(2)有FileSystem实例后,通过open()方法得到一个文件的输入流。publicFSDatalnputStreamopen(Pathf)throwsIOExceptionpublicabstractFSDatalnputStreamopen(Pathf,intbufferSize)throwsIOException如,InputStreamin=null;in=fs.open(newPath(uri));注:第一个方法缓冲区默认大小4KB。FSDataInputStream类实现的接口:FileSystem的open方法实际返回的是一个FSDataInputStream类,支持随机访问,并可在任意位置读取。Seekable

接口:支持在文件中找到指定位置,并提供一个查询当前位置相对于文件起始位置偏移量(getPos())的查询方法。

publicinterfaceSeekable{voidseek(longpos)throwsIOException;longgetPos()throwsIOException;

…...}PositionedReadable接口:从一个指定偏移量处读取文件的一部分。publicinterfacePositionedReadable{publicintread(longposition,byte[]bu忏er,intoffset,intlength)

throwsIOException;3.写数据FileSystem类创建文件的方法中,最简单的就是给拟创建的文件指定一个路径对象,并返回FSDataOutputStream写输入流:publicFSDataOutputStreamcreate(Pathf)throwsIOException注:create()方法可以为需要写入且当前不存在的文件创建父目录。有一个用于传递回调接口的重载方法Progressable,可以获得数据节点的写入进度。另一种新建文件的方法:使用append()方法在一个已知文件中追加内容:publicFSDataOutputStreamappend(Pathf)throwsIOException注:append方法对写入日志文件很有用。另外,该方法HDFS支持,但S3不支持FSDataOutputStream与FSDataInputStream不同,它不允许定位。因为HDFS不支持对除文件尾部以外的其他位置进行写入。4.创建目录publicbooleanmkdirs(Pathf)throwsIOException按照客户端请求创建未存在的父目录。事实上,一般不需要特别地创建一个目录,因为调用create()时,写入文件会自动生成所有的父目录。5.删除数据使用FileSystem的delete()方法可以永久性删除文件或目录:publicbooleandelete(Pathf,booleanrecursive)throwsIOException当f是一个文件或空目录,那么recursive的值就会被忽略;在recrusive值为true时,一个非空目录及其内容才会被删除,否抛出异常。6.文件系统查询JavaAPI提供了文件系统的基本查询接口,可以查询元数据信息、文件目录结构,并可进行复杂的目录匹配。(1)文件元数据:FilestatusFileStatus类封装了文件系统中文件和目录的元数据,包括文件长度、块大小、备份、修改时间、所有者以及权限信息。FileSystem的getFileStatus()方法用于获取文件或目录的FileStatus对象:如获取文件状态信息,

FileStatusstat=fs.getFileStatus(file);(2)列出目录信息:listStatus()FileSystem的listStatus()方法:publicFileStatus[]listStatus(Pathf)throwsIOExceptionpublicFileStatus[]listStatus(Path[]files)throwsIOException当传入的参数是一个文件时,会返回长度为1的FileStatus对象的一个数组;当传入的参数是一个目录时,则返回0或多个FileStatus对象,表示此目录中包含的文件和目录。若如果指定一组路径,则依次轮流传递每条路径并对其调用listStatus()方法,再将返回的FileStatus对象数组累积存入同一数组中。(3)通过通配符实现目录筛选当批量处理文件时,文件可能包含大量的目录,这时在一个表达式中使用通配符来匹配多个文件比较方便。Hadoop为执行通配提供了两个FileSystem方法:publicFileStatus[]globStatus(PathpathPattern)throwsIOExceptionpublicFileStatus[]globStatus(PathpathPattern,PathFilterfilter)throwsIOExceptionglobStatus()返回与路径相匹配所有文件的FileStatus对象数组,并对路径进行排序。PathFilter命令作为可选项进一步对匹配进行限制。(4)PathFilter对象通配符不一定能够精确地定位到要访问的文件集合,比如排除一个特定的文件。则可以使用FileSystem中的listStatus()和globStatus()提供的可选的PathFilter对象来控制匹配结果。如下:fs.globStatus(PathpathPattern,PathFilter

filter);过滤器由Path表示,只能作用于文件名。如果你将文件存储在按照日期排列的目录结构中,则可以根据PathFilter在给定的时间范围内选出文件。过滤器将选出与正则表达式不匹配的的文件。六、HDFS的读写数据流1.文件的读取客户端从HDFS中读取数据文件读取流程:(1)客户端通过调用FileSystem对象中的open()方法来打开希望读取的文件。对于HDFS,这个对象是DistributedFileSystem的一个实例。(2)DistributedFileSystem通过使用RPC来调用Namenode,以确定文件起始块的位置。对于每一个块,namenode返回存有该块复本的datanode地址。如果该客户端本身就是一个datanode并保存有相应数据块的复本,则该节点将从本地datanode中读取数据。(3)DistributedFileSystem给客户端返回一个支持文件定位的输入流对象FSDatalnputStream,用于客户端读取数据。然后,客户端对这个输入流调用read()方法,读取块中的数据。(4)在数据流中反复调用read(),可以将数据从datanode传输到客户端。(5)到达块的末端时,DFSInputStream会关闭与该datanode的连接,然后寻找下一个块的最佳datanode。这对客户端是透明的。客户端从其他datanode读取数据块时,仍然需要先向namenode检索数据块所在的datanode位置。注:

DFSInputStream是FSDataInputStream封装的对象,该对象管理着datanode和namenode的I/O。(6)当完成所有文件数据块的读取后,客户端就在FSDataInputStream中调用close()方法,关闭数据流。在读取数据的时候,如果DFSInputStream在与datanode通信时遇到错误,它便会尝试从这个块的另外一个最邻近datanode读取数据,它也会记住那个故障datanode,以保证以后不会反复读取该节点上后续的块;如果发现一个损坏的块,它就会在DFSInputStream试图从其他datanode读取一个块的复本之前通知namenode。2.文件的写入客户端在HDFS中写入数据

写入数据流程:(1)客户端调用DistributedFileSystem对象中的create()方法创建一个文件。DistributedFileSystem通过RPC调用在namenode的文件系统命名空间中创建一个新文件。此时文件中还没有相应的数据块。(2)当namenode对新建文件的检验通过时,namenode会创建一个新文件的记录。创建成功后,DistributedFileSystem返回一个FSDataOutputStream给客户端,用于写入数据。注:与DFSInputStream类似,DFSOutputStream是FSDataOutputStream封装的数据流对象,该对象用来处理datanode和namenode之间的通信。(3)在客户端写入数据时,DFSOutputStream会将数据分割成多个数据包,并写入内部数据队列(dataqueue)。dataqueue由DataStreamer读取,并请求namenode分配数据节点datanode,用来存储数据块(每块默认复制3块)。并把分配的datanode列表形成一个“管道”(pipeline)。然后,DataStreamer将数据包以流的的方式传送到管道中的第一个datanode,第一个datanode会存储这个数据块,并将它推送到第二个datanode,接着第二个datanode存储这个数据块,并将它推送到第三个datanode,直到管道中的最后一个datanode已经存储了此数据块结束。注:DataStreamer是DFSOutputSream的一个内部线程类,

用于将数据块发送到目标datanode上。(4)DFSOutputStream为发出去的数据包保存了一个确认队列(ackqueue),等待管道中的所有datanode返回数据块写入完成的确认信息,然后才将数据包从确认队列删除。(5)客户端完成数据包写入操作后,会对数据流调用close()方法。该操作会在连接namenode确认文件写入完成之前,将所有剩余的数据包放入datanode管道中,等待确认信息。最后通知namenode文件写入完毕。由于namenode已经知道文件由哪些块组成,所以namenode只要在返回成功标志前等待数据块进行最小量的复制即可。当数据块写入datanode失败时:关闭pipeline,将ackqueue中的数据块放入dataqueue的开始,以确保故障节点下游的datanode不会漏掉任何一个数据包;为存储在另一正常datanode的当前数据块指定一个新的标识,并将该标识传送给namenode,以便故障datanode在恢复后可以删除存储的部分数据块;从管道中删除故障datanode,并把余下的数据块写入管道中的两个正常的的datanode中;namenode被通知此数据块是复制块数不足,将会为它再创建一个块备份。3.一致性模型文件系统的一致性模型描述了对文件读/写的数据可见性。一个数据块写入成功后,新的reader就能看见这个块。而对当前写入的块是看不见的。(1)HDFS提供了一个方法来强制所有的缓存与数据节点同步,即对FSDataOutputStream调用sync()方法。当sync()方法返回后,就能确保新用户能够看到至目前所有写入的数据块。如,out.sync();(2)一致性模型的重要性:如果不调用sync()方法,就需要准备好在客户端或系统发生故障时可能会丢失一个数据块。七、HDFS命令详解Hadoop提供了一组shell命令对Hadoop进行操作。包括格式化文件系统、上传文件、下载文件、启动datanode、查看文件系统使用情况、运行Jar包等。1.通过distcp并行复制distcp可以从Hadoop文件系统中复制大量的数据,也可以将大量的数据复制到Hadoop中。distcp典型的应用是在两个HDFS集群之间传输数据:(1)若两个集群运行相同版本的Hadoop,适合用hdfs方案。如,

hadoopdistcphdfs:llnamenodel/foo

hdfs:llnamenode2/bar源路径必须是绝对路径;默认情况下,distcp会跳过目标路径下已存在的文件,但可以通过-overwrite选项覆盖现有的文件。hadoopdistcp–updatehdfs:llnamenodel/foohdfs:llnamenode2/bar/foo(2)若在两个运行着不同版本Hadoop集群上使用distcp复制数据时,则需要使用基于只读http协议的HFTP文件系统并从源文件系统中读取数据。hadoopdistcp

hftp://namenodel:S0070/foo

hdfs://namenode2/bar注意:需要定义访问源的URI中namenode的Web端口,其默认值为50070。

2.HDFS的平衡向HDFS复制数据时,考虑集群的平衡性是相当重要的。当文件块在集群中均匀分布时,HDFS能达到最佳工作状态。(1)通常将map的数量设定为多于集群中datanode的数量,可以避免不平衡的发生,且最好首先使用默认的每个节点20个map任务来运行distcp命令。(2)另外,HDFS提供了一个工具balancer(均衡器)来改变集群中文件块存储的平衡。不均衡的集群会降低MapReduce的本地性。balancer程序是一个Hadoop守护进程,它将块从忙碌的datanode移到相对空闲的datanode,从而重新分配块,它不断移动块,直到集群达到均衡。3.Hadoop存档文件Hadoop存档文件和HAR文件可以将文件高效地放入HDFS块中的文件存档设备,在减少namenode内存使用

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论