HDFS入门和应用开发
文档
企业存储系统
硬盘
- SATA硬盘
- SATA SSD固态硬盘
- RAID磁盘阵列
文件系统
- 计算机的文件系统是一种存储和组织计算机数据的方法,它使得对其访问和查找变得容易
- 文件系统使用文件和树形目录的抽象逻辑概念代替了硬盘和光盘等物理设备使用数据块的概念,用户使用文件系统来保存数据不必关心数据实际保存在硬盘(或者光盘)的地址为多少的数据块上,只需要记住这个文件的所属目录和文件名。
- 在写入新数据之前,用户不必关心硬盘上的那个块地址没有被使用,硬盘上的存储空间管理(分配和释放)功能由文件系统自动完成,用户只需要记住数据被写入到了哪个文件中
- 文件系统通常使用硬盘和光盘这样的存储设备,并维护文件在设备中的物理位置。但是,实际上文件系统也可能仅仅是一种访问资料的界面而已,实际的数据是通过网络协议(如NFS、SMB、9P等)提供的或者内存上,甚至可能根本没有对应的文件(如proc文件系统)。
- 严格地说,文件系统是一套实现了数据的存储、分级组织、访问和获取等操作的抽象数据类型(Abstract data type)。
文件名
元数据
- 其它文件保存信息常常伴随着文件自身保存在文件系统中。
- 文件长度可能是分配给这个文件的区块数,也可能是这个文件实际的字节数。文件最后修改时间也许记录在文件的时间戳中。有的文件系统还保存文件的创建时间,最后访问时间及属性修改时间。(不过大多数早期的文件系统不记录文件的时间信息)其它信息还包括文件设备类型(如:区块数,字符集,套接口,子目录等等),文件所有者的ID,组ID,还有访问权限(如:只读,可执行等等)。
文件系统分类
磁盘文件系统
光盘
网络文件系统
网络文件系统(NFS,Network File System)是一种将远程主机上的分区(目录)经网络挂载到本地系统的一种机制。
如何实现分布式存储?
海量数据的存储问题
传统存储方式
传统做法是在服务器上部署文件服务比如FTP。但是随着数据变多,会遇到存储瓶颈。此时,本能的操作反应是:内存不够加内存,磁盘不够加磁盘—单机纵向扩展。但是单机能够扩展的内存磁盘是有上限的,不能无限制下去。
分布式存储方式
纵向扩展有上限,自然想到横向扩展。所谓横向指的是采用多台机器存储,一台不够就多台一起存储,不够就加机器。
理论上,可以横向无限制下去。因此海量数据如何存储的下的问题解决方式就是采用多台机器存储—即分布式存储。
数据查询便捷问题
当文件被分布式存储在多台机器之后,后续获取文件的时候如何能快速找到文件位于哪台机器上呢。一台一台查询过来也不靠谱。因此可以借助于元数据记录来解决这个问题。把文件和其存储的机器的位置信息记录下来,类似于图书馆查阅图书系统,这样就可以快速定位文件存储在哪一台机器上了。
大文件传输效率慢问题
当单个文件过大的时候,如何提高传输效率?通常的做法是分块存储:把大文件拆分成若干个小块(block 简写blk),分别存储在不同机器上,并行操作提高效率。
- 此外分块存储还可以解决数据存储负载均衡问题。此时元数据记录信息也应该更加详细:文件分了几块,分别位于哪些机器上。
数据丢失问题
如何保证数据存储的安全性。如果某台机器故障,数据块丢失,对于文件来说整体就是不完整的。冗余存储是个不错的选择。采用副本机制。副本越多,数据越安全,当然冗余也会越多。通过“不要把鸡蛋放在一个篮子里”的思想,可以把数据丢失的风险分散到各个机器上。
用户查询视觉统一问题
随着存储的进行,数据文件越来越多,与之对应元数据信息也越来越多,如何让用户视觉层面感觉不到元数据的凌乱,同时也与传统的文件系统操作体验保持一致?传统的文件系统拥有所谓的目录树结构,带有层次感的namespace(命名空间),因此可以把分布式文件系统的元数据记录这一块也抽象成统一的目录树结构。
分布式文件系统
- 通常来说一个分布式文件系统需要具备:分布式特性、分块存储、副本机制、元数据记录、抽象目录树、统一namespace命名空间。
分布式文件HDFS
简介
- HDFS(Hadoop Distributed File System)是 Apache Hadoop 项目的一个子项目,它的设计初衷是为了能够支持高吞吐和超大文件读写操作
- HDFS是一种能够在普通硬件上运行的分布式文件系统,它是高度容错的,适应于具有大数据集的应用程序,它非常适于存储大型数据 (比如 TB 和 PB)
- HDFS使用多台计算机存储文件, 并且提供统一的访问接口, 像是访问一个普通文件系统一样使用分布式文件系统
HDFS应用场景
适合的应用场景
- 存储非常大的文件:这里非常大指的是几百M、G、或者TB级别,需要高吞吐量,对延时没有要求。
- 基于流的数据访问方式: 即一次写入、多次读取,数据集经常从数据源生成或者拷贝一次,然后在其上做很多分析工作 ,且不支持文件的随机修改。
- 正因为如此,HDFS适合用来做大数据分析的底层存储服务,并不适合用来做网盘等应用,因为,修改不方便,延迟大,网络开销大,成本太高。
- 运行于商业硬件上: Hadoop不需要特别贵的机器,可运行于普通廉价机器,可以处节约成本
- 需要高容错性
- 为数据存储提供所需的扩展能力
不适合的应用场景
- 低延时的数据访问对延时要求在毫秒级别的应用,不适合采用HDFS。HDFS是为高吞吐数据传输设计的,因此可能牺牲延时
- 大量小文件的元数据保存在NameNode的内存中, 整个文件系统的文件数量会受限于NameNode的内存大小。 经验而言,一个文件/目录/文件块一般占有150字节的元数据内存空间。如果有100万个文件,每个文件占用1个文件块,则需要大约300M的内存。因此十亿级别的文件数量在现有商用机器上难以支持。
- 多方读写,需要任意的文件修改 HDFS采用追加(append-only)的方式写入数据。不支持文件任意offset的修改,HDFS适合用来做大数据分析的底层存储服务,并不适合用来做.网盘等应用,因为,修改不方便,延迟大,网络开销大,成本太高。
【!】HDFS重要特性
主从架构
- HDFS采用master/slave架构。一般一个HDFS集群是有一个Namenode和一定数目的Datanode组成。Namenode是HDFS主节点,Datanode是HDFS从节点,两种角色各司其职,共同协调完成分布式的文件存储服务。
分块机制
- HDFS中的文件在物理上是分块存储(block)的,块的大小可以通过配置参数来规定,参数位于hdfs-default.xml中:dfs.blocksize。默认大小是128M(134217728)。
副本机制
- 为了容错,文件的所有block都会有副本。每个文件的block大小(dfs.blocksize)和副本系数(dfs.replication)都是可配置的。
- 应用程序可以指定某个文件的副本数目。副本系数可以在文件创建的时候指定,也可以在之后通过命令改变。
- 默认dfs.replication的值是3,也就是会额外再复制2份,连同本身总共3份副本。
NameSpace
- HDFS支持传统的层次型文件组织结构。用户可以创建目录,然后将文件保存在这些目录里。文件系统名字空间的层次结构和大多数现有的文件系统类似:用户可以创建、删除、移动或重命名文件。
- Namenode负责维护文件系统的namespace名称空间,任何对文件系统名称空间或属性的修改都将被Namenode记录下来。
- HDFS会给客户端提供一个统一的抽象目录树,客户端通过路径来访问文件,形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data。
元数据管理
在HDFS中,Namenode管理的元数据具有两种类型:
- 文件自身属性信息:文件名称、权限,修改时间,文件大小,复制因子,数据块大小。
- 文件块位置映射信息:记录文件块和DataNode之间的映射信息,即哪个块位于哪个节点上。
数据块存储
文件的各个block的具体存储管理由DataNode节点承担。每一个block都可以在多个DataNode上存储。
HDFS的Shell命令
HDFS是存取数据的分布式文件系统,那么对HDFS的操作,就是文件系统的基本操作,比如文件的创建、修改、删除、修改权限等,文件夹的创建、删除、重命名等。对HDFS的操作命令类似于Linux的shell对文件的操作,如ls、mkdir、rm等。
#Hadoop提供了文件系统的shell命令行客户端
hadoop fs <args>
hadoop fs -ls hdfs://namenode:port/parent/child
hadoop fs -ls /parent/child #core-site.xml中的fs.defaultFS中有配置
hadoop fs -ls file:///root/ #本地文件系统
hdfs dfs <args>
选项名称 | 使用格式 | 含义 |
---|---|---|
-ls | -ls <路径> | 查看指定路径的当前目录结构 |
-lsr | -lsr <路径> | 递归查看指定路径的目录结构 |
-du | -du <路径> | 统计目录下个文件大小 |
-dus | -dus <路径> | 汇总统计目录下文件(夹)大小 |
-count | -count [-q] <路径> | 统计文件(夹)数量 |
-mv | -mv <源路径> <目的路径> | 移动 |
-cp | -cp <源路径> <目的路径> | 复制 |
-rm | -rm [-skipTrash] <路径> | 删除文件/空白文件夹 |
-rmr | -rmr [-skipTrash] <路径> | 递归删除 |
-put | -put <多个linux上的文件> <hdfs路径> | 上传文件 |
-copyFromLocal | -copyFromLocal <多个linux上的文件> <hdfs路径> | 从本地复制 |
-moveFromLocal | -moveFromLocal <多个linux上的文件> <hdfs路径> | 从本地移动 |
-getmerge | -getmerge <源路径> <linux路径> | 合并到本地 |
-cat | -cat <hdfs路径> | 查看文件内容 |
-text | -text <hdfs路径> | 查看文件内容 |
-copyToLocal | -copyToLocal [-ignoreCrc] [-crc] [hdfs源路径] [linux目的路径] | 从本地复制 |
-moveToLocal | -moveToLocal [-crc] <hdfs源路径> <linux目的路径> | 从本地移动 |
-mkdir | -mkdir <hdfs路径> | 创建空白文件夹 |
-touchz | -touchz <文件路径> | 创建空白文件 |
-stat | -stat [format] <路径> | 显示文件统计信息 |
-tail | -tail [-f] <文件> | 查看文件尾部信息 |
-chmod | -chmod [-R] <权限模式> [路径] | 修改权限 |
-chown | -chown [-R] [属主][:[属组]] 路径 | 修改属主 |
-chgrp | -chgrp [-R] 属组名称 路径 | 修改属组 |
-help | -help [命令选项] | 帮助 |
HDFS的安全模式
安全模式是hadoop的一种保护机制,用于保证集群中的数据块的安全性。当集群启动的时候,会首先进入安全模式。当系统处于安全模式时会检查数据块的完整性。
- 在NameNode启动过程中,等待DataNodes汇报可用的block信息。在此期间,NameNode保持在安全模式。随着DataNode的block汇报持续进行,当整个系统达到安全标准时,HDFS自动离开安全模式。在NameNode Web主页上会显示安全模式是打开还是关闭。
- 如果HDFS处于安全模式下,不允许HDFS客户端进行任何修改文件的操作,包括上传文件,删除文件,重命名,创建文件夹,修改副本数等操作。
- 假设我们设置的副本数(即参数dfs.replication)是3,那么在datanode上就应该有3个副本存在,假设只存在2个副本,那么比例就是2/3=0.666。hdfs默认的副本率0.999。我们的副本率0.666明显小于0.999,因此系统会自动的复制副本到其他dataNode,使得副本率不小于0.999。如果系统中有5个副本,超过我们设定的3个副本,那么系统也会删除多于的2个副本。
- 在安全模式状态下,文件系统只接受读数据请求,而不接受删除、修改等变更请求。在当整个系统达到安全标准时,HDFS自动离开安全模式。
hdfs dfsadmin -safemode get #查看安全模式状态
hdfs dfsadmin -safemode enter #进入安全模式
hdfs dfsadmin -safemode leave #离开安全模式
【面试】HDFS的数据读写流程
因为namenode维护管理了文件系统的元数据信息,这就造成了不管是读还是写数据都是基于NameNode开始的,也就是说NameNode成为了HDFS访问的唯一入口。入口地址是:http://nn_host:8020。
写数据流程
Pipeline管道、ACK应答响应
- Pipeline,中文翻译为管道。这是HDFS在上传文件写数据过程中采用的一种数据传输方式。客户端将数据块写入第一个数据节点,第一个数据节点保存数据之后再将块复制到第二个数据节点,后者保存后将其复制到第三个数据节点。通俗描述pipeline的过程就是:Client>A>B>C。
为什么datanode之间采用pipeline线性传输,而不是一次给三个datanode拓扑式传输呢?因为数据以管道的方式,顺序的沿着一个方向传输,这样能够充分利用每个机器的带宽,避免网络瓶颈和高延迟时的连接,最小化推送所有数据的延时。在线性推送模式下,每台机器所有的出口宽带都用于以最快的速度传输数据,而不是在多个接受者之间分配宽带。
- ACK (Acknowledge character)即是确认字符,在数据通信中,接收方发给发送方的一种传输类控制字符。表示发来的数据已确认接收无误。在pipeline管道传输数据的过程中,传输的反方向会进行ACK校验,确保数据传输安全。
默认3副本存储策略
- 默认副本存储策略是由BlockPlacementPolicyDefault指定。
第一块副本:优先客户端本地,否则随机 第二块副本:不同于第一块副本的不同机架。 第三块副本:第二块副本相同机架不同机器。
读数据流程
HDFS的机架感知
第一个BLOCK副本会存储在离客户端最近的一台主机上,如果客户端就是集群中的主机,则直接存在客户端所在主机,如果Client不在集群范围内或者不在同一个子网,则会在集群中随机选一个机架,在该机架中随机选一个健康(心跳正常,硬盘容量正常)的主机,将这个BLOCK存入 第二个BLOCK副本会存入另外一个机架(随机选择),会在该机架上随机选一台健康的主机,将数据存入 第三个BLOCK副本会在第二个BLOCK副本的机架上随机选择另外一台健康主机,将BLOCK数据存入
HDFS的元数据辅助管理
元数据
元数据(Metadata),又称中介数据,为描述数据的数据(data about data),主要是描述数据属性(property)的信息,用来支持如指示存储位置、历史数据、资源查找、文件记录等功能。
- 在HDFS中,元数据主要指的是文件相关的元数据,由NameNode管理维护。从广义的角度来说,因为NameNode还需要管理众多DataNode节点,因此DataNode的位置和健康状态信息也属于元数据。
元数据管理概述
在HDFS中,文件相关元数据具有两种类型:
- 文件自身属性信息
- 文件块位置映射信息
- 按存储形式分为内存元数据和元数据文件两种,分别存在内存和磁盘上。
内存元数据
为了保证用户操作元数据交互高效,延迟低,NameNode把所有的元数据都存储在内存中,我们叫做内存元数据。内存中的元数据是最完整的,包括文件自身属性信息、文件块位置映射信息。 但是内存的致命问题是,断点数据丢失,数据不会持久化。因此NameNode又辅佐了元数据文件来保证元数据的安全完整。
磁盘元数据文件
fsimage内存镜像文件
- 是内存元数据的一个持久化的检查点。但是fsimage中仅包含Hadoop文件系统中文件自身属性相关的元数据信息,但不包含文件块位置的信息。文件块位置信息只存储在内存中,时由datanode启动加入集群的时候,向namenode进行数据块的汇报得到的,并且后续间断指定时间进行数据块报告。
- 持久化的动作是一种数据从内存到磁盘的IO过程。会对namenode正常服务造成一定的影响,不能频繁的进行持久化。
加载元数据顺序
- fsimage和edits文件都是经过序列化的,在NameNode启动的时候,它会将fsimage文件中的内容加载到内存中,之后再执行edits文件中的各项操作,使得内存中的元数据和实际的同步,存在内存中的元数据支持客户端的读操作,也是最完整的元数据。
- 当客户端对HDFS中的文件进行新增或者修改操作,操作记录首先被记入edits日志文件中,当客户端操作成功后,相应的元数据会更新到内存元数据中。因为fsimage文件一般都很大(GB级别的很常见),如果所有的更新操作都往fsimage文件中添加,这样会导致系统运行的十分缓慢。
- HDFS这种设计实现着手于:一是内存中数据更新、查询快,极大缩短了操作响应时间;二是内存中元数据丢失风险颇高(断电等),因此辅佐元数据镜像文件(fsimage)+编辑日志文件(edits)的备份机制进行确保元数据的安全。
元数据管理相关目录文件
元数据储存目录
- 在Hadoop的HDFS首次部署好配置文件之后,并不能马上启动使用,而是先要对文件系统进行格式化操作:hdfs namenode -format
- 在这里要注意两个概念,一个是format之前,HDFS在物理上还不存在;二就是此处的format并不是指传统意义上的本地磁盘格式化,而是一些清除与准备工作。其中就会创建元数据本地存储目录和一些初始化的元数据相关文件。
- namenode元数据存储目录由参数:dfs.namenode.name.dir指定,格式化完成之后,将会在$dfs.namenode.name.dir/current目录下创建如下的文件
image.png - 其中的dfs.namenode.name.dir是在hdfs-site.xml文件中配置的,默认值如下
image.png
- dfs.namenode.name.dir属性可以配置多个目录,各个目录存储的文件结构和内容都完全一样,相当于备份,这样做的好处是当其中一个目录损坏了,也不会影响到hadoop的元数据,特别是当其中一个目录是NFS(网络文件系统Network File System,NFS)之上,即使你这台机器损坏了,元数据也得到保存。
Edits log编辑日志
- 为了避免两次持久化之间数据丢失的问题,又设计了Edits log编辑日志文件。文件中记录的是HDFS所有更改操作(文件创建,删除或修改)的日志,文件系统客户端执行的更改操作首先会被记录到edits文件中。
元数据相关文件
fsimage相关
元数据镜像文件。每个fsimage文件还有一个对应的.md5文件,其中包含MD5校验和,HDFS使用该文件来防止磁盘损坏文件异常。
Edits log相关
已完成且不可修改的编辑日志。这些文件中的每个文件都包含文件名定义的范围内的所有编辑日志事务。在HA高可用性部署中,主备namenode之间可以通过edits log进行数据同步。
Fsimage、Edits log查看
- oiv是offline image viewer的缩写,用于将fsimage文件的内容转储到指定文件中以便于阅读,该工具还提供了只读的WebHDFS API以允许离线分析和检查hadoop集群的命名空间。
hdfs oiv -i fsimage_0000000000000000050 -p XML -o fsimage.xml
- oev是offline edits viewer(离线edits查看器)的缩写,该工具不需要hadoop集群处于运行状态。
hdfs oev -i edits_0000000000000000011-0000000000000000025 -o edits.xml
SecondaryNameNode
SNN职责概述
当HDFS集群运行一段事件后,就会出现下面一些问题: Ø edits logs会变的很大,fsimage将会变得很旧; Ø namenode重启会花费很长时间,因为有很多改动要合并到fsimage文件上; Ø 如果频繁进行fsimage持久化,又会影响NameNode正常服务,毕竟IO操作是一种内存到磁盘的耗精力操作
- 为了克服这个问题,需要一个易于管理的机制来帮助我们减小edit logs文件的大小和得到一个最新的fsimage文件,这样也会减小在NameNode上的压力。
- SecondaryNameNode就是来帮助解决上述问题的,它的职责是合并NameNode的edit logs到fsimage文件中。
SNN CheckPoint机制
Checkpoint核心是把fsimage与edits log合并以生成新的fsimage的过程。此过程有两个好处:fsimage版本不断更新不会太旧、edits log文件不会太大。
流程
- 当触发checkpoint操作条件时,SNN发生请求给NN滚动edits log。然后NN会生成一个新的编辑日志文件:edits new,便于记录后续操作记录。
- 同时SNN会将edits文件和fsimage复制到本地(使用HTTP GET方式)。
- SNN首先将fsimage载入到内存,然后一条一条地执行edits文件中的操作,使得内存中的fsimage不断更新,这个过程就是edits和fsimage文件合并。合并结束,SNN将内存中的数据dump生成一个新的fsimage文件。
- SNN将新生成的Fsimage new文件复制到NN节点。
- 至此刚好是一个轮回,等待下一次checkpoint触发SecondaryNameNode进行工作,一直这样循环操作。
触发机制
Checkpoint触发条件受两个参数控制,可以通过core-site.xml进行配置
dfs.namenode.checkpoint.period=3600 //两次连续的checkpoint之间的时间间隔。默认1小时
dfs.namenode.checkpoint.txns=1000000 //最大没有执行checkpoint事务的数量,满足将强制执行紧急checkpoint,即使尚未达到检查点周期。默认100万事务数量。
从上面的描述我们可以看出,SecondaryNamenode根本就不是Namenode的一个热备,只是将fsimage和edits合并。
NameNode元数据恢复
NameNode存储多目录
- namenode元数据存储目录由参数:dfs.namenode.name.dir指定。
- dfs.namenode.name.dir属性可以配置多个目录,各个目录存储的文件结构和内容都完全一样,相当于备份,这样做的好处是当其中一个目录损坏了,也不会影响到hadoop的元数据,特别是当其中一个目录是NFS(网络文件系统Network File System,NFS)之上,即使你这台机器损坏了,元数据也得到保存。
从SecondaryNameNode恢复
- SecondaryNameNode在checkpoint的时候会将fsimage和edits log下载到自己的本机上本地存储目录下。并且在checkpoint之后也不会进行删除。
- 如果NameNode中的fsimage真的出问题了,还是可以用SecondaryNamenode中的fsimage替换一下NameNode上的fsimage,虽然已经不是最新的fsimage,但是我们可以将损失减小到最少!
Java操作HDFS
See Doc.
集群之间的数据复制
集群内部文件拷贝scp
本地复制到远程
- 方式一:指定用户名,命令执行后需要再输入密码;
scp -r local_folder remote_username@remote_ip:remote_folder
- 方式二:没有指定用户名,命令执行后需要再输入用户名和密码;
scp -r local_folder remote_ip:remote_folder
- 若已实现ssh免密连接则不需要密码
远程复制到本地
#复制文件-将192.168.88.162的/root目录下的test.txt拷贝到当前主机的/root/目录下,文件名不变
scp root@192.168.88.162:/root/test.txt /root/test.txt
HDFS分布式拷贝工具:DistCp
DistCp
DistCp是Apache Hadoop中的一种流行工具,在hadoop-tools工程下,作为独立子工程存在。其定位就是用于数据迁移的,定期在集群之间和集群内部备份数据。(在备份过程中,每次运行DistCp都称为一个备份周期。)尽管性能相对较慢,但它的普及程度已经越来越高。
hadoop distcp hdfs://node1:8020/jdk-8u241-linux-x64.tar.gz hdfs://cluster2:8020/
Trash垃圾回收
背景
HDFS本身也是一个文件系统,那么就会涉及到文件数据的删除操作。默认情况下,HDFS中是没有回收站垃圾桶概念的,删除操作的数据将会被直接删除,没有后悔药。
功能概述
- Trash机制,叫做回收站或者垃圾桶。Trash就像Windows操作系统中的回收站一样。它的目的是防止你无意中删除某些东西。默认情况下是不开启的。
- 启用Trash功能后,从HDFS中删除某些内容时,文件或目录不会立即被清除,它们将被移动到回收站Current目录中(/user/${username}/.Trash/current)。
- .Trash中的文件在用户可配置的时间延迟后被永久删除。也可以简单地将回收站里的文件移动到.Trash目录之外的位置来恢复回收站中的文件和目录。
Trash CheckPoint
- 检查点仅仅是用户回收站下的一个目录,用于存储在创建检查点之前删除的所有文件或目录。
- 最近删除的文件被移动到回收站Current目录,并且在可配置的时间间隔内,HDFS会为在Current回收站目录下的文件创建检查点/user/${username}/.Trash/<日期>,并在过期时删除旧的检查点。
功能开启
- 关闭集群
- 修改core-site.xml文件
- 在node1节点上修改core-site.xml文件,添加下面两个属性
<property>
<name>fs.trash.interval</name>
<value>1440</value>
</property>
<property>
<name>fs.trash.checkpoint.interval</name>
<value>0</value>
</property>
- fs.trash.interval:分钟数,当超过这个分钟数后检查点会被删除。如果为零,Trash回收站功能将被禁用。
- fs.trash.checkpoint.interval:检查点创建的时间间隔(单位为分钟)。其值应该小于或等于fs.trash.interval。如果为零,则将该值设置为fs.trash.interval的值。每次运行检查点时,它都会从当前版本中创建一个新的检查点,并删除在数分钟之前创建的检查点。
- 同步集群配置文件
- 启动HDFS集群
功能使用
删除文件到Trash
- 开启Trash功能后,正常执行删除操作,文件实际并不会被直接删除,而是被移动到了垃圾回收站。
image.png image.png
删除文件跳过Trash
- 有的时候,我们希望直接把文件删除,不需要再经过Trash回收站了,可以在执行删除操作的时候添加一个参数:-skipTrash.
image.png
从Trash中恢复文件
- 回收站里面的文件,在到期被自动删除之前,都可以通过命令恢复出来。使用mv、cp命令把数据文件从Trash目录下复制移动出来就可以了。
image.png
清空Trash
- 除了fs.trash.interval参数控制到期自动删除之外,用户还可以通过命令手动清空回收站,释放HDFS磁盘存储空间。
- 首先想到的是删除整个回收站目录,将会清空回收站,这是一个选择。此外。HDFS提供了一个命令行工具来完成这个工作:
- hadoop fs -expunge
- 该命令立即从文件系统中删除过期的检查点。
- hadoop fs -expunge
Archive档案的使用
HDFS不擅长存储小文件,因为每个文件最少一个block,每个block的元数据都会在NameNode占用内存。如果存在大量的小文件,会吃掉NameNode节点的大量内存。
Hadoop Archive可以有效的处理以上问题,它可以把多个文件归档成为一个文件,归档之后还可以透明访问每一个文件。
如何创建Archive
#hadoop archive -archiveName name -p <parent> <src>* <dest>
#存档一个目录/config下的所有文件
hadoop archive -archiveName test.har -p /config /outputdir
如何查看Archive
#查看下创建好的har文件
hadoop fs -ls /outputdir/test.har
har文件包括两个索引文件,多个part文件以及一个标识成功与否的文件。
- part文件是多个原文件的集合,根据index文件去找到原文件。
#查看part里所有的小文件列表
hadoop fs -cat /outputdir/test.har/part-0
- archive作为文件系统层暴露给外界。所以所有的fs shell命令都能在archive上运行,但是要使用不同的URI。
- Hadoop Archives的URI是:har://scheme-hostname:port/archivepath/fileinarchive
- scheme-hostname格式为hdfs-域名:端口,如果没有提供scheme-hostname,它会使用默认的文件系统。
- har:///archivepath/fileinarchive
- scheme-hostname格式为hdfs-域名:端口,如果没有提供scheme-hostname,它会使用默认的文件系统。
- 若使用har uri去访问的话,索引和标识文件会隐藏起来。
#查看har归档文件中小文件的内容
hadoop fs -cat har:///outputdir/test.har/core-site.xml
如何解压Archive
hadoop fs -mkdir /config2
hadoop fs -cp har:///outputdir/test.har/* /config2
Archive注意事项
- Hadoop archives是特殊的档案格式。一个Hadoop archive对应一个文件系统目录。Hadoop archive的扩展名是*.har
- 创建archives本质是运行一个Map/Reduce任务,所以应该在Hadoop集群上运行创建档案的命令,要提前启动Yarn集群
- 创建archive文件要消耗和原文件一样多的硬盘空间
- archive文件不支持压缩,尽管archive文件看起来像已经被压缩过
- archive文件一旦创建就无法改变,要修改的话,需要创建新的archive文件。事实上,一般不会再对存档后的文件进行修改,因为它们是定期存档的,比如每周或每日
- 当创建archive时,源文件不会被更改或删除
HDFS权限管理
概述
作为分布式文件系统,HDFS也集成了一套兼容POSIX的权限管理系统。客户端在进行每次文件操时,系统会从用户身份认证和数据访问授权两个环节进行验证:客户端的操作请求会首先通过本地的用户身份验证机制来获得“凭证”(类似于身份证书),然后系统根据此“凭证”分辨出合法的用户名,再据此查看该用户所访问的数据是否已经授权。一旦这个流程中的某个环节出现异常,客户端的操作请求便会失败
UGO权限管理
简介
HDFS的文件权限与Linux/Unix系统的UGO模型类型类似,可以简单描述为:每个文件和目录都与一个所有者和一个组相关联。该文件或目录对作为**所有者(USER)的用户,作为该组成员的其他用户(GROUP)以及对所有其他用户(OTHER)**具有单独的权限。
- 在HDFS中,对于文件,需要r权限才能读取文件,而w权限才能写入或追加到文件。没有x可执行文件的概念。
- 对于目录,需要r权限才能列出目录的内容,需要w权限才能创建或删除文件或目录,并且需要x权限才能访问目录的子级。
UGO权限相关命令
#变更目录或文件的权限位
hadoop fs -chmod 750 /user/dir
#变更目录或文件的属主或用户组
hadoop fs -chown :portal /user/dir
#变更用户组
hadoop fs -chgrp group1 /user/dir
- 需要注意的是,使用这个命令的用户必须是超级用户,或者是该文件的属主,同时也是该用户组的成员
Web页面修改UGO权限
Hadoop3.0之后,支持在HDFS的Web页面上操作修改。
粘滞位(Sticky bit)用法在目录上设置,如此以来,只有目录内文件的所有者或者root才可以删除或移动该文件。如果不为目录设置粘滞位,任何具有该目录写和执行权限的用户都可以删除和移动其中的文件。实际应用中,粘滞位一般用于/tmp目录,以防止普通用户删除或移动其他用户的文件。
HDFS动态节点管理
背景
已有HDFS集群容量已经不能满足存储数据的需求,需要在原有集群基础上动态添加新的DataNode节点。就是俗称的动态扩容。 旧的服务器需要进行退役更换,暂停服务,需要在当下的集群中停止某些机器上HDFS的服务,俗称动态缩容。
动态扩容、节点上线
NameNode节点配置
- 修改NameNode节点的workers配置文件,增加新节点主机名,以便后续一键启停。
新机器配置
- 从NameNode节点复制Hadoop安装包到新节点,注意不包括hadoop.tmp.dir指定的数据存储目录。
- 新机器上配置Hadoop环境变量
export HADOOP_HOME=/opt/export/server/hadoop-3.1.4
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
source /etc/profile
手动启动DataNode节点
- 手动启动需要动态上线的节点
hdfs --daemon start datanode
DataNode负载均衡服务
新加入的节点,没有数据块的存储,使得集群整体来看负载不均衡。因此最后还需要对hdfs负载设置均衡
#设置数据传输带宽
hdfs dfsadmin -setBalancerBandwidth 104857600
#启动Balancer,等待集群自均衡完成即可
hdfs balancer -threshold 5
- 解释: 5表示每台主机的磁盘空间占有率不能超过5%,否则会自动进行负载均衡(进行Block动态移动来保持存储均衡)
动态缩容、节点下线
添加退役节点
在namenode机器的hdfs-site.xml配置文件中需要提前配置dfs.hosts.exclude属性,该属性指向的文件就是所谓的黑名单列表,会被namenode排除在集群之外。如果文件内容为空,则意味着不禁止任何机器。
提前配置好的目的是让namenode启动的时候就能加载到该属性,只不过还没有指定任何机器。否则就需要重启namenode才能加载,因此这样的操作我们称之为具有前瞻性的操作。
<property>
<name>dfs.hosts.exclude</name>
<value>/opt/export/server/hadoop-3.1.4/etc/hadoop/excludes</value>
</property>
- 编辑dfs.hosts.exclude属性指向的excludes文件,添加需要退役的主机名称。
- 注意:如果副本数是3,服役的节点小于等于3,是不能退役成功的,需要修改副本数后才能退役。
刷新集群
- 在namenode所在的机器刷新节点:hdfs dfsadmin -refreshNodes
- 等待退役节点状态为decommissioned(所有块已经复制完成)
手动关闭DataNode进程
hdfs --daemon stop datanode
DataNode负载均衡服务
- 如果需要可以对已有的HDFS集群进行负载均衡服务。
- hdfs balancer -threshold 5
HDFS High Availability(HA)高可用
背景知识
单点故障、高可用
- 单点故障(英语:single point of failure,缩写SPOF)是指系统中某一点一旦失效,就会让整个系统无法运作,换句话说,单点故障即会整体故障。
- 高可用性(英语:high availability,缩写为 HA),IT术语,指系统无中断地执行其功能的能力,代表系统的可用性程度。是进行系统设计时的准则之一。高可用性系统意味着系统服务可以更长时间运行,通常通过提高系统的容错能力来实现。
高可用性或者高可靠度的系统不会希望有单点故障造成整体故障的情形。一般可以透过冗余的方式增加多个相同机能的部件,只要这些部件没有同时失效,系统(或至少部分系统)仍可运作,这会让可靠度提高。
高可用如何实现
主备集群
- 当下企业中成熟的做法就是给单点故障的位置设置备份,形成主备架构。通俗描述就是当主挂掉,备份顶上,短暂的中断之后继续提供服务。
- 常见的是一主一备架构,当然也可以一主多备。备份越多,容错能力越强,与此同时,冗余也越大,浪费资源。
Active、StandBy
- Active:主角色。活跃的角色,代表正在对外提供服务的角色服务。任意时间有且只有一个active对外提供服务。
- Standby:备份角色。需要和主角色保持数据、状态同步,并且时刻准备切换成主角色(当主角色挂掉或者出现故障时),对外提供服务,保持服务的可用性。
可用性评判标准
在系统的高可用性里有个衡量其可靠性的标准——X个9,这个X是代表数字3-5。X个9表示在系统1年时间的使用过程中,系统可以正常使用时间与总时间(1年)之比。
高可用系统设计的核心问题
脑裂问题
- 在HA集群中,脑裂指的是当联系主备节点的"心跳线"断开时(即两个节点断开联系时),本来为一个整体、动作协调的HA系统,就分裂成为两个独立的节点。
- 由于相互失去了联系,主备节点之间像"裂脑人"一样,使得整个集群处于混乱状态。
- 脑裂的严重后果:
- 集群无主:都认为对方是状态好的,自己是备份角色,后果是无服务
- 集群多主:都认为对方是故障的,自己是主角色。相互争抢共享资源,结果会导致系统混乱,数据损坏。此外对于客户端访问也是一头雾水,找谁呢?
- 避免脑裂问题的核心是:保持任意时刻系统有且只有一个主角色提供服务。
数据同步问题
主备切换保证服务持续可用性的前提是主备节点之间的状态、数据是一致的,或者说准一致的。如果说备用的节点和主节点之间的数据差距过大,即使完成了主备切换的动作,那也是没有意义的。
- 数据同步常见做法是:通过日志重演操作记录。主角色正常提供服务,发生的事务性操作通过日志记录,备用角色读取日志重演操作。
HDFS NameNode单点故障问题
Hadoop2.0之前,NameNode是HDFS集群中的单点故障。每个群集只有一个NameNode,如果该计算机或进程不可用,则整个群集在整个NameNode重新启动或在另一台计算机上启动之前将不可用。
- NameNode的单点故障从两个方面影响了HDFS群集的总可用性
- 如果发生意外事件(例如机器崩溃),则在重新启动NameNode之前,群集将不可用。
- 计划内的维护事件,例如NameNode计算机上的软件或硬件升级,将导致群集停机时间的延长。
- HDFS高可用性解决方案
- 在同一群集中运行两个(从3.0.0起,超过两个)冗余NameNode。这样可以在机器崩溃的情况下快速故障转移到新的NameNode,或者出于计划维护的目的由管理员发起的正常故障转移。
HDFS 高可用解决方案——QJM
QJM全称Quorum Journal Manager,由cloudera公司提出,是Hadoop官方推荐的HDFS HA解决方案之一
- QJM中,使用zookeeper中ZKFC来实现主备切换;使用Journal Node(JN)集群实现edits log的共享以达到数据同步的目的。
QJM——主备切换、脑裂问题解决
ZKFailoverController
Apache ZooKeeper是一款高可用分布式协调服务软件,用于维护少量的协调数据。 Zookeeper的下列特性功能参与了HDFS的HA解决方案中:
- 临时ZNode
- 如果一个znode节点是临时的,那么该znode的生命周期将和创建它的客户端的session绑定。客户端断开连接session结束,znode将会被自动删除。
- Path路径唯一性
- zookeeper中维持了一份类似目录树的数据结构。每个节点称之为Znode。Znode具有唯一性,不会重名。也可以理解为排他性。
- 监听机制
- 客户端可以针对znode上发生的事件设置监听,当事件发生触发条件,zk服务会把事件通知给设置监听的客户端。
ZKFailoverController(ZKFC)是一个新组件,它是一个ZooKeeper客户端。运行NameNode的每台计算机也都运行ZKFC,ZKFC的主要职责:
- 监视和管理NameNode健康状态
- ZKFC通过命令定期ping本地负责监视的NameNode节点
- 维持和Zookeeper集群联系
- 如果本地NameNode运行状况良好,并且ZKFC看到当前没有其他节点持有锁znode,它将自己尝试获取该锁。如果成功,则表明它“赢得了选举”,并负责运行故障转移以使其本地NameNode处于Active状态。如果已经有其他节点持有锁,zkfc选举失败,则会对该节点注册监听,等待下次继续选举。
Fencing隔离机制
- 故障转移过程也就是俗称的主备角色切换的过程,切换过程中最怕的就是脑裂的发送。因此需要Fencing机制来避免,将先前的Active节点隔离,然后将本地NameNode转换为Active状态。
Hadoop公共库中对外提供了两种fenching实现,分别是sshfence和shellfence(缺省实现),其中sshfence是指通过ssh登陆目标节点上,使用命令fuser将进程杀死(通过tcp端口号定位进程pid,该方法比jps命令更准确),shellfence是指执行一个用户事先定义的shell命令(脚本)完成隔离。
QJM——主备数据同步问题解决
- Journal Node(JN)集群是轻量级分布式系统,主要用于高速读写数据、存储数据。通常使用2N+1台JournalNode存储共享Edits Log(编辑日志)。
- 任何修改操作在 Active NN上执行时,JournalNode进程同时也会记录edits log到至少半数以上的JN中
- 这时 Standby NN 监测到JN 里面的同步log发生变化了会读取JN里面的edits log,然后重演操作记录同步到自己的目录镜像树里面。
- 当发生故障Active NN挂掉后,Standby NN 会在它成为Active NN 前,读取所有的JN里面的修改日志,这样就能高可靠的保证与挂掉的NN的目录镜像树一致,然后无缝的接替它的职责,维护来自客户端请求,从而达到一个高可用的目的。
HDFS HA环境搭建
HA集群规划
node1 | namenode | resourcemanager | zkfc | nodemanager | datanode | zookeeper | journal node |
---|---|---|---|---|---|---|---|
node2 | namenode | resourcemanager | zkfc | nodemanager | datanode | zookeeper | journal node |
node3 | |||||||
nodemanager | datanode | zookeeper | journal node |
HDFS Federation联邦机制
当前HDFS体系架构
简介
- 命名空间
HDFS体系结构中的命名空间层由文件,块和目录组成。该层支持与名称空间相关的文件系统操作,例如创建,删除,修改和列出文件和目录
- 块存储层
- 块管理: NameNode执行块管理。块管理通过处理注册和定期心跳来提供DataNode群集成员身份。它处理块报告并支持与块相关的操作,如创建,删除,修改或获取块位置。它还维护块的位置,副本位置。为未复制的块管理块复制,并在已复制的块中删除。
- 存储: DataNode通过在本地文件系统上存储块并提供读/写访问权限来管理存储空间。
局限性
当下的HDFS体系结构仅允许单个NameNode维护文件系统名称空间。注意HA体系中虽然说允许多个NameNode,但是他们所维护的是同一套文件系统名称空间。这种体系目前存在着一些弊端和局限性。
- DataNode磁盘存储空间不够增加节点,NameNode内存不够是否可以无限扩容。一种是DataNode横向扩展机器增加节点,一种是纵向扩展单机加内存。
- 由于名称空间和存储层的紧密耦合,NameNode的替代实现很困难。这限制了其他服务直接使用块存储。唯一的NameNode成了唯一入口。
- 文件系统的操作还限于NameNode一次处理的任务数。因此,群集的性能取决于NameNode吞吐量。
- 同样,由于使用单个名称空间,因此使用群集的占用者组织之间没有隔离。
HDFS Federation架构
简介
Federation中文意思为联邦,联盟,是NameNode之间的Federation,也就是集群中会有多个NameNode。多个NameNode的情况意味着有多个namespace。注意,这区别于HA模式下的多NameNode,HA中它们是拥有着同一个namespace。
Federation体系中多个namenode之间相互独立且不需要互相协调,各自分工,管理自己的区域。每个DataNode要向集群中所有的namenode注册,且周期性地向所有namenode发送心跳和块报告,并执行来自所有namenode的命令。 上图中,有多个NameNode,分别表示为NN1,NN2,.. NNn。NS1,NS2等是由它们各自的NameNode管理的多个名称空间。 每个名称空间都有其自己的块池(block pool)(NS1具有Pool1,NS2具有Pool2,依此类推)。每个DataNode存储集群中所有块池的块。 HDFS Federation体系结构中的块池是属于单个名称空间的块的集合。每个块池彼此独立地进行管理。在删除NameNode或名称空间时,DataNode中存在的相应块池也将被删除。在升级群集时,每个名称空间卷都作为一个单元进行升级。
好处
- 命名空间可伸缩性
- 使用Federation,可以水平扩展名称空间。这对大型群集或包含太多小文件的群集有利,因为向群集添加了更多的NameNode。
- 性能
- 由于文件系统操作不受单个NameNode吞吐量的限制,因此可以提高文件系统的性能。
- 隔离
- 由于有多个名称空间,它可以为使用群集的占用者组织提供隔离。