本节书摘来自华章计算机《深入理解大数据:大数据处理与编程实践》一书中的第3章,第3.4节,作者 主 编:黄宜华(南京大学)副主编:苗凯翔(英特尔公司),更多章节内容可以访问云栖社区“华章计算机”公众号查看。
3.4 HDFS文件系统操作命令
通过之前章节的学习,相信各位读者对HDFS已经有了一个基本的认识。在本小节里,我们来了解一下HDFS常用的的基本操作命令。
3.4.1 HDFS启动与关闭
HDFS和普通的硬盘上的文件系统不一样,是通过Java虚拟机运行在整个集群当中的,所以当Hadoop程序写好之后,需要启动HDFS文件系统,才能运行。
HDFS启动过程如下:
1)进入到NameNode对应节点的Hadoop安装目录下。
2)执行启动脚本:
bin/start-dfs.sh
这一脚本会启动NameNode,然后根据conf/slaves中的记录逐个启动DataNode,最后根据conf/masters中记录的Secondary NameNode地址启动SecondaryNameNode。
HDFS关闭过程如下:
运行以下关闭脚本:
bin/stop-dfs.sh
这一脚本的运行过程正好是bin/start-dfs.sh的逆过程,关闭Secondary NameNode,然后是每个DataNode,最后是NameNode自身。
3.4.2 HDFS文件操作命令格式与注意事项
HDFS文件系统提供了相当多的shell操作命令,大大方便了程序员和系统管理人员查看、修改HDFS上的文件。进一步,HDFS的操作命令和Unix/Linux的命令名称和格式相当一致,因而学习HDFS命令的成本也大为缩小。
HDFS的基本命令格式如下:
bin/hadoop dfs–cmd
这里cmd就是具体的命令,记住cmd前面的短线“–”千万不要忽略。
部分命令(如mkdir等)需要文件目录名作为参数,参数一般都是URI格式,args参数的基本格式是:
scheme:// authority/path
scheme指具体的文件系统,如果是本地文件,那么scheme就是file;如果是HDFS上的文件,那么scheme就是hdfs。authority就是机器的地址和对应的端口。当然,正如Linux文件有绝对路径和相对路径一样,这里的URI参数也可以做一定程度省略。当对应的设置为hdfs://namenode:namenodeport时,如果路径参数为/parent/child,那么它对应的实际文件为
hdfs:// namenode:namenodeport/parent/child
但是有一点要注意,HDFS没有所谓当前工作目录的概念。前面说过,HDFS所有文件元数据都是存在NameNode节点上的,具体文件的存放由NameNode掌控,某一个文件可能被分拆放到不同的机器上,也可能为了提高效率将路径不同的文件也放到同一台机器上。所以,为HDFS提供cd、pwd操作,都是不现实的。
3.4.3 HDFS文件操作命令
接下来,我们来了解一下HDFS的命令。再提醒一下,文件操作命令的基本格式是:
bin/hadoop dfs–cmd
1.?cat
格式:hadoop dfs-cat URI [URI …]
作用:将参数所指示的文件的内容输出到stdout。
示例:
hadoop dfs -cat hdfs:// nn1.example.com/file1 hdfs:// nn2.example.com/file2
hadoop dfs -cat file:/// file3 /user/hadoop/file4
返回值:成功结束返回0,出现错误返回-1。
2.?chgrp
格式:hadoop dfs -chgrp [-R] GROUP URI [URI …]
作用:改变文件所属的用户组。如果使用-R选项,则这一操作对整个目录结构递归执行。使用这一命令的用户必须是文件的所属用户,或者是超级用户。
3.?chmod
格式:hadoop dfs -chmod [-R] URI[URI …]
作用:改变文件的权限。如果使用-R选项,则这一操作对整个目录结构递归执行。使用这一命令的用户必须是文件的所属用户,或者是超级用户。
4.?chown
格式:hadoop dfs -chown [-R] OWNER] URI [URI… ]
作用:改变文件的所属用户。如果使用-R选项,则这一操作对整个目录结构递归执行。使用这一命令的用户必须是文件在命令变更之前的所属用户,或者是超级用户。
5.?copyFromLocal
格式:hadoop dfs -copyFromLocal URI
作用:与put命令类似,但是要限定源文件路径为本地文件系统。
6.?copyToLocal
格式:hadoop dfs -copyToLocal [-ignorecrc] [-crc] URI
作用:与get命令类似,但是要限定目标文件路径为本地文件系统。
7.?count
格式:hadoop dfs -count [-q]
作用:统计匹配对应路径下的目录数,文件数,字节数(文件大小)。
选项意义:
使用-count选项时,输出的列为:
DIR_COUNT, FILE_COUNT, CONTENT_SIZE,FILE_NAME
从左到右分别对应目录下已存在的目录数,文件数,文件大小,文件名
使用-count-q选项时,输出的列为:
QUOTA, REMAINING_QUOTA, SPACE_QUOTA, REMAINING_SPACE_QUOTA,
DIR_COUNT, FILE_COUNT, CONTENT_SIZE, FILE_NAME
从左到右的意义是:目录下最大允许文件+目录数(不存在上限,则为none),目录下可增加目录+文件数(不存在上限,则为inf),目录下最大允许空间(不存在上限,则为none),目录下可用最大空间(不存在上限,则为inf);后面的几个和-count选项一致,分别对应目录下已存在的目录数,文件数,文件大小,文件名。
示例:
hadoop dfs -count hdfs:// nn1.example.com/f?ile1 hdfs:// nn2.example.com/f?ile2
hadoop dfs -count -q hdfs:// nn1.example.com/f?ile1
返回值:成功结束返回0,出现错误返回-1。图3-8所示是一个count选项使用后的结果示例。
图3-8 count命令示例
8.?cp
格式:hadoop dfs -cp URI [URI …]
作用:将文件拷贝到目标路径中。如果为目录的话,可以将多个文件拷贝到该目录下。
示例:
hadoop dfs -cp /user/hadoop/f?ile1 /user/hadoop/f?ile2
hadoop dfs -cp /user/hadoop/f?ile1 /user/hadoop/f?ile2 /user/hadoop/dir
返回值:成功结束返回0,出现错误返回-1。
9.?du
格式:hadoop dfs -du [-s] [-h] URI [URI …]
作用:如果参数为目录,显示该目录下所有目录+文件的大小;如果参数为单个文件,则显示文件大小。
选项意义:
-s指输出所有文件大小的累加和,而不是每个文件的大小。
-h会将文件大小的数值用方便阅读的形式表示,比如用64.0M代替67108864。
示例:
hadoop dfs -du /user/hadoop/dir1 /user/hadoop/file1
hdfs:// nn.example.com/user/hadoop/dir1
返回值:成功结束返回0,出现错误返回-1。
10.?dus
格式:hadoop dfs -dus
作用:显示文件的大小。这个命令等价于hadoop dfs -du-s。
11.?expunge
格式:hadoop dfs -expunge
作用:清空回收站。如需更多有关回收站特性的信息,请参考其他资料和文献。
12.?get
格式:hadoop dfs -get [-ignorecrc] [-crc]
作用:将文件拷贝到本地文件系统。CRC校验失败的文件可通过-ignorecrc选项拷贝。文件和CRC校验和可以通过-crc选项拷贝。
示例:
hadoop dfs -get /user/hadoop/f?ile localf?ile
hadoop dfs -get hdfs:// nn.example.com/user/hadoop/f?ile localf?ile
返回值:成功结束返回0,出现错误返回-1。
13.?getmerge
格式:hadoop dfs -getmerge [addnl]
作用:命令参数为一个源文件目录和一个目的文件。将源文件目录下的所有文件排序后合并到目的文件中。添加addnl可以在每个文件后面插入新行。
14.?ls
格式:hadoop dfs -ls
作用:对于一个文件,该命令返回的文件状态以如下格式列出:
permissions number_of_replicas userid groupid f?ilesize
modif?ication_date modif?ication_time f?ilename
从左到右的意义分别是:文件权限,副本个数,用户ID,组ID,文件大小,最近一次修改日期,最近一次修改时间,文件名。
对于一个目录,该命令返回这一目录下的第一层子目录和文件,与Unix中ls命令的结果类似;结果以如下状态列出:
permissions userid groupid modif?ication_date modif?ication_time dirname
从左到右的意义分别是:文件权限,用户ID,组ID,最近一次修改日期,最近一次修改时间,文件名。
示例:
hadoop dfs -ls /user/hadoop/f?ile1
返回值:成功结束返回0,出现错误返回-1。图3-9所示是一个ls命令显示结果示例。
图3-9 HDFS启动与ls命令示例
15.?lsr
格式:hadoop dfs -lsr
作用:在整个目录下递归执行ls,与Unix中的ls-R类似。
16.?mkdir
格式:hadoop dfs -mkdir
作用:以中的URI作为参数,创建目录。该命令的行为与Unix中mkdir-p的行为十分相似。这一路径上的父目录如果不存在,则创建该父目录。
示例:
hadoop dfs -mkdir /user/hadoop/dir1 /user/hadoop/dir2
hadoop dfs -mkdir hdfs:// nn1.example.com/user/hadoop/dir
hdfs:// nn2.example.com/user/hadoop/dir
返回值:成功结束返回0,出现错误返回-1。
17.?moveFromLocal
格式:hadoop dfs -moveFromLocal
作用:和put命令类似,但是源文件localsrc拷贝之后自身被删除。
18.?moveToLocal
格式:hadoop dfs -moveToLocal [-crc]
作用:输出“Not implemented yet”信息,也就是说当前版本中未实现此命令。
19.?mv
格式:hadoop dfs -mv URI [URI …]
作用:将文件从源路径移动到目标路径(移动之后源文件删除)。目标路径为目录的情况下,源路径可以有多个。跨文件系统的移动(本地到HDFS或者反过来)是不允许的。
示例:
hadoop dfs -mv /user/hadoop/f?ile1 /user/hadoop./f?ile2
hadoop dfs -mv hdfs:// nn.example.com/f?ile1
hdfs:// nn.example.com/f?ile2 hdfs:// nn.example.com/f?ile3
hdfs:// nn.example.com/dir1
返回值:
成功结束返回0,出现错误返回-1。
20.?put
格式:hadoop dfs -put …
作用:将单个的源文件src或者多个源文件srcs从本地文件系统拷贝到目标文件系统中(对应的路径)。也可以从标准输入中读取输入,写入目标文件系统中。
示例:
hadoop dfs -put localf?ile /user/hadoop/hadoopf?ile
hadoop dfs -put localf?ile1 localf?ile2 /user/hadoop/hadoopdir
hadoop dfs -put localf?ile hdfs:// nn.example.com/hadoop/hadoopf?ile
hadoop dfs -put - hdfs:// nn.example.com/hadoop/hadoopf?ile
最后一个实例中,为“-”,这就是可以读取标准输入,当用户输入
EOF(Ctrl+C)时,输入结束,此命令会将这些输入的数据写入HDFS的对应目录中。
返回值:成功结束返回0,出现错误返回-1。图3-10所示是一个put命令操作结果示例。
图3-10 put命令示例
21.?rm
格式:hadoop dfs -rm [-skipTrash] URI [URI …]
作用:删除参数指定的文件,参数可以有多个。此命令只删除文件和非空目录。如果指定了-skipTrash选项,那么在回收站可用的情况下,该选项将跳过回收站而直接删除文件;否则,在回收站可用时,在HDFS Shell中执行此命令,会将文件暂时放到回收站中。这一选项在删除超过容量限制的目录(over-quota directory)中的文件时很有用。需要递归删除时可参考rmr命令。
示例:
hadoop dfs -rm hdfs:// nn.example.com/f?ile /user/hadoop/emptydir
返回值:成功结束返回0,出现错误返回-1。图3-11所示是一个rm命令操作结果示例。
图3-11 tail,rm命令,以及HDFS关闭命令示例
22.?rmr
格式:hadoop dfs -rmr [-skipTrash] URI [URI …]
作用:删除操作的递归版本,即递归删除所有子目录下的文件。如果指定了-skipTrash选项,那么在回收站可用的情况下,该选项将跳过回收站而直接删除文件;否则,在回收站可用时,在HDFS Shell中执行此命令,会将文件暂时放到回收站中。这一选项在删除超过容量限制的目录(over-quota directory)中的文件时很有用。
示例:
hadoop dfs -rmr /user/hadoop/dir
hadoop dfs -rmr hdfs:// nn.example.com/user/hadoop/dir
返回值:成功结束返回0,出现错误返回-1。
23.?setrep
格式:hadoop dfs -setrep [-R]
作用:改变一个文件在HDFS中的副本个数。使用-R选项可以对一个目录下的所有目录+文件递归执行改变副本个数的操作。
示例:
hadoop dfs -setrep -w 3 -R /user/hadoop/dir1
返回值:成功结束返回0,出现错误返回-1。
24.?stat
格式:hadoop dfs -stat [format] URI [URI …]
作用:返回对应路径的状态信息。可以通过与C语言中的printf类似的格式化字符串定制输出格式,这里支持的格式字符有:
%b:文件大小
%o:Block大小
%n:文件名
%r:副本个数
%y或%Y:最后一次修改日期和时间
默认情况输出最后一次修改日期和时间。
示例:
hadoop dfs -stat path
hadoop dfs -stat “%n %b %o %y”path
返回值:成功结束返回0,出现错误返回-1。
25.?tail
格式:hadoop dfs -tail [-f] URI
作用:在标准输出中显示文件末尾的1KB数据。-f的用法与Unix类似,也就是说当文件尾部添加了新的数据或者做出了修改时,在标准输出中也会刷新显示。
示例:
hadoop dfs -tail pathname
返回值:成功结束返回0,出现错误返回-1。
26.?test
格式:hadoop dfs -test -[ezd] URI
作用:判断文件信息。
选项含义:
-e检查文件是否存在,如果存在返回0。
-z检查文件大小是否为0,是的话返回0。
-d检查这一路径是否为目录,是的话返回0。
如果返回0则不输出,否则会输出相应的信息。
示例:
hadoop dfs -test -e f?ilename
27.?text
格式:hadoop dfs -text
作用:将文本文件或者某些格式的非文本文件通过文本格式输出。允许的格式有zip和TextRecordInputStream。
28.?touchz
格式:hadoop dfs -touchz URI [URI …]
作用:创建一个大小为0的文件。
示例:
hadoop dfs -touchz pathname
返回值:成功结束返回0,出现错误返回-1。
3.4.4 高级操作命令和工具
本节讲解HDFS的一些高级操作功能,以及通过web方式查看HDFS信息的方法。
1.?archive
在本地文件系统中,如果文件很少用,但又占用很大空间,可以将其压缩起来,以减少空间使用。在HDFS中同样也会面临这种问题,一些小文件可能只有几KB到几十KB,但是在DataNode中也要单独为其分配一个几十MB的数据块,同时还要在NameNode中保存数据块的信息。如果小文件很多的话,对于NameNode和DataNode都会带来很大负担。所以HDFS中提供了archive功能,将文件压缩起来,减少空间使用。
HDFS的压缩文件的后缀名是.har,一个har文件中包括文件的元数据(保存在_index和_masterindex)以及具体数据(保存在part-XX)。但是,HDFS的压缩文件和本地文件系统的压缩文件不同的是:har文件不能进行二次压缩;另外,har文件中,原来文件的数据并没有变化,har文件真正的作用是减少NameNode和DataNode过多的空间浪费。简单算一笔账,保存1000个10K的文件,不用archive的话,要用64M×1000,也就是将近63G的空间来保存;用archive的话,因为总数据量有10M(还需要加上这些文件的_index和_masterindex,不过很小就是了),只需要一个数据块,也就是64M的空间就够了。这样的话,节约的空间相当多;如果有十万百万的文件,那节省的空间会更可观。
将文件压缩成.har文件的格式如下:
hadoop archive -archiveName name -p *
选项含义如表3-1:
示例:
hadoop archive -archiveName zoo.har -p /foo/bar /outputdir
注意,.har文件一旦创建之后就不能更改,也不能再次被压缩。如果想给.har加文件,只能找到原来的文件,重新创建一个。
访问har文件的内容可以通过指定URL har:///user/data/arch.har来完成,所以可以通过上节提到的文件操作命令操作har,比如,显示har文件内容可以用:
hadoop dfs -ls har:///user/data/arch.har
查看全部文件可以用:
hadoop dfs -lsr har:///user/data/arch.har
也可以作为MapReduce作业的输入:
hadoopjar MyJob.jar MyJobMain har:///user/data/arch.jar \
/user/data/output/
看一下图2-12,将一个目录/user/zhaodi/resultTest/origin压缩成har文件。
压缩完毕后,发现origin的大小和har文件中的part-XX的大小一样,之所以一样的原因是har压缩文件在文件的数据块占用上做了优化,但是文件本身并未发生变化,只是单纯连接到一起而已。
2.?balancer
如3.2.1节所述,HDFS并不会将数据块的副本在集群中均匀分布,一个重要原因就是在已存在的集群中添加和删除DataNode被视作正常的情形。保存数据块时,NameNode会从多个角度考虑DataNode的选择,比如:
将副本保存到与第一个副本所在DataNode所属机架不同的机架上(这里的机架可以认为是若干DataNode组成的“局域网”,机架内部的DataNode之间的数据传输的代价远小于机架内部DataNode和机架外部的数据传输)。
在与正写入文件数据的DataNode相同的机架上,选择另外的DataNode放一个副本。
在满足以上条件之后,尽量将副本均匀分布。
在默认的副本因子为3的集群中,一般情况下,数据块的存放策略如下:首先,选择一个DataNode保存第一个副本;接下来,选择与第一副本所在DataNode不同的机架保存第二个副本;最后,和第二个副本相同的机架中,选择另外一个DataNode保存第三个副本。
如果管理员发现某些DataNode保存数据过多,而某些DataNode保存数据相对少,那么可以使用hadoop提供的工具balancer,手动启动内部的均衡过程。
命令如下:
hadoop balancer [-threshold ]
-threshold参数是一个0~100之间的实数,单位为百分比,默认值为10。这个参数表示:各个DataNode的利用率(已用空间/可用空间)与整个集群的利用率的差值的绝对值的上限。也就是说,如果每个DataNode的利用率和平均利用率相差不大(小于阈值)的话,可以认为这个集群已经“平衡”了。管理员可以通过Ctrl+C手动打断balancer。
另外还有一种运行方式,在终端中输入如下命令:
start-balancer.sh[–t ]
可以启动后台守护进程,也能达到同样效果。-t选项指定阈值。在“平衡”之后,进程退出,手动关闭进程的方式为:
stop-balancer.sh
3.?distcp
distcp(distribution copy)用来在两个HDFS之间拷贝数据。在HDFS之间拷贝数据要考虑很多因素,比如,两个HDFS的版本不同怎么办?两个HDFS的数据块大小、副本因子各不相同,又该怎么办?不同的数据块分布在不同节点上,如何让传输效率尽量高,等等。
正因如此,HDFS中专门用distcp命令完成跨HDFS数据拷贝。从/src/tools子目录下的源代码中可以看出,distcp是一个没有reducer的MapReduce过程。
distcp命令格式如下:
hadoop distcp [options] *
就是源文件和目标文件的路径,这和fs中的cp类似。
Options选项及含义如表3-2所示:
注:不同版本的HDFS可以通过http协议拷贝,那么命令
Hadoop distcp hdfs:// dn1:port1/data/f?ile1\
hdfs:// dn2:port2/data/f?ile2
可以写成:
hadoop distcp hftp:// dn1:port1/data/f?ile1\
hftp:// dn2:port2/data/f?ile2
后续版本中,HDFS中增加了distcp的增强版本distcp2。比起distcp,dsitcp2多了许多高级功能,如:-bandwidth,允许设置传输带宽;-atomic,允许借助临时目录进行拷贝;-strategy,允许设置拷贝策略;-async,允许异步执行(后台运行传输过程,而命令行可以继续执行命令)。
4.?dfsadmin
管理员可以通过dfsadmin管理HDFS。支持的命令选项及含义如表3-3:
另外,HDFS还提供了通过web查看HDFS信息的方式。HDFS启动之后,会建立web服务,在默认情况下,访问http://namenode-name:50070即可查看HDFS的Name Node信息,如图3-14所示:
图3-14 NameNode的web界面
通过web界面可以查看HDFS的信息,包括总容量、可用容量、DataNodes的信息、HDFS运行目录等。
点击“Browse the filesystem”可以查看HDFS的目录结构,如图3-15所示。
点击“Live Nodes”可以查看当前有效的DataNode的信息,如图3-16所示。
图3-15 HDFS的文件目录结构
图3-16 DataNode的相关信息