irpas技术客

第3章 分布式文件系统HDFS(精心梳理 详解HDFS )_wyz191_分布式文件系统hdfs

大大的周 7357

分布式文件系统(Distributed File System)是一种通过网络实现文件在多台主机上进行分布式存储的文件系统。分布式文件系统的设计一般采用“Client/Server(客户机/服务器)”模式,客户端以特定的通信协议通过网络与服务器建立连接,提出文件访问请求,客户端和服务器可以通过设置访问权来限制请求方对底层数据存储块的访问。

分布式文件系统的结构

普通操作系统(Windows、Linux)中,文件系统一般会把磁盘空间划分为512Byte/每组的“磁盘组”,它是文件系统进行读写的最小单位,文件系统的块(Block)通常是磁盘块的整数倍,即每次读写的数据量必须是磁盘块大小的整数倍。

分布式文件系统也采用了块的概念,文件被分成若干个块进行存储,块是数据读写的基本单元。HDFS默认的一个块的大小是64M。与普通文件不同的是,在分布式文件系统中,如果一个文件小于一个数据块的大小,它并不占用整个数据块的存储空间。

分布式文件系统在物理结构上是由计算机集群中的两类节点构成:

?主节点(Master Node)/ 名称节点(NameNode)

名称节点负责文件和目录的创建、删除和重命名等,同时管理着数据节点和文件块的映射关系,客户端只有访问名称节点才能找到请求的文件块所在的位置,进而到相应位置读取所需文件块。

?从节点(Slave Node)/数据节点(DataNode)

数据节点负责数据的存储和读取;存储时,由名称节点分配存储位置,然后由客户端把数据直接写入相应数据节点;读取时,客户端从名称节点获得数据节点和文件块的映射关系,然后就可以到相应位置访问文件块。数据节点也要根据名称节点的命令创建、删除和复制数据块。

分布式文件系统通常采用多副本存储。文件块会被复制为多个副本,存储在不同的节点上,而且存储同一文件块的不同副本的各个节点会分布在不同的机架上。

分布式文件系统的设计需求

分布式文件系统的设计需求主要包括透明性、并发控制、文件复制、硬件和操作系统异构性、可伸缩性、容错以及安全需求等。

设计需求

具体含义

HDFS的实现情况

透明性

具备访问透明性、位置透明性、性能和伸缩透明性。

访问透明性:用户不需要专门区分哪些是本地文件、哪些是远程文件,用户能够通过相同的操作来访问本地文件和远程文件资源。

位置透明性:在不改变路径名的前提下,不管文件副本数量和实际存储位置发生何种变化,对用户而言都是透明的,用户不会感受到这种变化,只需要使用相同的路径名就始终可以访问同一个文件。

性能和伸缩透明性:指系统中节点的增加或减少以及性能的变化对用户而言是透明的,用户感受不到什么时候一个节点加入或退出了。

只能提供一定程度的访问透明性,完全支持位置透明性、性能和伸缩透明性。

并发控制

客户端对文件的读写不应该影响其他客户端对同一个文件的读写

机制非常简单,任何时间都只允许一个程序写入某个文件

文件复制

一个文件可以拥有在不同位置的多个副本

HDFS采用了多副本机制

硬件和操作系统的异构性

可以在不同的操作系统和计算机上实现同样的客户端和服务器端程序

采用JAVA语言开发,具有很好的跨平台能力

可伸缩性

支持节点的动态加入或退出

建立在大规模廉价机器上的分布式文件系统集群,具有很多的可伸缩性

容错

保证文件服务在客户端或者服务端出现问题的时候能正常使用

具有多副本机制和故障自动检测、恢复机制

安全

保障系统的安全性

安全性较弱

HDFS演变过程

传统的文件系统对海量数据的处理方式是将数据文件直接存储在一台服务器上,如图1所示。

图1 传统文件系统

从图1可以看出,传统的文件系统在存储数据时,会遇到两个问题,具体如下:

当数据量越来越大时,会遇到存储瓶颈,就需要扩容;由于文件过大,上传和下载都非常耗时;

为了解决传统文件系统遇到的存储瓶颈问题,那么首先考虑的就是扩容,扩容有两种形式,一种是纵向扩容,即增加磁盘和内存;另一种是横向扩容,即增加服务器数量。通过扩大规模从而达到分布式存储,这种存储形式就是分布式文件存储的雏形,如图2所示。

图2 分布式文件系统雏形

解决了分布式文件系统的存储瓶颈问题之后,那么还需要解决文件上传与下载的效率问题,常规的解决办法是将一个大的文件切分成多个数据块,将数据块以并行的方式进行存储。这里以30G的文本文件为例,将其切分成3块,每块大小10G(实际上每个数据块都很小只有100M左右),将其存储在文件系统中,如图3所示。

图3 分布式文件系统雏形

从图3可以看出,原先一台服务器要存储30G的文件,此时每台服务器只需要存储10G的数据块就完成了工作,从而解决了上传下载的效率问题。但是文件通过数据块分别存储在服务器集群中,那么如何获取一个完整的文件呢?针对这个问题,就需要再考虑增加一台服务器,专门用来记录文件被切割后的数据块信息以及数据块的存储位置信息,如图4所示。

图4 HDFS文件系统雏形

从图4可以看出,文件存储系统中增加了一台服务器A用于管理其他服务器,服务器A记录着文件被切分成多少个数据块,这些数据块分别存储在哪台服务器中,这样当客户端访问服务器A请求下载数据文件时,就能够通过类似查找目录的方式查找数据了。

通过前面的操作,看似解决了所有问题,但其实还有一个非常关键的问题需要处理,那就是当存储数据块的服务器中突然有一台机器宕机,我们就无法正常的获取文件了,这个问题被称为单点故障。针对这个问题,可以采用备份的机制进行解决,如图5所示。

图5 HDFS文件系统

从图5可以看出,每个服务器中都存储两个数据块,进行备份。服务器B存储blk-001和blk-002,服务器C存储blk-002和blk-003,服务器D存储blk-001和blk-003。此时,当服务器C突然宕机,我们也可以通过服务器B和服务器D查询完整的数据块供客户端访问下载。此时就形成了简单的HDFS分布式文件系统。

这里的服务器A被称为NameNode,它维护着文件系统内所有文件和目录的相关信息,服务器B、C、D被称为DataNode,用于存储数据块。

HDFS前世今生

2002年8月,Doug Cutting创建Nutch并托管于SourceForge上;

2003年10月,Google发布论文《Google File System》

2004年,Nutch模仿GFS开发了NDFS(Nutch Distributed File System,NDFS)

2006年2月,Nutch中的NDFS和MapReduce独立出来,成为Apache Lucene项目的子项目,称为Hadoop;创始人Dong Cutting加盟雅虎公司。

HDFS的特点 优点 兼容廉价的硬件设备流数据读写

普通文件系统主要用于随机读写以及与用户进行交互,HDFS放松了一些可移植操作系统接口(Portable Operating System Interface,POSIX)的约束,从而能以流式方式来访问文件系统。

大数据集简单的文件模型

HDFS采用了“一次写入、多次读取”的简单文件模型,文件一旦完成写入,关闭后就无法再次写入,只能被读取。

强大的跨平台兼容性

HDFS采用JAVA语言开发,具有很好的跨平台兼容性。

不足 不适合低延迟数据访问

HDFS主要是面向大规模数据批量处理而设计的,采用流式数据读取,具有很高的数据吞吐率,但这也意味着具有较高的延迟。对于低时延要求的应用程序,HBase是一个更好的选择。

无法高效存储大量小文件

小文件是指文件大小小于一个块(64M)的文件。过多小文件会给系统扩展性和性能带来诸多问题。首先,HDFS采用名称节点来管理文件系统的元数据,这些元数据被保存在内存中,如果文件过多,元数据检索的效率就会变低,甚至会超出内存存储范围。其次,用MapReduce处理大量小文件时,会产生过多的Map任务,进行管理开销会大大增加,因此处理大量小文件的速度远远低于处理同等规模的大文件的速度。再次,访问大量小文件的速度远远低于访问几个大文件的速度,因为访问大量小文件,需要不断从一个数据节点跳到另一个数据节点,严重影响性能。

不支持多用户写入及任意修改文件

HDFS只允许一个文件有一个写入者,而且只允许对文件执行追加操作,不能执行随机写操作。

HDFS的相关概念 块

在传统的文件系统中,为了提高磁盘的读写效率,一般以数据块为单位,而不是以字节为单位进行读写操作。

HDFS也同样采用了块的概念,默认的一个块大小是64MB。在HDFS中的文件会被拆分成多个块,每个块作为独立的单元进行存储。HDFS的块的大小定义这么大,是为了最小化寻址开销。HDFS寻扯开销不仅包括磁盘寻道开销,还包括数据块的定位开销。

当客户端需要访问一个文件时,首先从名称节点获得组成这个文件的数据块的位置列表,然后根据位置列表获取实际存储各个数据块的数据节点的位置,最后数据节点根据数据块信息在本地Linux文件系统中找到对应的文件,并把数据返回给客户端。

块的大小不宜设置过大,因为通常MapReduce中的Map任务一次只处理一个块中的数据,如果启动的任务太少,就会降低作业并行处理速度。

HDFS采用抽象的块概念可以带来以下几个明显的好处:

支持大规模文件存储

文件以块为单位进行存储,一个大规模文件被拆分成若干个文件块,不同的文件块可以被分发到不同的节点上,因此一个文件的大小不会受到单个节点的存储容量的限制,可以远远大于网络中任意节点的存储容量。

简化系统设计

首先,HDFS采用块概念大大简化了存储管理,因为文件块大小是固定的,这样就很容易计算出一个节点可以存储多少文件块;其次,这方便了元数据的管理,元数据不需要和文件块一起存储,可以由其他系统负责管理元数据。

适合数据备份

每个文件块都可以冗余存储到多个节点上,大大提高了系统的容错性和可用性。

名称节点

名称节点负责文件和目录的创建、删除和重命名等

在HDFS中,名称节点负责管理分布式文件系统的命名空间(Namespace),保存了两个核心的数据结构,即FsImage和EditLog。

FsImage用于维护文件系统树以及文件树中所有的文件和文件夹的元数据

操作日志文件EditLog中记录了所有针对文件的创建、删除、重命名等操作。

名称节点记录了每个文件中各个块所在的数据节点的位置信息,客户端只有访问名称节点才能找到请求的文件块所在的位置,进而到相应位置读取所需文件块。

名称节点内的信息不会被持久化存储,而是在系统每次启动时扫描所有数据节点并重构,得到这些信息。

名称节点的启动

名称节点启动时,会将FsImage的内容加载到内存中,然后执行EditLog文件中的各项操作,使内存中的元数据保持最新并同实际数据同步。

上述操作完成(在内存中成功建立文件系统元数据的映射)后,就会创建一个新的FsImage文件和一个空的EditLog文件。

启动成功进入正常运行状态以后,HDFS中的更新操作都会被写入EditLog,而不是直接被写入FsImage。(对于分布式文件系统而言,FsImage文件通常都很庞大(一般都是GB级别以上),如果所有的更新操作都直接在FsImage文件中进行,那么系统的运行速度会变得非常缓慢。相对而言,EditLog通常都要远远小于FsImage,更新操作写入EditLog是非常高效的。)

名称节点在启动的过程中处于“安全模式”,只能对外提供读操作,无法提供写操作。

启动过程结束后,系统就会退出安全模式,进入正常运行状态,对外提供读写操作。

数据节点

数据节点(DataNode)是分布式文件系统HDFS的工作节点,负责数据的存储和读取。

数据节点会根据客户端或者名称节点的调度来进行数据的存储和检索。

定期向名称节点发送自己所存储的块的列表信息。

每个数据节点中的数据会被保存在各自节点的本地Linux文件系统中。

第二名称节点

要解决的问题

在名称节点运行期间,HDFS的更新操作直接被写入EditLog文件,因此EditLog文件会逐渐变大。正常运行期间,变大的EditLog文件通常对于系统性能不会产生显著影响,但是当名称节点重启时,需要将FsImage加载到内存中,然后逐条执行EditLog中的记录,使FsImage保存最新。这时,如果EditLog很大,就会导致整个过程变得非常缓慢;同时,名称节点在启动过程中长期处于“安全模式”,无法正常对外提供写操作,影响用户的使用。

具有的功能

第二名称节点(Secondary NameNode)是HDFS架构的一个重要组成部分,具有两个方面的功能:

(1)它可以完成EditLog与FsImage的合并操作,减小EditLog文件大小,缩短名称节点重启时间

第二名称节点定期和名称节点通信,请求停止使用EditLog文件,暂时将新到达的写操作添加到一个新的EditLog.new文件中第二名称节点通过HTTP GET方式把名称节点中的FsImage文件和EditLog文件拉回本地相应目录下,再加载到内存中。第二名称节点把加载到内存的FsImage文件和EditLog文件执行合并操作,即在内存中逐条执行EditLog中的操作,使FsImage保持最新。第二名称节点通过post方式把合并后得到的最新的FsImage.ckpt文件发送到名称节点名称节点收到最新的FsImage.ckpt文件后,会替换旧的FsImage文件,同时,用EditLog.new文件去替换EditLog文件,从而减小了EditLog文件的大小

(2)它可以作为名称节点的“检查点”,保存名称节点中的元数据信息

???????? 第二名称节点只是对名称节点的t1时点的数据做了备份,无法保存在其后发生故障时名称节点的数据;同时,在HDFS的设计中,也并不支持把系统直接切换到第二名称节点。因此第二名称节点只是起到了名称节点的“检查点”作用,并不能起到“热备份”作用。

元数据

元数据指HDFS文件系统中,文件和目录的属性信息。HDFS实现时,采用了镜像文件(FsImage) + 日志文件(EditLog)的备份机制。文件的镜像文件中内容包括:修改时间、访问时间、数据块大小、组成文件的数据块的存储位置信息。目录的镜像文件内容包括:修改时间、访问控制权限等信息。日志文件记录的是:HDFS的更新操作。

HDFS的体系结构

HDFS采用了主从(Master/Slave)结构模型,一个HDFS集群包括一个名称节点和若干个数据节点。名称节点作为中心服务器,负责管理文件系统的命名空间及客户端对文件的访问。集群中的数据节点一般是一个节点运行一个数据节点进程,负责处理文件系统客户端的读/写请求,在名称节点的统一调度下进行数据块的创建、删除和复制等操作。每个数据节点的数据实际上是保存在本地Linux文件系统中的。每个数据节点会周期性地向名称节点发送“心跳”信息,报告自己的状态,没有按时发送心中信息的数据节点会被标记为“死机”,不会再给它分配任何I/O请求。

用户在使用HDFS时,可以像在普通文件系统中那样,使用文件名去存储和访问文件。

把文件名发送给名称节点名称节点根据文件名找到对应的数据块根据每个数据块信息找到实际存储各个数据块的数据节点的位置把数据节点位置发送给客户端客户端直接访问这些数据节点获取数据 命名空间管理

HDFS的命名空间包含目录、文件和块。

命名空间管理是指命名空间支持对HDFS中的目录、文件和块做类似文件系统的创建、修改、删除等基本操作。

在当前的HDFS体系结构中,整个HDFS集群只有一个命名空间,并且只有唯一一个名称节点,该节点负责对这个命名空间进行管理。

HDFS使用的是传统的分级文件体系,用户可以像使用普通文件系统一样,创建、删除目录和文件,在目录间转移文件、重命名文件等。但是,HDFS还没有实现磁盘配额和文件访问权限等功能,也不支持文件的硬连接和软链接(快捷方式)。

通信协议

HDFS通信协议都是构建在TCP/IP基础之上的。

客户端通过一个可配置的端口向名称节点主动发起TCP连接,并使用客户端协议与名称节点进行交互。

名称节点和数据节点之间使用数据节点协议进行交互。

客户端与数据节点的交互通过远程过程调用(Remote Procedure Call,RPC)来实现。

名称节点不会主动发起RPC,而是响应来自客户端和数据节点的RPC请求。

体系结构的局限性

1、命名空间的限制

名称节点是保存在内存中的,因此名称节点能够容纳对象的个数会受到内存空间大小的限制。

2、性能的瓶颈

整个分布式文件系统的吞吐量受限于单个名称节点的吞吐量。

3、隔离问题

由于集群中只有一个名称节点,只有一个命名空间,因此无法对不同应用程序进行隔离。

4、集群的可用性

一旦这个唯一的名称节点发生故障,会导致整个集群变得不可用。

HDFS的存储原理

HDFS的存储原理,包括数据的冗余存储、数据存储策略、数据错误与恢复。

数据的冗余存储

为了保证系统的容错性和可用性,HDFS采用了多副本方式对数据进行冗余存储,通常一个数据块的多个副本会被分布到不同的数据节点上。

多副本方式的优点:

加快数据传输速度

当多个客户端需要同时访问一个文件时,可以让各个客户端分别从不同的数据块副本中读取数据,这就大大加快了数据传输速度。

容易检查数据错误

HDFS的数据节点之间通过网络传输数据,采用多个副本可以很容易判断数据传输是否出错。

保证数据的可靠性

即使某个数据节点出现故障失效,也不会造成数据丢失。

数据存取策略

数据存放

HDFS采用了以机架(Rack)为基础的数据存放策略。

一个HDFS集群通常包含住多个机架,不同机架之间的数据通信需要经过交换机或者路由器,同一个机架中不同机器之间的通信则不需要经过交换机或路由器,这意味着一个机架中不同机器之间的通达信要比不同机架之间机器的通信带宽大。

HDFS默认每个数据节点都在不同的机架上。缺点:写入数据时不能充分利用同一机架内部机器间的带宽。优点:可以获得很高的数据可靠性;可以在多个机架上并行读取数据,大大提高数据读取速度;可以更容易地实现系统内部负载均衡和错误处理。

HDFS默认的冗余余缺因子是3,每一个文件块会被同时保存到3个地方,其中,有两个副本放在同一个机构的不同机器上,第3个副本放在不同机架的机器上;这样即可保证机架发生异常时的数据恢复,也可以提高数据读写性能。

HDFS副本放置策略如下:

如果是在集群内发起写操作,则把第1个副本放置在发起操作请求的数据节点上,实现就近写入数据。如果是在集群外发起写操作请求,则从集群内部挑选一台磁盘空间较为充足、CPU不太忙的数据节点,作为延续1个副本的存放地。第2个副本会被放置在与第1个副本不同的机架的数据节点上第3个副本会被放置在与第1个副本相同的机架的其他节点上如果还有更多的副本,则继续从集群中随机选择数据节点进行存放

数据读取

HDFS提供了一个API可以确定一个数据节点所属的机架ID,客户端也可以调用API确定自己所属的机架ID。

客户端读取数据时,从名称节点获得数据块不同副本的存放位置列表,列表中包含了副本所在的数据节点,调用API来确定客户端和这些数据节点所属的机架ID。当发现某个数据块副本对应的机架ID和客户端对应的机架ID相同时,就优先选择该副本读取数据,如果没有发现,就随机选择一个副本读取数据。

数据复制

HDFS的数据复制采用了流水线复制的策略。

当客户端要往HDFS中写入一个文件的流程

文件会首先被写入本地,并被切分成若干个块,每个块的大小是由HDFS的设定值来决定的。每个块都向HDFS集群中的名称节点发起写请求,名称节点会根据系统中各个数据节点的使用情况,选择一个数据节点列表返回给客户端客户端首先把数据写入列表中的第1个数据节点,同时把列表传给第1个数据节点,当第1个数据节点接收到4KB数据的时候,写入本地,并且向列表中的第2个数据节点发起连接请求,把自己已经接收到的4KB数据和列表传给第2个数据节点(DataNodes基于HDFS可用性、复制因子和机架感知的选择是完全随机的)当第2个数据节点接收到4KB数据的时候,写入本地,并且向列表中的第3个数据节点发起连接请求,依次类推,列表中的多个数据节点形成一条数据复制的流水线最后,当文件写完的时候,数据复制也同时完成

数据错误与恢复

HDFS设计了相应的机制检测数据错误和进行自动恢复,主要包括以下3种情形:

名称节点出错

Hadoop采用两种机制来确保名称节点的安全:

把名称节点上的元数据信息同步存储到其他文件系统运行一个第二名称节点,当名称节点死机以后,可以把运行第二名称节点作为一种弥补措施,利用第二名称节点中的元数据信息进行系统恢复;(这种方式仍然后丢失部分数据)

一般会把上述两种方式结合使用,当名称节点发生死机时,首先到远程挂载的网络文件系统中获取备份的元数据信息,放到第二名称节点上进行恢复,并把第二名称节点作为名称节点来使用。

数据节点出错

当数据节点因网络故障或节点故障被标记为“死机”后,有可能出现一种情形,即由于一些数据节点的不同用,会导致一些数据块的副本数量小于冗余因子。名称节点会定期检查这种情况,一旦发现某个数据块的副本数量小于冗余因子,就会启动数据冗余复制,为它生成新的副本。HDFS与其他分布式文件系统的最大区别就是可以调整冗余数据的位置。

数据出错

客户端在读取数据后,会采用MD5和SHA-1对数据块进行检验,以确定读取正确的数据。在文件被创建时,客户端就会对每一个文件块进行信息摘录,并把这些信息写入同一个路径的隐藏文件里面。当客户端读取文件的时候,会先读取该信息文件,然后利用该信息文件对每个读取的数据块进行校验。如果校验出错,客户端就会请求到另外一个数据节点读取该文件块,并且向名称节点报告这个文件块有错误,名称节点会定期检查并重新复制这个块。

HDFS可靠性保障措施

HDFS的主要设计目标之一是在故障情况下,要保障数据存储的可靠性。HDFS具备了完善的冗余备份和故障恢复机制。一般通过dfs.replication设置备份份数,默认3。

冗余备份

将数据写入到多个DataNode节点上,当其中某些节点宕机后,还可以从其他节点获取数据并复制到其他节点,使备份数达到设置值。dfs.replication设置备份数。

副本存放

HDFS采用机架感知(Rack-aware)的策略来改进数据的可靠性、可用性和网络宽带的利用率。当复制因子为3时,HDFS的副本存放策略是:第一个副本放到同一机架的另一个节点(执行在集群中)/随机一个节点(执行在集群外)。第二个副本放到本地机架的其他任意节点。第三个副本放在其他机架的任意节点。这种策略可以防止整个机架失效时的数据丢失,也可以充分利用到机架内的高宽带特效。

心跳检测

NameNode会周期性的从集群中的每一个DataNode上接收心跳包和块报告,NameNode根据这些报告验证映射和其他文件系统元数据。当NameNode没法接收到DataNode节点的心跳报告后,NameNode会将该DataNode标记为宕机,NameNode不会再给该DataNode节点发送任何IO操作。同时DataNode的宕机也可能导致数据的复制。一般引发重新复制副本有多重原因:DataNode不可用、数据副本损坏、DataNode上的磁盘错误或者复制因子增大。

安全模式

在HDFS系统的时候,会先经过一个完全模式,在这个模式中,是不允许数据块的写操作。NameNode会检测DataNode上的数据块副本数没有达到最小副本数,那么就会进入完全模式,并开始副本的复制,只有当副本数大于最小副本数的时候,那么会自动的离开安全模式。DataNode节点有效比例:dfs.safemode.threshold.pct(默认0.999f),所以说当DataNode节点丢失达到1-0.999f后,会进入安全模式。

数据完整性检测

HDFS实现了对HDFS文件内容的校验和检测(CRC循环校验码),在写入数据文件的时候,也会将数据块的校验和写入到一个隐藏文件中()。当客户端获取文件后,它会检查从DataNode节点获取的数据库对应的校验和是否和隐藏文件中的校验和一致,如果不一致,那么客户端就会认为该数据库有损坏,将从其他DataNode节点上获取数据块,并报告NameNode节点该DataNode节点的数据块信息。

回收站

HDFS中删除的文件先会保存到一个文件夹中(/trash),方便数据的恢复。当删除的时间超过设置的时间阀后(默认6小时),HDFS会将数据块彻底删除。

映像文件和事务日志

这两种数据是HDFS中的核心数据结构。

快照 HDFS高可用性(HA:High Availability)

HDFS HA是用来解决NameNode 单点故障问题的。

HDFS联邦是用来解决 NameNode 内存瓶颈问题的。

NameNode单点故障

单点故障(SPOF: Single Point Of Failure)。

对于分布式文件系统HDFS而言,名称节点(NameNode)是系统的核心节点,存储了各类元数据信息,并负责管理文件系统的命名空间和客户端对文件的访问。但是,在HDFS 1.0中,只存在一个名称节点,一旦这个唯一的名称节点发生故障,就会导致整个集群变得不可用,这就是常说的“单点故障”。

虽然,HDFS1.0中存在一个第二名称节点(Secondary NameNode),但是第二名称节点并不是名称节点的备用节点,它与名称节点有着不同的职责。第二名称节点的主要功能是周期性地从名称节点获取命名空间镜像文件(FsImage)和修改日志(EditLog),进行合并后发送给名称节点,替换掉原来的FsImage,以防止日志文件EditLog过大,导致名称节点失败恢复时间过长。合并后的命名空间镜像文件FsImage在第二名称节点中也保存一份,当名称节点失效的时候,可以使用第二名称节点中的FsImage进行恢复。

虽然第二名称节点能起到保护数据丢失的作用,但是并不能提高可用性,无法提供“热备份”功能,即在名称节点发生故障的时候,系统无法实时切换到第二名称节点立即对外提供服务,仍然需要进行停机恢复,因此HDFS 1.0的设计是存在单点故障的。

当NameNode出现单点故障时,常规的做法是使用元数据备份重新启动一个NameNode。元数据备份可能来源于:

多文件系统写入中的备份Second NameNode的检查点文件

启动新的NameNode之后,需要重新配置客户端和DataNode的NameNode信息。另外重启耗时一般比较久,稍具规模的集群重启经常需要几十分钟甚至数小时,造成重启耗时的原因大致有:?

元数据镜像文件载入到内存耗时较长。?需要重放EditLog?需要收到来自DataNode的状态报告并且满足条件后才能离开安全模式提供写服务。 Hadoop的HA方案

在 Hadoop2.x中采用了高可用(High Availability,HA)架构。 使得HDFS 1.0中 NameNode 的单点故障问题得到了解决。

HDFS NameNode 高可用整体架构如图所示。

在一个典型的HA集群中,一般设置两个名称节点,其中一个名称节点处于“活跃”(Active)状态,另一个处于“待命”(Standby)状态。处于活跃状态的名称节点负责对外处理所有客户端的请求,处于待命状态的名称节点则作为备用节点,保存足够多的系统元数据,当名称节点出现故障时提供快速恢复能力。也就是说,在HDFS HA中,处于待命状态的名称节点提供了“热备份”,一旦活跃名称节点出现故障,就可以立即切换到待命名称节点,不会影响到系统的正常对外服务。

由于待命名称节点是活跃名称节点的“热备份”,因此活跃名称节点的状态信息必须实时同步到待命名称节点。两种名称节点的状态同步,可以借助于一个共享存储系统来实现,比如网络文件系统(Network File System,NFS)、仲裁日志管理器(Quorum Journal Manager,QJM)或者ZooKeeper。活跃名称节点将更新数据写入共享存储系统,待命名称节点会一直监听该系统,一旦发现有新的写入,就立即从公共存储系统中读取这些数据并加载到自己的内存中,从而保证与活跃名称节点状态完全同步。

此外,名称节点中保存了数据块到实际存储位置的映射信息,即每个数据块是由哪个数据节点存储的。当一个数据节点加入HDFS集群时,它会把自己所包含的数据块列表报告给名称节点,此后会通过“心跳”的方式定期执行这种告知操作,以确保名称节点的块映射是最新的。因此,为了实现故障时的快速切换,必须保证待命名称节点一直包含最新的集群中各个块的位置信息。为了做到这一点,需要给数据节点配置两个名称节点的地址(即活跃名称节点和待命名称节点),并把块的位置信息和心跳信息同时发送到这两个名称节点。为了防止出现“两个管家”现象,HA还要保证任何时刻都只有一个名称节点处于活跃状态,否则,如果有两个名称节点处于活跃状态,HDFS集群中出现“两个管家”,就会导致数据丢失或者其他异常。这个任务是由ZooKeeper来实现的,ZooKeeper可以确保任意时刻只有一个名称节点提供对外服务。

failover:失效转移、故障转移

我们可以看出 NameNode的高可用架构主要分为下面几个部分:

在典型的HA集群中,一般设置两个独立的机器作为 NameNode。

任何时刻,只有一个 NameNode处于Active状态,另一个处于Standby 状态。

Active NameNode负责所有的客户端操作,而Standby NameNode只是简单的充当Slave,它负责维护状态信息以便在需要时能快速切换。

主备切换控制器 ZKFailoverController

ZKFailoverController作为独立的进程运行,对NameNode的主备切换进行总体控制。

ZKFailoverController能及时检测到NameNode的健康状况,在主NameNode故障时借助 Zookeeper实现自动的主备选举和切换,当然NameNode目前也支持不依赖于Zookeeper的手动主备切换。

Zookeeper集群的目的是为主备切换控制器提供主备选举支持。

ZKFailoverController 的主要职责

健康监测

周期性的向它监控的 NameNode发送健康探测命令,从而来确定某个NameNode是否处于健康状态,如果机器宕机,心跳失败,那么ZKFailoverController就会标记它处于一个不健康的状态

会话管理

如果NameNode是健康的,ZKFailoverController就会在Zookeeper中保持一个打开的会话。

如果NameNode同时还是Active状态的,那么kfc还会在Zookeeper中占有一个类型为短暂类型的znode,当这个Name Node挂掉时,这个znode将会被删除,然后备用的 NameNode将会得到这把锁,升级为主NN,同时标记状态为 Active。

当宕机的NameNode新启动时,它会再次注册Zookeeper,发现已经有znode锁了,便会自动变为Standby状态,如此往复循环,保证高可靠。

Hadoop2.x仅仅支持最多配置2个NameNode,Hadoop3.x支持多于2个的 NameNode。

Master选举

如上所述,通过在Zookeeper中维持一个短暂类型的ZNode,来实现抢占式的锁机制,从而判断哪个NameNode为Active状态。

共享存储系统 Quorum Journal Node

为了让Standby Node与Active Node保持状态的同步,它们两个都要与称为"JournalNodes"(JNs)的一组独立的进程通信。

Active Node 所做的任何命名空间的修改,都将修改记录的日志发送给大多数的 JNs。

Standby Node 能够从 JNs 读取 edits ,并且时时监控它们对 EditLog 的修改。

Standby Node获取 edits 后,将它们应用到自己的命名空间。

故障切换时, Standby 将确保在提升它自己为 Active 状态前已经从 JNs 读完了所有的 edits ,这就确保了故障切换发生前(两个 NameNode)命名空间状态是完全同步的。

DataNode节点

除了通过共享存储系统共享HDFS的元数据信息之外,主 NameNode和备 NameNode 还需要共享 HDFS 的数据块和 DataNode之间的映射关系。

DataNode会同时向主 NameNode 和备 NameNode 上报数据块的位置信息。

采用HA的HDFS集群配置两个NameNode,分别处于Active和Standby状态。当Active NameNode故障之后,Standby接过责任继续提供服务,用户没有明显的中断感觉。一般耗时在几十秒到数分钟。?

HA涉及到的主要实现逻辑有:

1)主备共享EditLog存储

主NameNode和待命的NameNode共享一份EditLog,当主备切换时,Standby通过回放EditLog同步数据。?

共享存储通常有2种选择:

NFS:Network File System 网络文件系统QJM:Quorum Journal Manager 仲裁日志管理器或Zookeeper

QJM是专门为HDFS的HA实现而设计的,用来提供高可用的EditLog。QJM运行一组Journal Node,EditLog必须写到大部分的Journal Node。通常使用3个节点,因此允许一个节点失败,类似ZooKeeper。注意QJM没有使用ZK,虽然HDFS HA的确使用了ZK来选举主Namenode。一般推荐使用QJM。

2)DataNode需要同时往主备发送Block Report?

因为Block映射数据存储在内存中(不是在磁盘上),为了在Active NameNode挂掉之后,新的NameNode能够快速启动,不需要等待来自DataNode的Block Report,DataNode需要同时向主备两个NameNode发送Block Report。

3)客户端需要配置failover模式(失效备援模式,对用户透明)?

NameNode的切换对客户端来说是无感知的,通过客户端库来实现。客户端在配置文件中使用的HDFS URI是逻辑路径,映射到一对NameNode地址。客户端会不断尝试每一个NameNode地址直到成功。

4)Standby替代Secondary NameNode?

如果没有启用HA,HDFS独立运行一个守护进程作为Secondary NameNode。定期checkpoint,合并镜像文件和edit日志。

如果当主NameNode失败时,备份NameNode正在关机(停止 Standby),运维人员依然可以从头启动备份NameNode,这样比没有HA的时候更省事,算是一种改进,因为重启整个过程已经标准化到Hadoop内部,无需运维进行复杂的切换操作。

NameNode的切换通过代failover controller来实现。failover controller有多种实现,默认实现使用ZooKeeper来保证只有一个NameNode处于active状态。

每个NameNode运行一个轻量级的failover controller进程,该进程使用简单的心跳机制来监控NameNode的存活状态并在NameNode失败时触发failover。Failover可以由运维手动触发,例如在日常维护中需要切换主NameNode,这种情况graceful(优雅的) failover,非手动触发的failover称为ungraceful failover。

在ungraceful failover的情况下,没有办法确定失败(被判定为失败)的节点是否停止运行,也就是说触发failover后,之前的主NameNode可能还在运行。QJM一次只允许一个NameNode写edit log,但是之前的主NameNode仍然可以接受读请求。Hadoop使用fencing来杀掉之前的NameNode。Fencing通过收回之前NameNode对共享的edit log的访问权限、关闭其网络端口使得原有的NameNode不能再继续接受服务请求。使用STONITH技术也可以将之前的主NameNode关机。

最后,HA方案中NameNode的切换对客户端来说是不可见的,前面已经介绍过,主要通过客户端库来完成。

HDFS Federation[?fed??re??n]联邦

Federation背景

HDFS 1.0采用单名称节点的设计,不仅会带来单点故障问题,还会存在可扩展性、系统整体性能和隔离性等问题。

在可扩展性方面

名称节点把整个HDFS中的元数据信息都保存在自己的内存中,HDFS 1.0中只有一个名称节点,不可以水平扩展,而单个名称节点的内存空间是有上限的,这限制了系统中数据块、文件和目录的数目。那么是否可以通过纵向扩展的方式(即为单个名称节点增加更多的CPU、内存等资源)解决这个问题呢?答案是否定的。纵向扩展带来的第一个问题就是,会带来过长的系统启动时间。其次,当在内存空间清理发生错误,就会导致整个HDFS集群死机。

在系统整体性能方面

整个HDFS的性能会受限于单个名称节点的吞吐量。

在隔离性方面

单个名称节点难以提供不同程序之间的隔离性,一个程序可能会影响其他程序的运行(比如一个程序消耗过多资源导致其他程序无法顺利运行)。HDFS HA虽然提供了两个名称节点,但是在某个时刻只公有一个节点处于活跃状态,另一个则处于待命状态。

因而,HDFS HA在本质上还是单名称节点,只是通过“热备份”设计方式解决了单点故障问题,并没有解决可扩展性、系统整体性能和隔离性3个方面的问题。

在HDFS联邦中,设计了多个相互独立的名称节点,使得HDFS的命名服务能够横向扩展,这些名称节点分别进行各自命名空间和块的管理,相互之间是联邦关系,不需要彼此协调。HDFS联邦并不是真正的分布设计,但是采用这种简单的“联合”设计方式,在实现和管理复杂性方面,都要远低于分布式设计,而且可以快速满足需求。在兼容性方面,HDFS联邦具有良好的向后兼容性,可以无缝地支持单名称节点架构中的配置。所以,原有针对单名称节点的部署配置,不需要做任何修改就可以继续工作。

HDFS联邦中的名称节点提供了命名空间和块管理功能。在HDFS联邦中,所有名称节点会共享底层的数据节点存储资源。每个数据节点要向集群中所有的名称节点注册,并周期性地向名称节点发送“心跳”和块信息,报告自己的状态,同时处理来自名称节点的指令。

正因为如此,在 Hadoop2.x中引入了Federation的机制,可以解决单名称节点存在的如下问题。

HDFS集群扩展性

多个 NameNode各自分管一部分目录,使得一个集群可以扩展到更多节点,不再像 HDFS 1.0中由于内存的限制制约文件存储数目。

性能更高效

多个 NameNode 管理不同的数据,且同时对外提供服务,将为用户提供更高的读写吞吐率。

良好的隔离性

用户可根据需要将不同业务数据交由不同 NameNode 管理,这样不同业务之间影响很小。

注意,HDFS联邦并不能解决单点故障问题。也就是说,每个名称节点都存在单点故障问题,需要为每个名称节点部署一个后备名称节点,以应对名称节点死机后对业务产生的影响。

单组Namenode架构

HDFS主要有两大模块:

Namespace (命名空间)

由目录文件和块组成,支持所有命名空间相关的文件操作,如创建、删除、修改,查看所有文件和目录。

Block Storage Service (块存储服务)

包括Block管理和存储两部分

Block管理 通过控制注册以及阶段性的心跳,来保证DataNode的正常运行;处理Block的报告信息和维护块的位置信息;支持Block相关的操作,如创建、删除、修改、获取Block的位置信息;管理Block的冗余信息、创建副本、删除多余的副本等。 存储 DataNode提供本地文件系统上Block的存储、读写、访问等。

单组Namenode架构

HDFS主要包括两方面:NameSpace和Block Storage。HDFS中有两种类型的节点,NameNode负责NameSpace和Block Management,而DataNode负责Storage。

通常情况下,单组Namenode能够满足集群大部分需求,单点故障问题可以通过启用HA解决,单组Namenode包含一主一备两个Namenode, 通过Zookeeper保障及控制Failover,而Zookeeper本身具有高可用特性,好像完全不用担心单点故障造成集群不可用的问题,一切看起来似乎非常完美。然而,随着集群规模不断的增长,似乎又不是那么完美了。

单组Namenode局限性

NameSpace(命名空间的限制)

由于Namenode在内存中存储所有的元数据(metadata)。NN在管理大规模的命名空间时,单个Namenode所能存储的对象(文件+块)数目受到Namenode所在JVM的堆【内存大小的限制】。

随着数据的飞速增长,存储的需求也随之增长。50G的heap能够存储20亿个对象—>4000个datanode—>12PB的存储(假设文件平均大小为40MB)。单个datanode从4T增长到36T,集群的尺寸增长到8000个datanode。存储的需求从12PB增长到大于100PB。

性能的瓶颈

由于是单个Namenode的HDFS架构,因此整个HDFS文件系统的吞吐量受限于单个NameNode的吞吐量。这将成为下一代MapReduce的瓶颈。

隔离问题

由于仅有一个Namenode,无法隔离各个程序,因此HDFS上的一个实验程序很可能影响整个HDFS上运行的程序。 NN在内部用一把全局锁撸遍所有的元数据操作来保证数据的一致性

集群的可用性

在只有一个Namenode的HDFS中,此Namenode的宕机无疑会导致整个集群的不可用。(低可用性)

Namespace和Block Management(管理)的紧密耦合

Hadoop 1.x在Namenode中的Namespace和Block Management组合的紧密耦合关系会导致如果想要实现另外一套。Namenode方案比较困难,而且也限制了其他想要直接使用块存储的应用。

纵向扩展NameNode的问题

(比如将NameNode的Heap堆空间扩大到512GB。)

启动时间太长。(Hadoop 1.x具有50GB Heap Namenode的HDFS启动一次大概需要30分钟到2小时)Namenode在Full GC时,如果发生错误将会导致整个集群宕机。对大JVM Heap进行调试比较困难。优化Namenode的内存使用性价比比较低

HDFS Federation架构

HDFS数据存储采取分层的结构。也就是说,所有关于存储数据的信息和管理是放在 NameNode这边,而真实的数据则是存储在各个DataNode下。

这些隶属于同一个NameNode所管理的数据都在同一个命名空间NameSpace下,而一个NameSpace对应一个Block Pool。

Block Pool 是同一个NameSpace下的Block的集合,当然这是我们最常见的单个 NameSpace的情况,也就是一个NameNode管理集群中所有元数据信息的时候,如果我们遇到了前面提到的 NameNode 内存使用过高的问题,这时候怎么办?

元数据空间依然还是在不断增大,一味调高 NameNode的JVM大小绝对不是一个持久的办法。这时候就诞生了 HDFS Federation 的机制。

Hadoop-2.X版本引入HDFS Federation机制。

HDFS 1.0只有一个命名空间,这个命名空间使用底层数据节点全部的块。与HDFS 1.0不同的是,HDFS联邦拥有多个独立的命名空间,其中,每一个命名空间管理属于自己的一组块,这些属于同一个命名空间的块构成一个“块池”(Block Pool)。每个数据节点会为多个块池提供块的存储。可以看出,数据节点是一个物理概念,块池则属于逻辑概念,一个块池是一组块的逻辑集合,块池中的各个块实际上存储在各个不同的数据节点中。因此,HDFS联邦中的一个名称节点失败,也不会影响到与它相关的数据节点继续为其他名称节点提供服务。

HDFS Federation对NameNode做了横向的拓展,Federation采用多组独立的NameNodes/NameSpaces。所有的NameNodes是联邦的,其中每一个NameNode管理文件系统命名空间中的一部分。也就是说,他们之间相互独立且不需要互相协调,各自分工,管理自己的区域。DataNode被用作通用的数据块存储设备,每一个DataNode会注册到集群中的所有NameNode,且周期性的向所有NameNode发送心跳和块报告,并执行来自所有NameNode的命令。

Federation架构与单组NameNode架构相比,主要是NameSpace被拆分成了多个独立的部分,分别由独立的NameNode进行管理。

NameNode和Block Pool一起被称作NameSpace Volume,它是管理的基本单位,当一个NameSpace被删除后,所有DataNode上与其对应的Block Pool也会被删除。当集群升级时,每个NameSpace Volume作为一个基本单元进行升级。

每一个NameNode都要维护一个命名空间卷(NameSpace Volume),由命名空间的元数据和一个数据块池组成。

总结:

1、多个NameNode是联合的;

2、NameNode之间互相独立,不需要协调;

3、DataNode之间用作所有NameNode的快的公共存储;

4、DataNode需要对所有NameNode进行注册;

5、DataNode定期发送心跳和Block报告给所有的NN;

6、DataNode需要处理来自所有NN的命令;

HDFS联邦的访问方式

对于HDFS联邦中的多个命名空间,可以采用客户端挂载表(Client-Side Mount-Table)方式进行数据共享和访问。每个阴影三角形代表一个独立的命名空间,上方空白三角形表示 从客户方向去访问下面子命名空间。客户可以通过不同的挂载点来访问不同的子命名空间。这就是HDFS联邦中命名空间管理的基本管理,即把各个命名空间挂载到全局“挂载表”(Mount-Table)中,实现数据全局共享。同样地,命名空间挂载到个人的挂载表中,就成为应用程序可见的命名空间。

Block Pool (块池)

数据块池(Block Pool)包含了该命名空间下文件的所有数据块。

Block Pool允许一个命名空间在不通知其他命名空间的情况下为一个新的block创建Block ID。同时一个NameNode失效不会影响其下DataNode为其他NameNode服务。

每个Block Pool内部自治,也就是说各自管理各自的block,不会与其他Block Pool交流。一个NameNode挂掉了,不会影响其他NameNode。

当DataNode与NameNode建立联系并开始会话后自动建立Block Pool。每个block都有一个唯一的标识,这个标识我们称之为扩展块ID,在HDFS集群之间都是惟一的, 为后集群归并创造了条件。

DataNode中的数据结构都通过块池ID索引,即DataNode中的BlockMap,storage等都通过BPID索引。

某个NameNode上的NameSpace和它对应的Block Pool一起被称为NameSpace Volume。它是管理的基本单位。当一个NN/NS被删除后,所有DN上对应的Block Pool也会被删除。当集群升级时,每个NameSpace Volume作为一个基本元进行升级。

ClusterlD

增加一个新的ClusterID来标识在集群中所有的节点。当一个NameNode被格式化的时候,这个标识被指定或自动生成,这个ID会用于格式化集群中的其它NameNode。

优点、缺点及局限性

优点

Namespace的可扩展性

HDFS的水平扩展,但是命名空间不能扩展,通过在集群中增加Namenode来扩展Namespace,以达到大规模部署或者解决有很多小文件的情况。

Performance (性能)

在之前的框架中,单个Namenode文件系统的吞吐量是有限制的,增加更多的Namenode能增大文件系统读写操作的吞吐量。

lsolation (隔离)

一个单一的Namenode不能对多用户环境进行隔离,一个实验性的应用程序会加大Namenode的负载,减慢关键的生产应用程序,多个Namenode情况下,不同类型的程序和用户可以通过不同的Namespace来进行隔离。

缺点

交叉访问问题

由于Namespace被拆分成多个,且互相独位,一个文件路径只允许存在一个Namespace中。如果应用程序要访问多个文件路径,那么不可避免的会产生交叉访问Namespace的情况。比如MR、Spark任务,都会存在此类问题。

管理性问题

启用Federation后,HDFS很多管理命令都会失效,比如"hdfs dfsadmin、hdfs fsck"等,除此之外,"hdfs dfs cp/mv"命令同样失效,如果要在不同Namespace间拷贝或移动数据,需要使用distcp命令,指定绝对路径。

没有完全解决单点故障

HDFS Federation并没有完全解决单点故障问题。虽然namenode/namespace存在多个,但对于单个namenode来说,仍然存在单点故障。

如果某个namenode挂掉了,其管理的相应文件便不可以访问。

Federation中每个namenode仍然像之前一样,配有一个secondary namenode,以便主namenode挂掉后,用于还原元数据信息

局限性

HDFS路径Scheme需要变为ViewFs, ViewFs路径和其他Scheme路径互不兼容, 比如DistributedFileSystem无法处理ViewFs为Scheme的路径,也就是说如果启用,则需要将Hive meta、ETL脚本、 MR/Spark作业中的所有HDFS路径均的scheme改为viewfs。

如果将fs.defaultFS的配置从hdfs://ns1/变为viewfs://ns/,将导致旧代码异常,通过脚本对用户上万个源码文件的分析,常用的HDFS路径风格多样,包括hdfs:///user、hdfs://ns1/user、/user等,如果fs.defaultFS有所更改,hds:///user将会由于缺失nameservice变为非法HDFS路径。

ViewFs路径的挂载方式与Linux有所区别:

如果一个路径声明了挂载,那么其同级目录都需要进行挂载,比如/user/path_one挂载到了hdfs://ns1/user/path_one上,那么/user/path_two也需要在配置中声明其挂载到哪个具体的路径上。如果一个路径声明了挂载,那么其子路径不能再声明挂载,比如/user/path_ one挂载到了hdfs://ns1/user/path_ one上,那么其子路径也自动并且必须挂载到hdfs://ns1/user/path_ one上。

一次路径请求不能跨多个挂载点:

由于HDFS客户端原有的机制,一个DFSClient只对应一个nameservice, 所以一次路径处理不能转为多个nameservice的多次RPC。对于跨挂载点的读操作,只根据挂载配置返回假结果。对于跨挂载点的rename (move路径)操作,会抛出异常。

Federation架构中,NameNode相互独立,NameNode元数据、 DataNode中块文件都没有进行共享,如果要进行拆分,需要使用DistCp, 将数据完整的拷贝一份,存储成本较高;数据先被读出再写入三备份的过程,也导致了拷贝效率的低效。

Federation是改造了客户端的解决方案,重度依赖客户端行为。方案中NameNode相互独立,对Federation没有感知。另外HDFS为Scheme的路径,不受Federation挂载点影响,也就是说如果对路径进行了namespace拆分后,如果因为代码中的路径或客户端配置没有及时更新,导致流程数据写入老数据路径,那么请求依然是合法但不符合预期的。

在HDFS中namespace是指NameNode中负责管理文件系统中的树状目录结构以及文件与数据块的映射关系的一层逻辑结构,在Federation方案中,NameNode之间相互隔离,因此社区也用一个namespace来指代Federation中一组独立的NameNode及元数据。

Scheme是URI命名结构([scheme:]//authority]path][?query][#fragment]) 中的一部分,于标识URI所使用的协议,HDFS路径也是一个URI, 常见的Scheme为HDFS, 在Federation的方案中,HDFS路径Scheme为ViewFs。

挂载点(mount point),它在HDFS Federation中和Linux中的概念近似,指在HDFS客户端上下文中,将ViewFs为Scheme的一个路径,比如viewfs://ns/user, 映射到一个具体的HDFS路径上,比如hdfs://ns2/user, 这个路径可以是任意Scheme的HDFS路径,这样对于viewfs://ns/user实际上会被转换为对hdfs://ns2/user的操作。

HDFS常用命令

关于HDFS的Shell命令有一个统一的格式:

hadoop command [genericoptions] [commandoptions]

HDFS有很多命令,其中fs命令可以说是HDFS最常用的命令,利用fs命令可以查看HDFS的目录结构、上传和下载数据、创建文件等。该命令的用法如下:

hadoop fs [genericoptions) tcommandoptions]

具体如下。

hadoop fs -ls <path>。显示<path>指定的文件的详细信息。hadoop fs -ls -R <path>。 ls命令的递归版本。hadoop fs -cat <path>。 将<path>指定的文件的内容输出到标准输出( stdout )。hadoop fs -chgrp [-R] group <path>。将<path>指定的文件所属的组改为group,使用-R对<path>指定的文件夹内的文件进行递归操作。这个命令只适用于超级用户。hadoop fs -chown [-R] [owner] [: [group]] <path>。 改变<path>指定的文件所有者,-R用于递归改变文件夹内的文件所有者。这个命令只适用于超级用户。hadoop fs -chmod [-R] <mode> <path>。 将<path>指定的文件的权限更改为<mode>。这个命令只适用于超级用户和文件所有者。hadop fs tail [-f] <path>。将<path>指定的文件最后1KB的内容输出到标准输出( stdout)上,-f选项用于持续检测新添加到文件中的内容。hadop fs stat [format] <patb>。以指定的格式返回<path>指定的文件的相关信息。当不指定format的时候,返回文件<path>的创建日期。hadoop fs -touchz <path>。创建一个<path>指定的空文件。hadoop fs mkdir [-p] <paths>。 创建<paths>指定的一个或多个文件夹,-p选项用于递归创建子文件夹。hadoop fs -copyFromLocal <localsrc> <dst>。将本地源文件<localsrc>复制到路径<dst>指定的文件或文件夹中。hadoop copyToLocal [-ignorecrc] [-crc] <target> <localdst>。 将目标文件<target>复制到本地文件做或文件夹<localdst>中,可用-ignorecrc选项复制CRC校验失败的文件,使用-crc选项复制文件以及CRC信息。hadoop fs -cp <src> <dst>。将文件从源路径<src>复制到目标路径<dst>。hadoop fs -du <path>。显示<path>指定的文件或文件夹中所有文件的大小。hadoop fs -expunge。清空回收站,请参考HDFS官方文档以获取更多关于回收站特性的信息。hadoop fs get [-ignorecrc] [-crc] <src> <localdst>。复制<src>指定的文件到本地文件系统<localdst>指定的文件或文件夹,可用-ignorecrc选项复制CRC校验失败的文件,使用-crc选项复制文件以及CRC信息。hadoop fs -getmerge [-nl] <src> <localdst>。对<src>指定的源目录中的所有文件进行合并,写入<localdst>指定的本地文件。-nl 是可选的,用于指定在每个文件结尾添加一个换行符。hadoop fs -put <localsrc> <dst>。从本地文件系统中复制<localsrc>指定的单个或多个源文件到<dst>指定的目标文件系统中,也支持从标准输人( stdin )中读取输人并写人目标文件系统。hadoop fs -moveFromLocal <localsrc> <dst>。 与put命令功能相同,但是文件上传结束后会从本地文件系统中删除<locasrc>指定的文件。hadoop fs -mv <src> <dest>。 将文件从源路径<src>移动到目标路径<dest>。hadoop fs -rm <path>。 删除<path>指定的文件,只删除非空目录和文件。hadoop fs -rm -r <path>。删除<path>指定的文件夹及其下的所有文件,-r选项表示递归删除子目录。hadop fs setrep [-R] <path>,改变<pah>指定的文件的副本系数,-R选项用于递归改变目录下所有文件的副本系数。hadoop fs -test -[ezd] <path>。 检查<path>指定的文件或文件夹的相关信息。不同选项的作用如下。

①-e检查文件是否存在,如果存在则返回0,否则返回1。

②-z检查文件是否是0字节,如果是则返回0,否则返回1。

③-d如果路径是个目录,则返回1,否则返回0。

hadoop fs -text ?<path>。将<path>指定的文件输出为文本格式,文件的格式也允许是zip和TextRecordlnputStream等。


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #分布式文件系统hdfs #file