前文讲解了hadoop的基础理论及安装与配置:
- hadoop系列之六:CentOS X64编译安装hadoop
- hadoop系列之五:hadoop 2.2.0的安装配置
- hadoop系列之四:hadoop版本选择
- hadoop系列之三:Hadoop分布式文件系统(HDFS)理论基础
- hadoop系列之二:MapReduce理论基础
- hadoop系列之一:Hadoop简介
下面继续实际操作。
1. hdfs shell命令简介
既然 HDFS 是存取数据的分布式文件系统,那么对 HDFS 的操作,就是文件系统的基本操作,比如文件的创建、修改、删除、修改权限等,文件夹的创建、删除、重命名等。对HDFS 的操作命令类似于 lLinux 的 shell 对文件的操作,如 ls、mkdir、rm 等。我们执行以下操作的时候,一定要确定 hadoop 是正常运行的,使用 jps 命令确保看到各个 hadoop 进程。
[hadoop@hadoop01 hadoop]$ jps
41518 NameNode
42367 Jps
42028 ResourceManager
执行命令hadoop fs,可以看到如下图的帮助:
注意:hadoop fs ==hdfs dfs
图中显示了很多命令选项信息。以上截图不全,主要命令选项及用途如下:
选项名称 | 使用格式 | 含义 |
-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] [-crc] [hdfs源路径] [linux目的路径] | 从本地移动 |
-mkdir | -mkdir <hdfs路径> | 创建hdfs文件夹 |
-setrep | -setrep [-R] [-w] <副本数> <路径> | 修改副本数量 |
-touchz | -touchz <文件路径> | 创建空白文件 |
-stat | -stat [format] <路径> | 显示文件统计信息 |
-tail | -tail [-f] <文件> | 查看文件尾部信息 |
-chmod | -chmod [-R] <权限模式> [路径] | 修改权限 |
-chown | -chown [-R] [属主][:[属组]] 路径 | 修改属主 |
-chgrp | -chgrp [-R] 属组名称 路径 | 修改属组 |
-help | -help [命令选项] | 帮助 |
2. 部分命令详解
2.1 -ls:列出文件或目录:
[hadoop@hadoop01 hadoop]$ hadoop fs -ls /
Found 2 items
-rw-r--r-- 3 hadoop supergroup 47 2014-04-06 01:26 /issue
drwxr-xr-x - hadoop supergroup 0 2014-04-06 01:02 /user
上述命令列出了hdfs跟目录的文件,与ls -l执行结果非常相似,主要如下:
- 首字母表示文件夹(如果是“d”)还是文件(如果是“-” ) ;
- 后面的 9 位字符表示权限;
- 后面的数字或者“-”表示副本数。如果是文件,使用数字表示副本数;文件夹没有副本;
- 后面的“hadoop”表示属主;
- 后面的“supergroup”表示属组;
- 后面的“0” 、 “47”表示文件大小,单位是字节;
- 后面的时间表示修改时间,格式是年月日时分;
- 最后一项表示文件路径。
如果该命令选项后面没有路径, 那么就会访问/user/<当前用户>目录。 我们使用hadoop用户登录,因此会访问 hdfs 的/user/hadoop目录,如下两个命令看到的实际是同一个目录:
[hadoop@hadoop01 hadoop]$ hadoop fs -ls
Found 1 items
drwxr-xr-x - hadoop supergroup 0 2014-04-06 01:02 test
[hadoop@hadoop01 hadoop]$ hadoop fs -ls /user/hadoop
Found 1 items
drwxr-xr-x - hadoop supergroup 0 2014-04-06 01:02 /user/hadoop/test
2.2 –put:从本地上传:
如:将本地/usr/local/hadoop/etc/hadoop/下所有文件上传到hdfs的该用户目录下的test下:
[hadoop@hadoop01 hadoop]$ hadoop fs -put /usr/local/hadoop/etc/hadoop/* test/ ##上传
[hadoop@hadoop01 hadoop]$ hadoop fs -du / ##统计目录大小
47 /issue
0 /user
[hadoop@hadoop01 hadoop]$ hadoop fs -lsr / ##递归查看
lsr: DEPRECATED: Please use 'ls -R' instead.
-rw-r--r-- 3 hadoop supergroup 47 2014-04-06 01:26 /issue
drwxr-xr-x - hadoop supergroup 0 2014-04-06 01:02 /user
drwxr-xr-x - hadoop supergroup 0 2014-04-06 01:02 /user/hadoop
drwxr-xr-x - hadoop supergroup 0 2014-04-06 01:38 /user/hadoop/test
-rw-r--r-- 3 hadoop supergroup 3560 2014-04-06 01:38 /user/hadoop/test/capacity-scheduler.xml
-rw-r--r-- 3 hadoop supergroup 1335 2014-04-06 01:38 /user/hadoop/test/configuration.xsl
-rw-r--r-- 3 hadoop supergroup 318 2014-04-06 01:38 /user/hadoop/test/container-executor.cfg
-rw-r--r-- 3 hadoop supergroup 1361 2014-04-06 01:38 /user/hadoop/test/core-site.xml
-rw-r--r-- 3 hadoop supergroup 3589 2014-04-06 01:38 /user/hadoop/test/hadoop-env.cmd
-rw-r--r-- 3 hadoop supergroup 3515 2014-04-06 01:38 /user/hadoop/test/hadoop-env.sh
……
2.3 -getmerge 合并到本地
该命令选项的含义是把 hdfs 指定目录下的所有文件内容合并到本地 linux 的文件中,如下:
[hadoop@hadoop01 ~]$ hadoop fs -getmerge test/ ~/abc
[hadoop@hadoop01 ~]$ ll
total 64
-rw-r--r--. 1 hadoop hadoop 63473 Apr 6 01:43 abc
2.4 -setrep 设置副本数量
该命令选项是修改已保存文件的副本数量,后面跟副本数量,再跟文件路径,如下文件默认有三个副本,我调整为2个副本:
[hadoop@hadoop01 ~]$ hadoop fs -ls test/hadoop-env.sh
Found 1 items
-rw-r--r-- 3 hadoop supergroup 3515 2014-04-06 01:38 test/hadoop-env.sh
[hadoop@hadoop01 ~]$ hadoop fs -setrep 2 test/hadoop-env.sh
Replication 2 set: test/hadoop-env.sh
[hadoop@hadoop01 ~]$ hadoop fs -ls test/hadoop-env.sh
Found 1 items
-rw-r--r-- 2 hadoop supergroup 3515 2014-04-06 01:38 test/hadoop-env.sh
如果最后的路径表示文件夹,那么需要跟选项-R,表示对文件夹中的所有文件都修改副本。
还有一个选项是-w,表示等待副本操作结束才退出命令。
2.5 -stat 显示文件的统计信息
[hadoop@hadoop01 ~]$ hadoop fs -stat "%b %n %o %r %Y" test/hadoop-env.sh
3515 hadoop-env.sh 134217728 2 1396773498032
命令选项后面可以有格式,使用引号表示。示例中的格式“%b %n %o %r %Y”依次表示文件大小、文件名称、块大小、副本数、访问时间。
2.6 -touchz 创建空白文件
与linux下touch功能一样。
除上述命令外,其他命令用法基本与Linux下相关文件系统操作命令一直。
3. 其他常用命令
3.1 查看hdfs集群状态:
[hadoop@hadoop01 ~]$ hdfs dfsadmin -report
Configured Capacity: 56338194432 (52.47 GB)
Present Capacity: 42888241152 (39.94 GB)
DFS Remaining: 42887401472 (39.94 GB)
DFS Used: 839680 (820 KB)
DFS Used%: 0.00%
Under replicated blocks: 0
Blocks with corrupt replicas: 0
Missing blocks: 0-------------------------------------------------
Datanodes available: 3 (3 total, 0 dead)Live datanodes:
Name: 172.18.8.204:50010 (hadoop04)
Hostname: hadoop04
Decommission Status : Normal
Configured Capacity: 18779398144 (17.49 GB)
DFS Used: 282624 (276 KB)
Non DFS Used: 4482347008 (4.17 GB)
DFS Remaining: 14296768512 (13.31 GB)
DFS Used%: 0.00%
DFS Remaining%: 76.13%
Last contact: Sun Apr 06 05:02:34 PDT 2014Name: 172.18.8.203:50010 (hadoop03)
Hostname: hadoop03
Decommission Status : Normal
Configured Capacity: 18779398144 (17.49 GB)
DFS Used: 282624 (276 KB)
Non DFS Used: 4482486272 (4.17 GB)
DFS Remaining: 14296629248 (13.31 GB)
DFS Used%: 0.00%
DFS Remaining%: 76.13%
Last contact: Sun Apr 06 05:02:36 PDT 2014Name: 172.18.8.202:50010 (hadoop02)
Hostname: hadoop02
Decommission Status : Normal
Configured Capacity: 18779398144 (17.49 GB)
DFS Used: 274432 (268 KB)
Non DFS Used: 4485120000 (4.18 GB)
DFS Remaining: 14294003712 (13.31 GB)
DFS Used%: 0.00%
DFS Remaining%: 76.12%
Last contact: Sun Apr 06 05:02:34 PDT 2014
3.2 查看文件块组成:
[hadoop@hadoop01 ~]$ hdfs fsck / -files -blocks
Connecting to namenode via http://hadoop01.barlow.com:50070
FSCK started by hadoop (auth:SIMPLE) from /172.18.8.201 for path / at Sun Apr 06 05:08:19 PDT 2014
/ <dir>
/issue 47 bytes, 1 block(s): OK
0. BP-1956410728-172.18.8.201-1396769414895:blk_1073741825_1001 len=47 repl=3/user <dir>
/user/hadoop <dir>
/user/hadoop/abc <dir>
Status: HEALTHY
Total size: 47 B
Total dirs: 4
Total files: 1
Total symlinks: 0
Total blocks (validated): 1 (avg. block size 47 B)
Minimally replicated blocks: 1 (100.0 %)
Over-replicated blocks: 0 (0.0 %)
Under-replicated blocks: 0 (0.0 %)
Mis-replicated blocks: 0 (0.0 %)
Default replication factor: 3
Average block replication: 3.0
Corrupt blocks: 0
Missing replicas: 0 (0.0 %)
Number of data-nodes: 3
Number of racks: 1
FSCK ended at Sun Apr 06 05:08:19 PDT 2014 in 2 millisecondsThe filesystem under path '/' is HEALTHY
4. hdfs的Web接口
在namenode节点上,默认web接口端口为50070,可以使用浏览器访问查看hdfs状态
可以查看各DataNode状态,如下图:
该端口的定义位于 core-default.xml 中,用户可以在 core-site.xml 中自行修改。
<property>
<name>dfs.http.address</name>
<value>0.0.0.0:50070</value>
</property>
而DataNode的web端口默认为50075,要通过namenode节点点击访问(上图):
通过此图也可以看出,DataNode的默认块大小为128M。即使几kb的文件也占用128M空间,再次验证了HDFS仅适合存放大数据,对于海量小文件是不适合的。
该地址和端口的定义位于 hdfs-default.xml 中,用户可以在 hdfs-site.xml中自行修改,如下图:
5. HDFS的JavaAPI
我们在工作中写完的各种代码是在服务器中运行的,HDFS 的操作代码也不例外。在开发阶段,如果我们使用 windows 下的 eclipse 作为开发环境,访问运行在hadoop中的 HDFS。也就是通过在本地的 eclipse 中的 java 代码访问远程 linux 中的 hdfs。
要使用Windows中的 java 代码访问hadoop中的 hdfs,需要保证以下几点:
- 确保宿主机与客户机的网络是互通的
- 确保宿主机和客户机的防火墙都关闭,因为很多端口需要通过,为了减少防火墙配置,直接关闭
- 确保宿主机与客户机使用的 jdk 版本一致。如果客户机使用 jdk6,宿主机使用 jdk7,那么代码运行时会报不支持的版本的错误
- 宿主机的登录用户名必须与客户机的用户名一直。比如我们 linux 使用的是 root 用户,那么 windows 也要使用 root 用户,否则会报权限异常
- 在 eclipse 项目中覆盖 hadoop 的 org.apache.hadoop.fs.FileUtil 类的 checkReturnValue 方法,以避免权限错误,如下图:
5.1 简单的读取文件:
具体如下:
ljava.net.URL
lorg.apache.hadoop.io.IOUtils
lorg.apache.hadoop.fs.FsUrlStreamHandlerFactory
或:
java.net.URI
org.apache.hadoop.conf.Configuration
org.apache.hadoop.fs.FileSystem
org.apache.hadoop.fs.Path
org.apache.hadoop.io.IOUtils
5.2 FileSystem API
在 hadoop 的 HDFS 操作中,有个非常重要的 api,是 org.apache.hadoop.fs.FileSystem,这是我们用户代码操作 HDFS 的直接入口,该类含有操作 HDFS 的各种方法,类似于 jdbc 中操作数据库的直接入口是 Connection 类。
通过FileSystem API,可以完成如下功能及其对应的类:
- 写文件 create
- 读取文件 open
- 删除文件delete
- 创建目录 mkdirs
- 删除文件或目录 delete
- 列出目录的内容 listStatus
- 显示文件系统的目录和文件的元数据信息 getFileStatus
5.2.1 读取文件可用如下方法:
/**
* 读取文件,调用fileSystem的open(path)
* @throws Exception
*/
private static void readFile() throws Exception {
FileSystem fileSystem = getFileSystem();
FSDataInputStream openStream = fileSystem.open(new Path("hdfs://hadoop01:9000/aaa"));
IOUtils.copyBytes(openStream, System.out, 1024, false);
IOUtils.closeStream(openStream);
}
5.2.2 创建目录与删除目录:
/**
* 创建目录,调用fileSystem的mkdirs(path)
* @throws Exception
*/
private static void mkdir() throws Exception {
FileSystem fileSystem = getFileSystem();
fileSystem.mkdirs(new Path("hdfs://hadoop01:9000/bbb"));
}
/**
* 删除目录,调用fileSystem的deleteOnExit(path)
* @throws Exception
*/
private static void rmdir() throws Exception {
FileSystem fileSystem = getFileSystem();
fileSystem.delete(new Path("hdfs://hadoop01:9000/bbb"));
}
5.2.3 遍历目录:
/**
* 遍历目录,使用FileSystem的listStatus(path)
* 如果要查看file状态,使用FileStatus对象
* @throws Exception
*/
private static void list() throws Exception{
FileSystem fileSystem = getFileSystem();
FileStatus[] listStatus = fileSystem.listStatus(new Path("hdfs://hadoop01:9000/"));
for (FileStatus fileStatus : listStatus) {
String isDir = fileStatus.isDir()?"目录":"文件";
String name = fileStatus.getPath().toString();
System.out.println(isDir+" "+name);
}
}
其他操作类似,只需调用相关子类即可完成。
由于本人并不会Java开发,因此只列举几个简单的示例,不做深入探讨。