HDFS是一个分布式文件系统,安装完成之后使用起来类似于本地文件系统,但是它是一个网络文件系统,所以访问这种文件系统的方式和访问本地文件系统的方式还是有所差别的(本地文件系统的方式是基于系统调用的,当然也有类似NFS这样的网络文件系统可以使用和本地文件系统相同的访问方式,那是因为已经在内核中安装了NFS,而HDFS只是一个应用层的服务程序罢了)。但是这些命令看上去还是和常用的shell命令很类似的。
首先,我们需要下载一个hadoop程序包,hadoop分为两个压缩文件,一个是源代码,一个是编译好的程序包,下载的地址:http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-2.6.0/,这里使用的是最新的2.6.0版本,下载好hadoop-2.6.0.tar.gz文件之后进行解压会有这些文件:
hzfengyu@hzfengyu-VirtualBox:~/workplace/hadoop/hadoop-2.6.0$ ls
bin etc include lib libexec LICENSE.txt logs NOTICE.txt README.txt sbin share
这些文件和我们在linux下安装的其他软件的目录结构差不多,所有的配置文件都在/etc下面,可执行文件放在bin目录下,sbin放的是一些脚本文件。
要想单独启动一个hdfs用来尝试一下文件存储的功能,需要对下面的文件进行配置:
1、配置etc/hadoop/hadoop-env.sh文件,看了一下这里执行了一些export目录设置系统的环境变量。
需要配置里面的JAVA_HOME变量,设置为java安装路径
默认情况下export JAVA_HOME=${JAVA_HOME},查看系统的JAVA_HOME路径并配置。
hzfengyu@hzfengyu-VirtualBox:~/workplace/hadoop/hadoop-2.6.0/etc/hadoop$ echo ${JAVA_HOME}
/home/hzfengyu/java/jdk1.7.0_60
当然,也可以在这里面添加HADOOP_HOME=hadoop的安装目录,方面访问hadoop的根目录。
2、配置etc/hadoop/core-site.xml文件,从命名上可以看出这里是一些核心的配置项,hadoop的配置都是使用key:value的方式,但是配置文件都是使用xml的方式,所以基本的结构都是这样子的:
<configuration>
<property>
<name>key</name>
<value>value</value>
</property>
</configuration>
这里需要配置的key是hadoop.tmp.dir,这个配置的是HDFS系统以来的基础目录,如果不配置它会设置为/tmp目录下,而/tmp目录下的文件不是永久性的,所以可能出现问题。另外如果在hdfs的namenode和datanode目录不配置的情况下,默认也会存放在该目录中。(http://f.dataguru.cn/thread-72882-1-1.html)
配置项fs.default.name设置的是HDFS的namenode的访问地址,因为namenode存放的是系统的所有元数据信息,也就是文件系统访问的入口,所以这个是必须要配置的,这里配置的是hdfs://hzfengyu.netease.com:9000。要保证前面的域名是本机可以识别的。整个的配置文件如下:
<configuration>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hzfengyu/workplace/hadoop/data</value>
</property>
<property>
<name>fs.default.name</name>
<value>hdfs://hzfengyu.netease.com:9000</value>
</property>
</configuration>
3、配置etc/hadoop/hdfs-site.xml文件,这个文件是hdfs的配置文件,需要配置如下几项:
dfs.replication:从命名上可以看出这里配置的是每一个block的复制的份数,这里我们为了测试,简单配置为1.
dfs.namenode.name.dir:namenode依赖的根目录文件
dfs.datannode.data.dir:datanode依赖的根目录文件
完整的配置如下:
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/home/hzfengyu/workplace/hadoop/hdfs/name</value>
</property>
<property>
<name>dfs.datannode.data.dir</name>
<value>/home/hzfengyu/workplace/hadoop/hdfs/data</value>
</property>
</configuration>
4、配置好了hdfs的两个程序的配置,接下来就可以启动进程了,首先要执行HDFS的格式化操作:
./bin/hadoop namenode -format
执行完成之后,配置的namenode目录下会出现一些文件。
5、启动进程
分别要启动namenode、datanode和secondarynamenode,分别执行一下命令:
./sbin/hadoop-daemon.sh start namenode
./sbin/hadoop-daemon.sh start datanode
./sbin/hadoop-daemon.sh start secondarynamenode
查看启动的java进程可以看到,他们都分别启动了:
hzfengyu@hzfengyu-VirtualBox:~/workplace/hadoop/hadoop-2.6.0$ jps
10012 Jps
9834 NameNode
9973 SecondaryNameNode
9890 DataNode
6、使用
HDFS的目录格式是hadoop fs -cmd,其中cmd是具体的目录,例如ls、cp等,现在我们hadoop是绿色安装的,所以这里先设置一下hadoop的路径到系统的PATH变量下:
export PATH="${PATH}:${HADOOP_HOME}/sbin:${HADOOP_HOME}/bin"
接着就可以使用hadoop fs -cmd执行具体的命令了。
首先我们试着执行一下ls的命令:hadoop fs -ls,结果出现了这样的错误:
hzfengyu@hzfengyu-VirtualBox:~/workplace/hadoop/hadoop-2.6.0$ hadoop fs -ls
Java HotSpot(TM) Client VM warning: You have loaded library /home/hzfengyu/workplace/hadoop/hadoop-2.6.0/lib/native/libhadoop.so.1.0.0 which might have disabled stack guard. The VM will try to fix the stack guard now.
It's highly recommended that you fix the library with 'execstack -c <libfile>', or link it with '-z noexecstack'.
15/01/16 18:08:08 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
ls: `.': No such file or directory
上面的WARN不用管,这里提示我们没有这个目录,其实就像我们在linux的shell下执行ls目录一样,默认ls打印的是当前目录下文件的信息,但是shell是一个进程,所以他可以保存我们当前进入到的目录,因此就可以使用"."和".."进入当前目录和父目录,也就是说可以使用相对路径,但是我们在客户端启动一个HDFS的命令启动的是一个单独的进程,所以也就没有当前目录的概念了,所以我们在这时只能使用绝对路径访问,如果我们在一个程序里面使用HDFS的客户端访问,这时候才可以使用相对路径。
好了,HDFS的目录结构也是树形的结构,所以我们先看一下根目录下的信息,执行hadoop fs -ls /,发现除了之前的WARN信息之外就没有其他的内容了,这是因为我们还没有在HDFS中存储任何文件。顺便提一下,HDFS支持的命令如下:
Usage: hadoop fs [generic options]
[-appendToFile <localsrc> ... <dst>]
[-cat [-ignoreCrc] <src> ...]
[-checksum <src> ...]
[-chgrp [-R] GROUP PATH...]
[-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...]
[-chown [-R] [OWNER][:[GROUP]] PATH...]
[-copyFromLocal [-f] [-p] [-l] <localsrc> ... <dst>]
[-copyToLocal [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
[-count [-q] [-h] <path> ...]
[-cp [-f] [-p | -p[topax]] <src> ... <dst>]
[-createSnapshot <snapshotDir> [<snapshotName>]]
[-deleteSnapshot <snapshotDir> <snapshotName>]
[-df [-h] [<path> ...]]
[-du [-s] [-h] <path> ...]
[-expunge]
[-get [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
[-getfacl [-R] <path>]
[-getfattr [-R] {-n name | -d} [-e en] <path>]
[-getmerge [-nl] <src> <localdst>]
[-help [cmd ...]]
[-ls [-d] [-h] [-R] [<path> ...]]
[-mkdir [-p] <path> ...]
[-moveFromLocal <localsrc> ... <dst>]
[-moveToLocal <src> <localdst>]
[-mv <src> ... <dst>]
[-put [-f] [-p] [-l] <localsrc> ... <dst>]
[-renameSnapshot <snapshotDir> <oldName> <newName>]
[-rm [-f] [-r|-R] [-skipTrash] <src> ...]
[-rmdir [--ignore-fail-on-non-empty] <dir> ...]
[-setfacl [-R] [{-b|-k} {-m|-x <acl_spec>} <path>]|[--set <acl_spec> <path>]]
[-setfattr {-n name [-v value] | -x name} <path>]
[-setrep [-R] [-w] <rep> <path> ...]
[-stat [format] <path> ...]
[-tail [-f] <file>]
[-test -[defsz] <path>]
[-text [-ignoreCrc] <src> ...]
[-touchz <path> ...]
[-usage [cmd ...]]
先来使用df看一下根目录的空间使用情况:fs -df -h /
Filesystem Size Used Available Use%
hdfs://hzfengyu.netease.com:9000 18.6 G 24 K 8.4 G 0%
然后在使用touchz创建一个空文件:
hadoop fs -touchz /hello /world
然后执行ls目录查看这两个文件:
Found 2 items
-rw-r--r-- 1 hzfengyu supergroup 0 2015-01-16 18:21 /hello
-rw-r--r-- 1 hzfengyu supergroup 0 2015-01-16 18:21 /world
但是此时查看datanode目录下根本没有内容,这是因为创建两个空文件只需要在文件系统的命名空间上添加个叶节点,而不需真正的创建block写入数据,接着我们试着拷贝一个大文件:hadoop fs -put ../../hadoop.tar /,注意cp目录是在hdfs内部拷贝文件。
此时如果用tcpdump抓包查看会发现大量的网络数据包,使用的端口是50010,查看会发现它是datanode的监听端口,也就是说数据传输是在客户端和datanode之间进行的。
此时再次执行ls目录会发现文件已经存在于根目录下了:
Found 3 items
-rw-r--r-- 1 hzfengyu supergroup 620369920 2015-01-16 18:26 /hadoop.tar
-rw-r--r-- 1 hzfengyu supergroup 0 2015-01-16 18:21 /hello
-rw-r--r-- 1 hzfengyu supergroup 0 2015-01-16 18:21 /world
此时会在datanode的目录下发现一个个的block文件:
总用量 597M
drwxrwxr-x 2 hzfengyu hzfengyu 4.0K 1月 16 18:26 .
drwxrwxr-x 3 hzfengyu hzfengyu 4.0K 1月 16 18:25 ..
-rw-rw-r-- 1 hzfengyu hzfengyu 128M 1月 16 18:25 blk_1073741825
-rw-rw-r-- 1 hzfengyu hzfengyu 1.1M 1月 16 18:25 blk_1073741825_1001.meta
-rw-rw-r-- 1 hzfengyu hzfengyu 128M 1月 16 18:26 blk_1073741826
-rw-rw-r-- 1 hzfengyu hzfengyu 1.1M 1月 16 18:26 blk_1073741826_1002.meta
-rw-rw-r-- 1 hzfengyu hzfengyu 128M 1月 16 18:26 blk_1073741827
-rw-rw-r-- 1 hzfengyu hzfengyu 1.1M 1月 16 18:26 blk_1073741827_1003.meta
-rw-rw-r-- 1 hzfengyu hzfengyu 128M 1月 16 18:26 blk_1073741828
-rw-rw-r-- 1 hzfengyu hzfengyu 1.1M 1月 16 18:26 blk_1073741828_1004.meta
-rw-rw-r-- 1 hzfengyu hzfengyu 80M 1月 16 18:26 blk_1073741829
-rw-rw-r-- 1 hzfengyu hzfengyu 638K 1月 16 18:26 blk_1073741829_1005.meta
每一个block的大小为128M,每一个文件关联一个meta文件。
好了,这里我们简单介绍了一下部署和安装HDFS的步骤和一些基本的命令。