这是我《高性能计算》这门课的作业。折腾了好久,一个前辈说“每个新手初次接触都会遇到问题”,所以这过程虽是曲折,还是比较有意义的,记录之,希望能帮到你。
Hadoop是Apache软件基金会旗下的一个开源的分布式计算平台。以Hadoop分布式文件系统(Hadoop Distributed File System, HDFS)和MapReduce(Google MapReduce的开源实现)为核心的Hadoop为用户提供了系统底层细节透明的分布式基础架构。
HDFS的高容错性、高伸缩性等优点允许用户将Hadoop部署在低廉的硬件上,形成分布式系统;MapReduce分布式编程模型允许用户在不了解分布式底层细节的情况下开发并行应用程序。所以用户可以利用Hadoop轻松地组织计算机资源,从而搭建自己的分布式计算平台,并且可以充分利用集群的计算和存储能力,完成海量数据的处理。经过业界和学术界长达10多年的锤炼,目前Hadoop已经发布到2.7.2稳定版本。
Hadoop的源头是Apache Nutch,该项目始于2002年,是Apache Lucene的子项目之一。2004年,Google在Operating System Design and Implementation(OSDI,“操作系统设计与实现”)会议上公开发表了题为MapReduce: Simplified Data Processing on Large Clusters的论文之后,受到启发的Doug Cutting等人开始尝试实现MapReduce计算框架,并将它与NDFS(Nutch Distributed File System)结合,用以支持Nutch引擎的主要算法。由于NDFS和MapReduce在Nutch引擎中有着良好的应用,所以它们于2006年2月被分离出来,成为一套完整而独立的软件。它被应用到包括Yahoo!在内的很多互联网公司。现在的Hadoop已经发展成为包含HDFS、MapReduce子项目,与Pig、ZooKeeper、Hive、HBase等项目相关的大型应用工程。
由于Hadoop的优势,基于Hadoop的应用已经遍地开花,尤其是在互联网领域。Yahoo!通过集群运行Hadoop,用以支持广告系统和Web搜索的研究;Facebook借助集群运行Hadoop来支持其数据分析和机器学习;Baidu则使用Hadoop进行搜索日志分析和网页数据挖掘工作;淘宝的Hadoop系统用于存储并处理电子商务交易的相关数据;中国移动研究院基于Hadoop的BigCloud系统对数据进行分析并对外提供服务。
2008年2月,作为Hadoop最大贡献者的Yahoo!构建了当时规模最大的Hadoop应用。他们在2000个节点上面执行了超过1万个Hadoop虚拟机器来处理超过5PB的网页内容,分析大约1兆个网络连接之间的网页索引资料。这些网页索引资料压缩后超过300TB。Yahoo!正是基于这些为用户提供高质量的搜索服务。
现在Hadoop已经发展成为包含很多项目的集合。虽然其核心内容是MapReduce和Hadoop分布式文件系统,但与Hadoop相关的Common、Avro、Chukwa、Hive、HBase等项目也是不可或缺的。它们提供了互补性服务或在核心层上提供更高层的服务。下图是Hadoop的项目结构图。
如上文所说,HDFS和MapReduce是Hadoop的两大核心。而整个Hadoop的体系结构主要通过HDFS来实现分布式存储的底层支持的。并且它会通过MapReduce来实现分布式并行任务处理的程序支持。
下面首先介绍HDFS的体系结构。HDFS采用了主从(Master/Slave)结构模型,一个HDFS集群是由一个NameNode和若干个DataNode组成的。其中NameNode作为主服务器,管理文件系统的命名空间和客户端对文件的访问操作;集群中的DataNode管理存储的数据。HDFS允许用户以文件的形式存储数据。从内部来看,文件被分成若干个数据块,而且这若干个数据块存放在一组DataNode上。NameNode执行文件系统的命名空间操作,比如打开、关闭、重命名文件或目录等,它也负责数据块到具体DataNode的映射。DataNode负责处理文件系统客户端的文件读写请求,并在NameNode的统一调度下进行数据块的创建、删除和复制工作。如下图所示,HDFS的体系结构。
安装配置Hadoop环境之前,先要知道Hadoop有三种运行模式:
1. 单机模式(standalone)
单机模式是Hadoop的默认模式。当首次解压Hadoop的源码包时,Hadoop无法了解硬件安装环境,便保守地选择了最小配置。在这种默认模式下所有3个XML文件均为空。当配置文件为空时,Hadoop会完全运行在本地。因为不需要与其他节点交互,单机模式就不使用HDFS,也不加载任何Hadoop的守护进程。该模式主要用于开发调试MapReduce程序的应用逻辑。
2. 伪分布模式(Pseudo-Distributed Mode)
伪分布模式在“单节点集群”上运行Hadoop,其中所有的守护进程都运行在同一台机器上。该模式在单机模式之上增加了代码调试功能,允许你检查内存使用情况,HDFS输入输出,以及其他的守护进程交互。
3. 全分布模式(Fully Distributed Mode)
Hadoop运行在一个集群上。
下面是我搭建Hadoop环境的过程。我安装的是单机模式与伪分布模式。
我用的是Ubuntu 14.04,64位操作系统。下载的Hadoop版本是2.6.4。
$ sudo useradd -m hduser -s /bin/bash
这条命令创建了可以登陆的 hduser 用户,并使用 /bin/bash 作为 shell。
接着使用如下命令设置密码,可简单设置为 hadoop,按提示输入两次密码:
$ sudo passwd hduser
接着,为 hadoop 用户增加管理员权限,方便部署:
$ sudo adduser hduser sudo
下面就可以用这个hduser
用户来登陆了,可以直接在当前用户的终端中切换到hduser
用户:
$ sudo su hduser
输入密码后,就进入了hduser
用户下:
集群、单节点模式都需要用到 SSH 登陆(类似于远程登陆,你可以登录某台 Linux 主机,并且在上面运行命令),Ubuntu 默认已安装了 SSH client,此外还需要安装 SSH server:
$ sudo apt-get install openssh-server
安装后,可以使用如下命令登陆本机:
$ ssh localhost
此时会有SSH首次登陆提示,输入 yes 。然后按提示输入密码,这样就登陆到本机了。
但这样登陆是需要每次输入密码的,若配置成SSH无密码登陆比较方便。首先退出刚才的 ssh,就回到了我们原先的终端窗口,然后利用 ssh-keygen 生成密钥,并将密钥加入到授权中:
$ exit # 退出刚才的 ssh localhost
$ cd ~/.ssh/ # 若没有该目录,请先执行一次ssh localhost
$ ssh-keygen -t rsa # 会有提示,都按回车就可以
$ cat ./id_rsa.pub >> ./authorized_keys # 加入授权
此时再用 ssh localhost 命令,无需输入密码就可以直接登陆了。
Java环境可选择 Oracle 的 JDK,或是 OpenJDK,按http://wiki.apache.org/hadoop/HadoopJavaVersions中说的,新版本在 OpenJDK 1.7 下是没问题的。我安装的是Oracle的Java 8:
$ sudo add-apt-repository ppa:webupd8team/java
$ sudo apt-get update # 更新资源列表
$ sudo apt-get install oracle-java8-installer
接着配置 JAVA_HOME 环境变量,我在~/.bashrc
中进行设置:
$ sudo vim ~/.bashrc
在文件最前面添加如下单独一行(=
号前后不能有空格):
export JAVA_HOME=/usr/lib/jvm/java-8-oracle
$ sudo vim ~/.bashrc
检查Java是否安装成功,与Java的环境变量是否正确配置:
$ echo &JAVA_HOME
$ java -version
显示如下则正确配置Java相关:
下载好2.6.4之后,就是安装了。我选择安装到/usr/local/
目录下:
$ sudo tar -zxf ~/Downloads/hadoop-2.6.4.tar.gz -C /usr/local # 解压到/usr/local中
$ cd /usr/local/
$ sudo mv ./hadoop-2.6.0/ ./hadoop # 将文件夹名改为hadoop
$ sudo chown -R hadoop ./hadoop # 修改文件权限
配置变量:在/usr/local/hadoop/etc/hadoop/hadoop-env.sh
文件中添加Java_Home
:
~/.bashrc
文件里,添加
HADOOP_HOME
环境变量:
#HADOOP VARIABLES START
export JAVA_HOME=/usr/lib/jvm/java-8-oracle
export HADOOP_INSTALL=/usr/local/hadoop
export PATH=$PATH:$HADOOP_INSTALL/bin
export PATH=$PATH:$HADOOP_INSTALL/sbin
export HADOOP_MAPRED_HOME=$HADOOP_INSTALL
export HADOOP_COMMON_HOME=$HADOOP_INSTALL
export HADOOP_HDFS_HOME=$HADOOP_INSTALL
export YARN_HOME=$HADOOP_INSTALL
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_INSTALL/lib/native
export HADOOP_OPTS="-Djava.library.path=$HADOOP_INSTALL/lib"
#HADOOP VARIABLES END
别忘了刷新更新使之生效:source ~/.bashrc
Hadoop 默认模式为非分布式模式,无需进行其他配置即可运行。非分布式即单 Java 进程,方便进行调试。现在我们可以执行例子来感受下 Hadoop 的运行。
Hadoop 附带了丰富的例子,运行:
$ /usr/local/hadoop/bin/hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0.jar
可以看到所有例子,包括 wordcount、terasort、join、grep 等:
Hadoop 可以在单节点上以伪分布式的方式运行,Hadoop 进程以分离的 Java 进程来运行,节点既作为 NameNode 也作为 DataNode,同时,读取的是 HDFS 中的文件。
Hadoop 的配置文件位于/usr/local/hadoop/etc/hadoop/
中,伪分布式需要修改2个配置文件 core-site.xml 和 hdfs-site.xml 。Hadoop的配置文件是 xml 格式,每个配置以声明 property 的 name 和 value 的方式来实现。
修改配置文件 core-site.xml ,通过 gedit 编辑会比较方便:
$ sudo gedit /usr/local/hadoop/etc/hadoop/core-site.xml
$ sudo gedit /usr/local/hadoop/etc/hadoop/hdfs-site.xml
修改如下:
<configuration>
+ <property>
+ <name>hadoop.tmp.dir</name>
+ <value>file:/usr/local/hadoop/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/tmp/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/usr/local/hadoop/tmp/dfs/data</value>
</property>
</configuration>
配置完成后,执行 NameNode 的格式化:
$ /usr/local/hadoop/bin/hdfs namenode -format
成功的话,会看到 “successfully formatted” 和 “Exitting with status 0” 的提示,若为 “Exitting with status 1” 则是出错。
接着开启 NameNode 和 DataNode 守护进程。
$ /sur/local/hadoop/sbin/start-dfs.sh #建议使用 or: $ /sur/local/hadoop/sbin/start-all.sh #deprecated,旧的方式
用jps
命令查看是否启动成功,显示如下,成功配置。如没有NameNode、DataNode,则没有配置成功,检查配置:
成功启动后,可以访问 Web 界面 http://localhost:50070 查看 NameNode 和 Datanode 信息,还可以在线查看 HDFS 中的文件。
伪分布式读取的是HDFS上的数据,要使用 HDFS,首先需要在 HDFS 中创建用户目录:
$ /usr/local/hadoop/bin/hadoop fs -mkdir /user/hduser
or:
$ /usr/local/hadoop/bin/hdfs dfs -mkdir /user/hduser
可以使用$ hadoop fs -ls /***
或者$ hdfs dfs -ls /***
命令查看目录文件:
/user、/input、/output
,
/input
下有两个待会儿实验要用的txt文件。这个文件是从本地上上传到HDFS中的,使用如下命令:
$ hadoop fs -put /***/***/file1.txt /input
或者
$ hdfs dfs -put /***/***/file1.txt /input
file1.txt, file2.txt
是我创建的两个实验文件:
file1.txt
文件内容为:Hello World
file2.txt
文件内容为:Hello Hadoop
下面就是运行wordcount实例了,根目录下的input
作为输入目录,output
目录作为输出目录。
$ /usr/local/hadoop/bin/hadoop jar /home/hduser/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.4.jar wordcount /input /output
/usr/local/hadoop/bin/hadoop/ jar
是指执行jar
命令。
/home/hduser/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.4.jar
是WordCount
所在的Jar
包。
wordcount
是程序主类名。
/input /output
是输入、输出文件夹。
查看HDFS上output目录内容,分别执行如下命令:
$ hadoop fs -ls /output
$ hadoop fs -cat /output/part-r-00000
file1.txt、file2.txt
内容一致。证明我们运行成功。