Hadoop学习:简介、Ubuntu上安装配置与wordcount示例

前言

  这是我《高性能计算》这门课的作业。折腾了好久,一个前辈说“每个新手初次接触都会遇到问题”,所以这过程虽是曲折,还是比较有意义的,记录之,希望能帮到你。

Hadoop简介

概述

  Hadoop是Apache软件基金会旗下的一个开源的分布式计算平台。以Hadoop分布式文件系统(Hadoop Distributed File System, HDFS)和MapReduce(Google MapReduce的开源实现)为核心的Hadoop为用户提供了系统底层细节透明的分布式基础架构。
  HDFS的高容错性、高伸缩性等优点允许用户将Hadoop部署在低廉的硬件上,形成分布式系统;MapReduce分布式编程模型允许用户在不了解分布式底层细节的情况下开发并行应用程序。所以用户可以利用Hadoop轻松地组织计算机资源,从而搭建自己的分布式计算平台,并且可以充分利用集群的计算和存储能力,完成海量数据的处理。经过业界和学术界长达10多年的锤炼,目前Hadoop已经发布到2.7.2稳定版本。

Hadoop历史

  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的优势,基于Hadoop的应用已经遍地开花,尤其是在互联网领域。Yahoo!通过集群运行Hadoop,用以支持广告系统和Web搜索的研究;Facebook借助集群运行Hadoop来支持其数据分析和机器学习;Baidu则使用Hadoop进行搜索日志分析和网页数据挖掘工作;淘宝的Hadoop系统用于存储并处理电子商务交易的相关数据;中国移动研究院基于Hadoop的BigCloud系统对数据进行分析并对外提供服务。
  2008年2月,作为Hadoop最大贡献者的Yahoo!构建了当时规模最大的Hadoop应用。他们在2000个节点上面执行了超过1万个Hadoop虚拟机器来处理超过5PB的网页内容,分析大约1兆个网络连接之间的网页索引资料。这些网页索引资料压缩后超过300TB。Yahoo!正是基于这些为用户提供高质量的搜索服务。

Hadoop项目及其结构

  现在Hadoop已经发展成为包含很多项目的集合。虽然其核心内容是MapReduce和Hadoop分布式文件系统,但与Hadoop相关的Common、Avro、Chukwa、Hive、HBase等项目也是不可或缺的。它们提供了互补性服务或在核心层上提供更高层的服务。下图是Hadoop的项目结构图。




  下面将对Hadoop的各个关联项目进行更详细的介绍。
  1) Common: Common是为Hadoop其他子项目提供支持的常用工具,它主要包括FileSystem、RPC和串行化库。它们为在廉价硬件上搭建云计算环境提供基本的服务,并且会为运行在该平台上的软件提供所需的API。
  2) Avro: Avro是用于数据序列化的系统。它提供了丰富的数据结构类型、快速可压缩的二进制数据格式、存储持久性数据的文件集、远程调用RPC的功能和简单的动态语言集成功能。其中代码生成器既不需要读写文件数据,也不需要使用或实现RPC协议,它只是一个可选的对静态类型语言的实现。
  Avro系统依赖于模式(Schema),数据的读和写是在模式之下完成的。这样可与减少写入数据的开销,提高序列化的速度并缩减其大小;同时,也可以方便动态脚本语言的使用,因为数据连同其模式都是自描述的。
  在RPC中,Avro系统的客户端和服务端通过握手协议进行模式的交换,因此当客户端和服务端拥有彼此全部的模式时,不同模式下相同命名字段、丢失字段和附加字段等信息一致性问题就得到了很好的解决。
  3) MapReduce: MapReduce 是一种编程模型,用于大规模数据集(大于1TB)的并行运算。映射(Map)、化简(Reduce)的概念和它们的主要思想都是从函数式编程语言中借鉴而来的。它极大的方便了编程人员——即使在不了解分布式并行编程的情况下,也可以将自己的程序运行在分布式系统上。MapReduce在执行时先指定一个Map(映射)函数,把输入键值对映射成一组新的键值对,经过一定处理后交给Reduce,Reduce对相同key下的所有value进行处理后再输出键值对作为最终的结果。
  下图是MapReduce的任务处理流程图,它展示了MapReduce程序输入划分到不同的Map上、再将Map的结果合并到Reduce、然后进行处理的输出过程。

Hadoop学习:简介、Ubuntu上安装配置与wordcount示例_第1张图片

  4)HDFS: HDFS是一个分布式文件系统。因为HDFS具有高容错性(fault-tolerent)的特点,所以它可以设计部署在低廉的硬件上。它可以通过提供高吞吐率(high-throughput)来访问应用程序数据,适合那些有着超大数据集的应用程序。HDFS放宽了对可移植操作系统接口(POSIX,Portable Operating System Interface)的要求,这样可以实现以流的形式访问文件系统中的数据。HDFS原本是开源的Apache项目Nutch的基础结构,最后它却成为了Hadoop基础架构之一。
  以下几个方面是HDFS的设计目标:
  (a). 检测和快速恢复硬件故障。硬件故障是计算机常见问题。整个HDFS系统由数百甚至上千个存储数据文件的服务器组成。而如此之多的服务器则意味着高故障率,因此,故障的检测和快速自动恢复是HDFS的一个核心目标。
  (b). 流式的数据访问。HDFS使应用程序流式地访问它们的数据集。HDFS被设计成适合进行批量处理,而不是用户交互式访问。所以它重视数据吞吐量,而不是数据访问反应速度。
  (c). 简化一致性模型。大部分的HDFS程序对文件的操作需要一次写入,多次读取。一个文件一旦经过创建、写入、关闭就不需要修改了。这个假设简化了数据一致性问题和高吞吐量的数据访问问题。
  (d). 通信协议。所有的通信协议都是在TCP/IP协议之上的。一个客户端和明确配置了端口的名字节点(NameNode)建立连接之后,它和名字节点的协议便是客户端协议(Client Protocal)。数据节点(DataNode)和名字节点之间则用数据节点协议(DataNode Protocal)。
  5)Chukwa: Chukwa是开源的数据收集系统,用于监控和分析大型分布式系统的数据。Chukwa是在Hadoop的HDFS和MapReduce框架之上搭建的,它继承了Hadoop的可扩展性和健壮性。Chukwa通过HDFS来存储数据,并以来MapReduce任务处理数据。Chukwa中也附带了灵活且强大的工具,用于显示、监视和分析数据结果,以便更好地利用所收集的数据。
  6)Hive: Hive最早是由Facebook设计的,是一个建立在Hadoop基础上的数据仓库,它提供了一些用于对Hadoop文件中的数据集进行数据整理、特殊查询和分析存储的工具。Hive提供的是一种结构化数据的机制,它类似于传统RDBMS中的SQL语言的查询语言,来帮助那些熟悉SQL的用户查询Hadoop中的数据,该查询语言称为Hive QL。与此同时,传统的MapReduce编程人员也可以在Mapper或Reducer中通过Hive QL查询数据。Hive编译器会把Hive QL编译成一组MapReduce任务,从而方便MapReduce编程人员进行Hadoop系统开发。
  7)HBase: HBase是一个分布式的,面向列的开源数据库,该技术来源于Google论文 Bigtable: A Distributed Storage System for Structured Data 。如同BigTable利用了Google的Google File System提供的分布式数据存储方式一样,HBase在Hadoop之上提供了类似于BigTable的能力。HBase不同于一般的关系数据库,原因有两个:其一,HBase是一个适合于非结构化数据存储的数据库;其二,HBase是基于列而不是基于行的模式。HBase和BigTable使用相同的数据模型。用户将数据存储在一个表里,一个数据行拥有一个可选择的键和任意数量的列。由于HBase表是疏松的,用户可以为行为定义各种不同的列。HBase主要用于需要随机访问、实时读写的大数据。
  8)Pig: Pig是一个对大型数据集进行分析、评估的平台。Pig的优势是它的结构能够经受住高度并行化的检验,这个特性使得它能够处理大型的数据集。目前,Pig的底层有一个编译器组成,它在运行的时候会产生一些MapReduce程序序列,Pig的语言层由一种叫做Pig Latin的正文型语言组成。
  9)ZooKeeper: ZooKeeper是一个为分布式应用所设计的开源协调服务。它主要为用户提供同步、配置管理、分组和命名服务,减轻分布式应用程序所承担的协调任务。ZooKeeper的文件系统使用目录树结构。支持java与C两种语言。

Hadoop体系结构

  如上文所说,HDFS和MapReduce是Hadoop的两大核心。而整个Hadoop的体系结构主要通过HDFS来实现分布式存储的底层支持的。并且它会通过MapReduce来实现分布式并行任务处理的程序支持。
  下面首先介绍HDFS的体系结构。HDFS采用了主从(Master/Slave)结构模型,一个HDFS集群是由一个NameNode和若干个DataNode组成的。其中NameNode作为主服务器,管理文件系统的命名空间和客户端对文件的访问操作;集群中的DataNode管理存储的数据。HDFS允许用户以文件的形式存储数据。从内部来看,文件被分成若干个数据块,而且这若干个数据块存放在一组DataNode上。NameNode执行文件系统的命名空间操作,比如打开、关闭、重命名文件或目录等,它也负责数据块到具体DataNode的映射。DataNode负责处理文件系统客户端的文件读写请求,并在NameNode的统一调度下进行数据块的创建、删除和复制工作。如下图所示,HDFS的体系结构。


Hadoop学习:简介、Ubuntu上安装配置与wordcount示例_第2张图片

  NameNode和DataNode都可以在普通商用计算机上运行。这些计算机通常运行的是GNU/Linux操作系统。HDFS采用Java语言开发,因此任何支持Java的机器都可以部署NameNode和DataNode。一个典型的部署场景是集群中的一台机器运行一个NameNode实例,其他机器分别运行一个DataNode实例。当然,并不排除一台机器运行多个DataNode实例的情况。集群中单一NameNode的设计大大简化了系统的架构。NameNode是所有HDFS元数据的管理者,用户需要保存的数据不会经过NameNode,而是直接流向存储数据的DataNode。
  接下来介绍MapReduce的体系结构。MapReduce是一种并行编程模式,利用这种模式软件开发者可以轻松地编写出分布式并行程序。在Hadoop的体系结构中,MapReduce是一个简单易用的软件框架,基于它可以将任务分发到上千台商用机器组成的集群上,并以一种可靠容错的方式并行处理大量的数据集,实现Hadoop的并行处理功能。MapReduce框架是由一个单独运行在主节点的JobTracker和运行在每个集群从节点的TaskTracker共同组成的。主节点负责调度构成一个作业的所有任务,这些任务分布在不同的从节点上。主节点监控它们的执行情况,并且重新执行之前失败的任务;从节点仅负责由主节点指派的任务。当一个Job被提交时,JobTracker接收到提交作业和其他配置信息之后,就会将配置信息等分发给从节点,同时调度任务并监控TaskTracker的执行。
  HDFS和MapReduce共同组成了Hadoop分布式体系结构的核心。HDFS在集群上实现了分布式文件系统,MapReduce在集群上实现了分布式计算和任务处理。HDFS在MapReduce任务处理过程中提供了对文件操作和存储等的支持,MapReduce在HDFS的基础上实现了任务的分发、跟踪、执行等工作,并收集结果,二者相互作用,完成了Hadoop分布式集群的主要任务。

Hadoop在Ubuntu上的安装与配置

  安装配置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。

创建Hadoop用户hduser

$ 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用户下:


Hadoop学习:简介、Ubuntu上安装配置与wordcount示例_第3张图片

安装SSH、配置SSH无密码登陆

  集群、单节点模式都需要用到 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环境

  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相关:

Hadoop学习:简介、Ubuntu上安装配置与wordcount示例_第4张图片

安装 Hadoop 2.6.4与添加环境变量

  下载好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单机配置

  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 可以在单节点上以伪分布式的方式运行,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 中的文件。

Hadoop学习:简介、Ubuntu上安装配置与wordcount示例_第5张图片

运行Hadoop伪分布式实例:wordcount

准备工作

  伪分布式读取的是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 /***命令查看目录文件:

Hadoop学习:简介、Ubuntu上安装配置与wordcount示例_第6张图片
  可以看见,我的HDFS根目录下有三个文件: /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.jarWordCount所在的Jar包。
  wordcount是程序主类名。
  /input /output是输入、输出文件夹。


  Hadoop命令会启动一个JVM来运行这个MapReduce程序,并自动获得Hadoop的配置,同时把类的路径(及其依赖关系)加入到Hadoop的库中。
  以上就是Hadoop Job的运行记录,从这里可以看到,这个Job被赋予了一个ID号: job_local926689626,而且得知输入文件有两个( Total input paths to process : 2)。
  同时还可以了解map的输入输出记录: Map input records = 2Map output records=4,以及reduce输入输出记录。十分的详细。
Hadoop学习:简介、Ubuntu上安装配置与wordcount示例_第7张图片

查看最终运行结果

  查看HDFS上output目录内容,分别执行如下命令:

$ hadoop fs -ls /output

$ hadoop fs -cat /output/part-r-00000


  最终可以看见,Hadoop为1个,Hello有两个,World有1个,与 file1.txt、file2.txt内容一致。证明我们运行成功。

你可能感兴趣的:(Hadoop学习:简介、Ubuntu上安装配置与wordcount示例)