实验环境
CentOS 6.X
Hadoop 2.6.0
JDK 1.8.0_65
目的
这篇文档的目的是帮助你快速完成单机上的Hadoop安装与使用以便你对Hadoop分布式文件系统(HDFS)和Map-Reduce框架有所体会,比如在HDFS上运行示例程序或简单作业等。
先决条件
支持平台
GNU/Linux是产品开发和运行的平台。 Hadoop已在有2000个节点的GNU/Linux主机组成的集群系统上得到验证。
Win32平台是作为开发平台支持的。由于分布式操作尚未在Win32平台上充分测试,所以还不作为一个生产平台被支持。
安装软件
如果你的集群尚未安装所需软件,你得首先安装它们。
以 CentOS 为例:
# yum install ssh rsync -y
# ssh 必须安装并且保证 sshd一直运行,以便用Hadoop 脚本管理远端Hadoop守护进程。
创建用户
# useradd -m hadoop -s /bin/bash # 创建新用户hadoop
Hosts解析
# cat /etc/hosts| grep ocean-lab
192.168.9.70 ocean-lab.ocean.org ocean-lab
安装jdk
JDK �C http://www.oracle.com/technetwork/java/javase/downloads/index.html
首先安装JAVA环境
# wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u65-b17/jdk-8u65-linux-x64.rpm"
# rpm -Uvh jdk-8u65-linux-x64.rpm
配置 Java
# echo "export JAVA_HOME=/usr/java/jdk1.8.0_65" >> /home/hadoop/.bashrc
# source /home/hadoop/.bashrc
# echo $JAVA_HOME
/usr/java/jdk1.8.0_65
下载安装hadoop
为了获取Hadoop的发行版,从Apache的某个镜像服务器上下载最近的 稳定发行版。
运行Hadoop集群的准备工作
# wget http://apache.fayea.com/hadoop/common/hadoop-2.6.0/hadoop-2.6.0.tar.gz
解压所下载的Hadoop发行版。编辑 conf/hadoop-env.sh文件,至少需要将JAVA_HOME设置为Java安装根路径。
# tar xf hadoop-2.6.0.tar.gz -C /usr/local
#### mv /usr/local/hadoop-2.6.0 /usr/local/hadoop
尝试如下命令:
# bin/hadoop
将会显示hadoop 脚本的使用文档。
现在你可以用以下三种支持的模式中的一种启动Hadoop集群:
单机模式
伪分布式模式
完全分布式模式
单机模式的操作方法
默认情况下,Hadoop被配置成以非分布式模式运行的一个独立Java进程。这对调试非常有帮助。
现在我们可以执行例子来感受下 Hadoop 的运行。Hadoop 附带了丰富的例子包括 wordcount、terasort、join、grep 等。
在此我们选择运行 grep 例子,我们将 input 文件夹中的所有文件作为输入,筛选当中符合正则表达式 dfs[a-z.]+ 的单词并统计出现的次数,最后输出结果到 output 文件夹中。
# mkdir input
# cp conf/*.xml input
# ./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0.jar grep ./input/ ./ouput 'dfs[a-z.]+'
# cat output/*
若执行成功的话会输出很多作业的相关信息,最后的输出信息如下图所示。作业的结果会输出在指定的 output 文件夹中,通过命令 cat ./output/* 查看结果,符合正则的单词 dfsadmin 出现了1次:
[10:57:58][hadoop@ocean-lab hadoop-2.6.0]$ cat ./ouput/*
1 dfsadmin
注意,Hadoop 默认不会覆盖结果文件,因此再次运行上面实例会提示出错,需要先将 ./output 删除。
否则会报如下错误
INFO jvm.JvmMetrics: Cannot initialize JVM Metrics with processName=JobTracker, sessionId= - already initialized
org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory file:/usr/local/hadoop-2.6.0/ouput already exists
若出现提示 “INFO metrics.MetricsUtil: Unable to obtain hostName java.net.UnknowHostException”,这需要执行如下命令修改 hosts 文件,为你的主机名增加IP映射:
# cat /etc/hosts| grep ocean-lab
192.168.9.70 ocean-lab.ocean.org ocean-lab
伪分布式模式的操作方法
Hadoop可以在单节点上以所谓的伪分布式模式运行,此时每一个Hadoop守护进程都作为一个独立的Java进程运行。
节点既作为 NameNode 也作为 DataNode,同时,读取的是 HDFS 中的文件。
在设置 Hadoop 伪分布式配置前,我们还需要设置 HADOOP 环境变量,执行如下命令在 ~/.bashrc 中设置
# Hadoop Environment Variables
export HADOOP_HOME=/usr/local/hadoop-2.6.0
export HADOOP_INSTALL=$HADOOP_HOME
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin
source ~/.bashrc
配置
使用如下的 etc/hadoop/core-site.xml
<configuration>
<property>
<name>hadoop.tmp.dir</name>
<value>file:/usr/local/hadoop-2.6.0/tmp</value>
<description>Abase for other temporary directories.</description>
</property>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
</configuration>
同样的,修改配置文件 hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/usr/local/hadoop-2.6.0/tmp/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/usr/local/hadoop-2.6.0/tmp/dfs/data</value>
</property>
</configuration>
关于Hadoop配置项的一点说明
虽 然只需要配置 fs.defaultFS 和 dfs.replication 就可以运行(官方教程如此),不过若没有配置 hadoop.tmp.dir 参数,则默认使用的临时目录为 /tmp/hadoo-hadoop,而这个目录在重启时有可能被系统清理掉,导致必须重新执行 format 才行。所以我们进行了设置,同时也指定 dfs.namenode.name.dir 和 dfs.datanode.data.dir,否则在接下来的步骤中可能会出错。
免密码ssh设置
现在确认能否不输入口令就用ssh登录localhost:
# ssh localhost date
如果不输入口令就无法用ssh登陆localhost,执行下面的命令:
# ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
# cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
#chmod 600 ~/.ssh/authorized_keys
格式化一个新的分布式文件系统:
$ bin/hadoop namenode -format
15/12/23 11:30:20 INFO util.GSet: VM type = 64-bit
15/12/23 11:30:20 INFO util.GSet: 0.029999999329447746% max memory 966.7 MB = 297.0 KB
15/12/23 11:30:20 INFO util.GSet: capacity = 2^15 = 32768 entries
15/12/23 11:30:20 INFO namenode.NNConf: ACLs enabled? false
15/12/23 11:30:20 INFO namenode.NNConf: XAttrs enabled? true
15/12/23 11:30:20 INFO namenode.NNConf: Maximum size of an xattr: 16384
15/12/23 11:30:20 INFO namenode.FSImage: Allocated new BlockPoolId: BP-823870322-192.168.9.70-1450841420347
15/12/23 11:30:20 INFO common.Storage: Storage directory /usr/local/hadoop-2.6.0/tmp/dfs/name has been successfully formatted.
15/12/23 11:30:20 INFO namenode.NNStorageRetentionManager: Going to retain 1 images with txid >= 0
15/12/23 11:30:20 INFO util.ExitUtil: Exiting with status 0
15/12/23 11:30:20 INFO namenode.NameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at ocean-lab.ocean.org/192.168.9.70
************************************************************/
成功的话,会看到 “successfully formatted” 和 “Exitting with status 0″ 的提示
注意
下次启动 hadoop 时,无需进行 NameNode 的初始化,只需要运行 ./sbin/start-dfs.sh 就可以!
启动 NameNode 和 DataNode
$ ./sbin/start-dfs.sh
15/12/23 11:37:20 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Starting namenodes on [localhost]
localhost: starting namenode, logging to /usr/local/hadoop-2.6.0/logs/hadoop-hadoop-namenode-ocean-lab.ocean.org.out
localhost: starting datanode, logging to /usr/local/hadoop-2.6.0/logs/hadoop-hadoop-datanode-ocean-lab.ocean.org.out
Starting secondary namenodes [0.0.0.0]
The authenticity of host '0.0.0.0 (0.0.0.0)' can't be established.
RSA key fingerprint is a5:26:42:a0:5f:da:a2:88:52:04:9c:7f:8d:6a:98:9b.
Are you sure you want to continue connecting (yes/no)? yes
0.0.0.0: Warning: Permanently added '0.0.0.0' (RSA) to the list of known hosts.
0.0.0.0: starting secondarynamenode, logging to /usr/local/hadoop-2.6.0/logs/hadoop-hadoop-secondarynamenode-ocean-lab.ocean.org.out
15/12/23 11:37:44 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
[13:57:08][hadoop@ocean-lab hadoop-2.6.0]$ jps
27686 SecondaryNameNode
28455 Jps
27501 DataNode
27405 NameNode
27006 GetConf
如果没有进程则说明启动失败 查看日志bebug
成功启动后,可以访问 Web 界面 http://[ip,fqdn]:/50070 查看 NameNode 和 Datanode 信息,还可以在线查看 HDFS 中的文件。
上面的单机模式,grep 例子读取的是本地数据,伪分布式读取的则是 HDFS 上的数据。
要使用 HDFS,首先需要在 HDFS 中创建用户目录:
# ./bin/hdfs dfs -mkdir -p /user/hadoop
# ./bin/hadoop fs -ls /user/hadoop
Found 1 items
drwxr-xr-x - hadoop supergroup 0 2015-12-23 15:03 /user/hadoop/input
接着将 ./etc/hadoop 中的 xml 文件作为输入文件复制到分布式文件系统中,即将 /usr/local/hadoop/etc/hadoop 复制到分布式文件系统中的 /user/hadoop/input 中。我们使用的是 hadoop 用户,并且已创建相应的用户目录 /user/hadoop ,因此在命令中就可以使用相对路径如 input,其对应的绝对路径就是 /user/hadoop/input:
# ./bin/hdfs dfs -mkdir input
# ./bin/hdfs dfs -put ./etc/hadoop/*.xml input
复制完成后,可以通过如下命令查看 HDFS 中的文件列表:
# ./bin/hdfs dfs -ls input
-rw-r--r-- 1 hadoop supergroup 4436 2015-12-23 16:46 input/capacity-scheduler.xml
-rw-r--r-- 1 hadoop supergroup 1180 2015-12-23 16:46 input/core-site.xml
-rw-r--r-- 1 hadoop supergroup 9683 2015-12-23 16:46 input/hadoop-policy.xml
-rw-r--r-- 1 hadoop supergroup 1136 2015-12-23 16:46 input/hdfs-site.xml
-rw-r--r-- 1 hadoop supergroup 620 2015-12-23 16:46 input/httpfs-site.xml
-rw-r--r-- 1 hadoop supergroup 3523 2015-12-23 16:46 input/kms-acls.xml
-rw-r--r-- 1 hadoop supergroup 5511 2015-12-23 16:46 input/kms-site.xml
-rw-r--r-- 1 hadoop supergroup 858 2015-12-23 16:46 input/mapred-site.xml
-rw-r--r-- 1 hadoop supergroup 690 2015-12-23 16:46 input/yarn-site.xml
伪分布式运行 MapReduce 作业的方式跟单机模式相同,区别在于伪分布式读取的是HDFS中的文件(可以将单机步骤中创建的本地 input 文件夹,输出结果 output 文件夹都删掉来验证这一点)。
# ./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0.jar grep input output 'dfs[a-z.]+'
查看运行结果的命令(查看的是位于 HDFS 中的输出结果):
$ ./bin/hdfs dfs -cat output/*
1 dfsadmin
1 dfs.replication
1 dfs.namenode.name.dir
1 dfs.datanode.data.dir
结果如下,注意到刚才我们已经更改了配置文件,所以运行结果不同。
Hadoop伪分布式运行grep的结果Hadoop伪分布式运行grep的结果
我们也可以将运行结果取回到本地:
# rm -r ./output # 先删除本地的 output 文件夹(如果存在)
# ./bin/hdfs dfs -get output ./output # 将 HDFS 上的 output 文件夹拷贝到本机
# cat ./output/*
1 dfsadmin
1 dfs.replication
1 dfs.namenode.name.dir
1 dfs.datanode.data.dir
Hadoop 运行程序时,输出目录不能存在,否则会提示错误 “org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory hdfs://localhost:9000/user/hadoop/output already exists” ,因此若要再次执行,需要执行如下命令删除 output 文件夹:
# 删除 output 文件夹
$./bin/hdfs dfs -rm -r output
Deleted output
运行程序时,输出目录不能存在
运行 Hadoop 程序时,为了防止覆盖结果,程序指定的输出目录(如 output)不能存在,否则会提示错误,因此运行前需要先删除输出目录。在实际开发应用程序时,可考虑在程序中加上如下代码,能在每次运行时自动删除输出目录,避免繁琐的命令行操作:
Configuration conf = new Configuration();
Job job = new Job(conf);
/* 删除输出目录 */
Path outputPath = new Path(args[1]);
outputPath.getFileSystem(conf).delete(outputPath, true);
若要关闭 Hadoop,则运行
./sbin/stop-dfs.sh
启动YARN
(伪分布式不启动 YARN 也可以,一般不会影响程序执行)
有的读者可能会疑惑,怎么启动 Hadoop 后,见不到书上所说的 JobTracker 和 TaskTracker,这是因为新版的 Hadoop 使用了新的 MapReduce 框架(MapReduce V2,也称为 YARN,Yet Another Resource Negotiator)。
YARN 是从 MapReduce 中分离出来的,负责资源管理与任务调度。YARN 运行于 MapReduce 之上,提供了高可用性、高扩展性,YARN 的更多介绍在此不展开,有兴趣的可查阅相关资料。
上述通过 ./sbin/start-dfs.sh 启动 Hadoop,仅仅是启动了 MapReduce 环境,我们可以启动 YARN ,让 YARN 来负责资源管理与任务调度。
首先修改配置文件 mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
接着修改配置文件 yarn-site.xml:
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
然后就可以启动 YARN 了(需要先执行过 ./sbin/start-dfs.sh):
# ./sbin/start-yarn.sh # 启动YARN
# ./sbin/mr-jobhistory-daemon.sh start historyserver # 开启历史服务器,才能在Web中查看任务运行情况
开启后通过 jps 查看,可以看到多了 NodeManager 和 ResourceManager 两个后台进程:
[09:18:34][hadoop@ocean-lab ~]$ jps
27686 SecondaryNameNode
6968 ResourceManager
7305 Jps
7066 NodeManager
27501 DataNode
27405 NameNode
启动 YARN 之后,运行实例的方法还是一样的,仅仅是资源管理方式、任务调度不同。观察日志信息可以发现,不启用 YARN 时,是 “mapred.LocalJobRunner” 在跑任务,启用 YARN 之后,是 “mapred.YARNRunner” 在跑任务。启动 YARN 有个好处是可以通过 Web 界面查看任务的运行情况:http://[ip,fqdn]:8088/cluster
开启YARN后可以查看任务运行信息开启YARN后可以查看任务运行信息
但 YARN 主要是为集群提供更好的资源管理与任务调度,然而这在单机上体现不出价值,反而会使程序跑得稍慢些。因此在单机上是否开启 YARN 就看实际情况了。
不启动 YARN 需删掉/重命名 mapred-site.xml
否则在该配置文件存在,而未开启 YARN 的情况下,运行程序会提示 “Retrying connect to server: 0.0.0.0/0.0.0.0:8032″ 的错误。
同样的,关闭 YARN 的脚本如下:
# ./sbin/stop-yarn.sh
# ./sbin/mr-jobhistory-daemon.sh stop historyserver
hadoop 常用命令
# 查看HDFS文件列表
hadoop fs -ls /usr/local/log/
# 创建文件目录
hadoop fs -mkdir /usr/local/log/test
# 删除文件
/hadoop fs -rm /usr/local/log/07
# 上传一个本机文件到HDFS中/usr/local/log/目录下
adoop fs -put /usr/local/src/infobright-4.0.6-0-x86_64-ice.rpm /usr/local/log/
# 下载
hadoop fs �Cget /usr/local/log/infobright-4.0.6-0-x86_64-ice.rpm /usr/local/src/
# 查看文件
hadoop fs -cat /usr/local/log/zabbix/access.log.zabbix
# 查看HDFS基本使用情况
# hadoop dfsadmin -report
DEPRECATED: Use of this script to execute hdfs command is deprecated.
Instead use the hdfs command for it.
Configured Capacity: 29565767680 (27.54 GB)
Present Capacity: 17956433920 (16.72 GB)
DFS Remaining: 17956405248 (16.72 GB)
DFS Used: 28672 (28 KB)
DFS Used%: 0.00%
Under replicated blocks: 0
Blocks with corrupt replicas: 0
Missing blocks: 0
-------------------------------------------------
Live datanodes (1):
Name: 127.0.0.1:50010 (localhost)
Hostname: ocean-lab.ocean.org
Decommission Status : Normal
Configured Capacity: 29565767680 (27.54 GB)
DFS Used: 28672 (28 KB)
Non DFS Used: 11609333760 (10.81 GB)
DFS Remaining: 17956405248 (16.72 GB)
DFS Used%: 0.00%
DFS Remaining%: 60.73%
Configured Cache Capacity: 0 (0 B)
Cache Used: 0 (0 B)
Cache Remaining: 0 (0 B)
Cache Used%: 100.00%
Cache Remaining%: 0.00%
Xceivers: 1
Last contact: Thu Dec 24 09:52:14 CST 2015
自此,你已经掌握 Hadoop 的配置和基本使用了。