与HDFS交互 这节将向你介绍与HDFS交互的命令,这些命令可以载入数据,取得数据,操作文件。 所有与集群交互的命令是通过一个脚本bin/hadoop来进行的,它可以用Java虚拟机载入Hadoop系统,来执行用户命令,命令的格式如下: user@machine:hadoop$ bin/hadoop moduleName -cmd args... modulteName是要使用的Hadoop功能的模块名,-cmd是用这个模块的命令,它的参数在命令名之后。 有两个模块与HDFS相关:dfs和dfsadmin,它们的用途将在下面描述。 常用的操作示例dfs模块也被称为“FsShell”,它提供基本的文件操作功能,下面将进行介绍。 只有集群有有用信息时,这个集群才是有用的。所以首先要进行的操作是载入数据到集群,在示例中,我们假设用户为“someone”,你自己尝试时使用自己的用户名就可以了,同样注意对文件的操作可以是集群中任一一个结点的操作,在这个结点上的conf/hadoop-sicte.xml中fs,default.name为你集群的名字结点。我们称我们操作的机器为anynode,命令行在你安装Hadoop的hadoop目录下运行,也许它在的机器的路径是/home/someone/hadoop,在别的机器上是/home/foo/hadoop,开始介绍的命令主要是载入数据,查看它是否在那里,再从HDFS中取回数据。 列出文件如果我们现在就尝试去查看HDFS,我们什么也不会看到: someone@anynode:hadoop$ bin/hadoop dfs -ls someone@anynode:hadoop$ ls命令什么也没有返回。不带参数,-ls将列出HFFS的主目录下的文件,不要忘记它和/home/$USER不是同一目录(HDFS与本地文件不在一个命名空间中),HDFS中没有当前工作目录这个概念,也没有cd命令。 如果提供-ls参数,你会看到一些初始目录的内容: someone@anynode:hadoop$ bin/hadoop dfs -ls / Found 2 items drwxr-xr-x - hadoop supergroup 0 2008-09-20 19:40 /hadoop drwxr-xr-x - hadoop supergroup 0 2008-09-20 20:08 /tmp 这些都是系统创建的内容,示例输出假设hadoop是用户名,Hadoop守护进程就是在这个用户名下启动的。Supergroup是HDFS实例启动用户(hadoop)所在的组,示例的输出目录可使Hadoop MapReduce系统将必要的数据移到不同的结点,细节在第四章中解释。 载入数据到集群因为在一般的Unix或Linux系统中,用户的文件保存在/home/$USER中,所以HDFS将文件保存在/user/$USER,对于一些如ls的命令,需要用户给出目录名却没有给出时,就默认/home/$USER目录(有的命令要求明确指名源路径和目标路径),在HDFS或Hadoop MapReduce中,参数中所有的相对路径,或系统的其它地方,都假设相对的是/home/$USER目录。 第一步:如果你的主目录不存在,先创建它。 someone@anynode:hadoop$ bin/hadoop dfs -mkdir /user 如果没有/user目录,先创建它,其实它会在需要的时候自动创建,但作为示例,现在我们手动创建也是合理的。 然后我们可以创建你的主目录了。 someone@anynode:hadoop$ bin/hadoop dfs -mkdir /user/someone 当然,别忘了把/user/someone换成/user/yourUserName。 第二步:上传一个文件,将单个文件载入HDFS,我们可以用put命令: someone@anynode:hadoop$ bin/hadoop dfs -put /home/someone/interestingFile.txt /user/yourUserName 这个命令会将/home/someone/interestingFile.txt从本地目录拷贝到HDFS的/user/yourUserName/interestingFile.txt。 第三步:检查在HDFS中的文件,我们可用下面任一命令来查看文件。 someone@anynode:hadoop$ bin/hadoop dfs -ls /user/yourUserName someone@anynode:hadoop$ bin/hadoop dfs -ls 在下面将展示put命令的示例和它们的结果: 命令 | 假设 | 结果 | bin/hadoop dfs -put foo bar | No file/directory named /user/$USER/bar exists in HDFS | Uploads local file foo to a file named /user/$USER/bar | bin/hadoop dfs -put foo bar | /user/$USER/bar is a directory | Uploads local file foo to a file named /user/$USER/bar/foo | bin/hadoop dfs -put foo somedir/somefile | /user/$USER/somedir does not exist in HDFS | Uploads local file foo to a file named /user/$USER/somedir/somefile, creating the missing directory | bin/hadoop dfs -put foo bar | /user/$USER/bar is already a file in HDFS | No change in HDFS, and an error is returned to the user. |
当用put命令操作一个文件,这个操作或是全部完成,或是一点不做。一个文件上传到HDFS,首先要把数据复制到数据结点,当数据结点表明它们已经接收了全部的数据,并且文件句柄也已经关闭,那么这时文件才对系统其余部分是可见的,所以根据put命令的返回值 ,你可以确定文件或是成功上传,或是“完全失败”,你将永远不会得到一个文件部分上传或是文件内容部分可见的状态,如果遇到上传断开连接,或上传内容未完成的情况,HDFS表现地就像没有上传发生一样。 第四步:一次上传多个文件。put命令可以一次操作多个文件,还可以上传整个目录到HDFS中。 创建一个目录,然后用cp命令拷贝几个文件到这个目录中,在示例中,我们有如下目录内容: someone@anynode:hadoop$ ls -R myfiles myfiles: file1.txt file2.txt subdir/ myfiles/subdir: anotherFile.txt someone@anynode:hadoop$ 整个myfiles/目录可以用下面命令拷贝到HDFS中: someone@anynode:hadoop$ bin/hadoop -put myfiles /user/myUsername someone@anynode:hadoop$ bin/hadoop -ls Found 1 items /user/someone/myfiles <dir> 2008-06-12 20:59 rwxr-xr-x someone supergroup user@anynode:hadoop bin/hadoop -ls myfiles Found 3 items /user/someone/myfiles/file1.txt <r 1> 186731 2008-06-12 20:59 rw-r--r-- someone supergroup /user/someone/myfiles/file2.txt <r 1> 168 2008-06-12 20:59 rw-r--r-- someone supergroup /user/someone/myfiles/subdir <dir> 2008-06-12 20:59 rwxr-xr-x someone supergroup 上面展示了整个目录被正确地递归上传上,你会注意到除了文件路径外,ls命令还显示了每个文件的复制数(在<r 1>中的1),文件大小,上传时间,权限,所有者信息。 另一个与put功能相同的命令-copyFromLocal,它在使用方法上与put完全一样。 从HDFS中取得数据有多种多HDFS中取得数据的方法,最简单的方法是用cat命令将文将内容输出到标准输出(当然它也可以输出到管道用于其它应用或目标文件)。 第一步:用cat显示文件。 假设你已经上传了一个foo文件到HDFS的主目录,你可以用以下命令显示它的内容: someone@anynode:hadoop$ bin/hadoop dfs -cat foo (contents of foo are displayed here) someone@anynode:hadoop$ 第二步:将一个文件从HDFS拷贝到本地文件系统。 get命令作用与put命令相反,它将一个文件或一个目录(递归地)从HDFS中拷贝到你选择的本地文件系统中,一个功能相同的命令是copyToLocal。 someone@anynode:hadoop$ bin/hadoop dfs -get foo localFoo someone@anynode:hadoop$ ls localFoo someone@anynode:hadoop$ cat localFoo (contents of foo are displayed here) 停止HDFS如果你想停止集群的HDFS(或是因为不想不用Hadoop时,它还占用内存资源,或是因为想升级配置重启集群),那么你可以登录名字结点所在的机器,运行: someone@namenode:hadoop$ bin/stop-dfs.sh 这个命令必须由启动HDFS,即运行bin/start-dfs.sh的用户执行。 HDFS命令参考除介绍的命令外,还有许多bin/hadoop.dfs命令,以上介绍的只是帮助你开始使用HDFS,运行bin/hadoop dfs不带任何参数会列出所有FsShell系统提供的命令,当你遇到问题时执行bin/hadoop dfs –help commandName会显示这个命令的用法。 下面是所有命令的介绍,介绍之前先定义一下参数的意义: 1. 斜体:表示用户输入的变量。 2. path:表示文件名或目录名。 3. path…:表示一个或多个文件名或目录名。 4. file:表示任意文件名。 5. src和dest:表示HDFS的源路径和目标路径 6. localSrc和localDest:表示本地文件系统的源路径和目标路径。 7. 在[]中的参数是可选的。 1. -ls path 列出path目录下的内容,包括文件名,权限,所有者,大小和修改时间。 2. -lsr path 与ls相似,但递归地显示子目录下的内容。 3. -du path 显示path下所有文件磁盘使用情况下,用字节大小表示,文件名用完整的HDFS协议前缀表示。 4. -dus path 与-du相似,但它还显示全部文件或目录磁盘使用情况 5. -mv src dest 将文件或目录从HDFS的源路径移动到目标路径。 6. -cp src dest 在HDFS中,将src文件或目录复制到dest。 7. –rm path 删除一个文件或目录 8. –rmr path 删除一个文件或递归删除目录 9. –put localSrc dest 将本地文件或目录localSrc上传到HDFS中的dest路径。 10. –copyFromLocal localSrc dest 与-put命令相同 11. –moveFromLocal localSrc dest 将文件或目录从localSrc上传到HDFS中的dest目录,再删除本地文件或目录localSrc。 12 –get [-crc] src localDest 将文件或目录从HDFS中的src拷贝到本地文件系统localDest。 13 –getmerge src localDest [addnl] 将在HDFS中满足路径src的文件合并到本地文件系统的一个文件localDest中。 14 –cat filename 显示文件内容到标准输出上。 15. -copyToLocal [-crc] src localDest 与-get命令相同。 16 -moveToLocal [-crc] src localDest 与-get命令相似,但拷贝结束后,删除HDFS上原文件。 17 -mkdir path 在HDFS中创建一个名为path的目录,如果它的上级目录不存在,也会被创建,如同linux中的mkidr –p。 18 -setrep [-R] [-w] rep path 设置目标文件的复制数。 19 -touchz path 创建一个文件。时间戳为当前时间,如果文件本就存在就失败,除非原文件长充为0。 20 -test –[ezd] path 如果路径(path)存在,返回1,长度为0(zero),或是一个目录(directory)。 21 –stat [format] path 显示文件所占块数(%b),文件名(%n),块大小(%n),复制数(%r),修改时间(%y%Y)。 22 –tail [-f] file 显示文件最后的1KB内容到标准输出。 23 –chmod [-R] [owner][:[group]] path… 递归修改时带上-R参数,mode是一个3位的8进制数,或是[augo]+/-{rwxX}。 24 –chgrp [-R] group 设置文件或目录的所有组,递归修改目录时用-R参数。 25 –help cmd 显示cmd命令的使用信息,你需要把命令的“-”去掉。 DFSAdmin命令参考dfs模块提供了常用的文件或目录操作,但它们都是对文件系统内部的操作,dfsadmin模块是对整个文件系统操作或查询,我们下面将介绍它。 得到全局状态。一个简洁的HDFS状态状态报告可以用bin/hadoop dfsadmin –report得到,它返回的是HDFS集群的基本健康信息。 更详细的状态。如果你想知道名字结点元数据状态的更多信息,你可以使用bin/hadoop dfsadmin –metasave filename命令,它将信息保存到filename中,metasave命令枚举在复制的块列表。注意,这个命令的帮助信息是“保存名字结点的主要数据结构”,但它是错误 的,名字结点的状态不能通过个命令保存,它提供的是名字结点对数据块的处理信息。 安全模式。安全模式是HDFS的一种状态,在这种状态下,文件系统以只读方式被挂载,不进行冗余复制,文件不能被创建也不能被删除,这是名字结点启动后自动进入的状态,以来允许所有数据结点与名字结点时间同步,并声明它们所拥有的块,然后名字结点才决定哪些块被复制,等等。名字结点要等到一定比例的数据块可见,这个比例是由配置中的dfs.safemode.threshold参数来决定,在达到这个比例的阈值后,安全模式自动退出,然后HDFS允许正常操作。bin/hadoop dfsadmin –safemode what命令允许用户根据what的值操作安全模式,what的值在下面列出: 1. enter进入安全模式。 2. leave 强制名字结点退出安全模式。 3. get 返回标名安全模式是ON还是OFF的字符串。 4. wait 等待直到名字结点退出安全模式后自动返回。 修改HDFS成员。当停止结点时,要将它们逐步地与HDFS断开连接,来保证数据不会丢失,在本章停止结点的小节中,介绍-refreshNodes dfasdmin命令。 升级HDFS版本。当将HDFS版本升级到另一版本时,名字结点和数据结点的格式有可能改变,当你要启动新的Hadoop时,你需要告诉Hadoop去修改HDFS版本,用bin/start-dfs.sh –upgrade命令。它将开始升级HDFS版本,升级进行的信息可以用bin/hadoop dfsadmin –upgradeProgress status命令查询,你可以用bin/hadoop dfsadmin –upgradeProgress details得到更详细的升级信息。如果升级阻塞了,你可以用bin/hadoop dfsadmin –updateProgress force命令,使它继续进行(注意,在使用这个命令时,你最好知道你在干什么)。 当HDFS升级后,Hadoop保留了允许你降级到以前HDFS版本的信息,以防你想回到以前的Hadoop版本,如果你要降级就先停止集群,重装旧版的Hadoop,再运行bin/start-dfs.sh –rollback,它就会回到以前版本的HDFS状态。 每次只能保存一个存档拷贝,所以在新版本下运行几天后(当感觉它稳定后),可以用bin/hadoop dfsadmin –finalizeUpgrade命令删除存档拷贝,而rollback命令将不再可用,但这也是进行第二次升级必要的一个工作。 获得帮助。与dfs中一样,输入bin/hadoop dfsadmin –help cmd命令会显示这个命令的用法。
|