大数据(1):Hadoop 搭建
一、什么是 Hadoop
Hadoop 起源于 Apache Nutch 项目,始于 2002 年。Nutch 的设计目标是构建一个大型的全网搜索引擎,包括网页抓取、索引、查询等功能,但随着抓取网页数量的增加,遇到了严重的可扩展性问题——如何解决数十亿网页的存储和索引问题。2003 年发表 GFS 相关论文,用于处理海量网页的存储。
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 月被分离出来,成为一套完整而独立的软件,并被命名为 Hadoop。
那今天的 Hadoop 到底是什么呢?
官方语言:
Hadoop 是 Apache 旗下一款 reliable、scalable 的分布式计算开源软件。用 Java 语言实现开源软件框架,实现在大量计算机组成的集群中对海量数据进行分布式计算。
它允许使用简单的编程模型,跨计算机集群分布式处理大型数据集。它被设计成从单个服务器扩展到数千台机器,每台机器都提供本地计算和存储。
说人话:
把一个人干不动的活,分给多个人。就像打仗,1 个人肯定打不下某个国家,所以就召集很多人,组成军队,再来进攻。
对应到 Hadoop 中,也就是,最终集群 (军队) 的能力,还是依赖于每台主机 (士兵) 的计算能力和存储能力。军队的强大要落实到每个士兵。
Hadoop 本身不依赖硬件来提供高可用性,而是设计用于检测和处理应用程序层的故障,因此在计算机集群上提供高可用性服务,每个集群都可能容易出现故障。
Hadoop 主要由以下模块组成:
- Hadoop Common: The common utilities that support the other Hadoop modules.
- Hadoop Distributed File System (HDFS): A distributed file system that provides high-throughput access to application data.
- Hadoop YARN: A framework for job scheduling and cluster resource management.
- Hadoop MapReduce: A YARN-based system for parallel processing of large data sets.
Hadoop 介绍就不多说,先用起来,在使用的过程中再去详细了解。
二、安装 Hadoop
使用的操作系统是 Centos 7。使用普通用户登录操作。由于 Hadoop 是用 Java 开发的,所以首先应该安装 JDK,由于 Hadoop 3.x 只支持 JDK 1.8+,所以我们安装 JDK 1.8。可以在 Oracle 官网 下载 JDK,下载后,解压,在 /etc/profile
中配置环境变量就可以了,如下:
export JAVA_HOME=/soft/jdk
exprot PATH=$PATH:$JAVA_HOME/bin
然后安装 Hadoop,与 JDK 安装方法类似,在 Apache 官网 下载 Hadoop。下载后,解压,在 /etc/profile
中配置环境变量就可以了:
export HADOOP_HOME=/soft/hadoop
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
使用 hadoop version
查看版本信息。
$ hadoop version
Hadoop 3.2.1
Source code repository https://gitbox.apache.org/repos/asf/hadoop.git -r b3cbbb467e22ea829b3808f4b7b01d07e0bf3842
Compiled by rohithsharmaks on 2019-09-10T15:56Z
Compiled with protoc 2.5.0
From source with checksum 776eaf9eee9c0ffc370bcbc1888737
This command was run using /soft/hadoop-3.2.1/share/hadoop/common/hadoop-common-3.2.1.jar
至此为止,Hadoop 已经安装完毕。够简单吧。现在我们可以选择以下 3 种模式之一启动集群。
- Local (Standalone) Mode:本地 (独立) 模式
- Pseudo-Distributed Mode:伪分布模式
- Fully-Distributed Mode:完全分布式
三、 Local (Standalone) Mode
进入 ${HADOOP}/bin
目录,其中有 hdfs
脚本,直接输入 hdfs
命令,即可查看该脚本的帮助。由于配置了环境变量,所以不用进入该目录,直接输入命令也可以。我们先列出当前文件系统的根目录:
$ hdfs dfs -ls /
打印结果会是当前操作系统的根目录,也就是说本地模式使用的是当前的操作系统。也就是说本地模式下,不需要启动 Hadoop 进程。
四、Pseudo-Distributed Mode
伪分布模式下,Hadoop 的所有进程都在本机上运行。并且还需要在
${HADOOP_HOME}/etc/hadoop
目录下,配置以下文件。
在 core-site.xml 文件中加入以下配置:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<!-- 配置默认文件系统为本机localhost -->
<name>fs.defaultFS</name>
<value>hdfs://localhost</value>
</property>
</configuration>
在 hdfs-site.xml 文件中配置:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<!-- 配置副本数量为1 -->
<name>dfs.replication</name>
<value>1</value>
</property>
</configuration>
在 mapred-site.xml 文件中配置:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<!-- 配置MapReduce的框架为yarn -->
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>yarn.app.mapreduce.am.env</name>
<value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
</property>
<property>
<name>mapreduce.map.env</name>
<value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
</property>
<property>
<name>mapreduce.reduce.env</name>
<value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
</property>
</configuration>
在 yarn-site.xml 文件中配置:
<configuration>
<property>
<!-- 配置yarn资源管理节点为本机localhost -->
<name>yarn.resourcemanager.hostname</name>
<value>localhost</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
在 hadoop-env.sh 文件中配置:
export JAVA_HOME=/soft/jdk
在这几个文件配置完成后,还需要进行 SSH 配置。
这是由于伪分布模式的工作原理与完全分布式是相同的,只是伪分布式下,Hadoop 的所有进程运行在同一台主机上;而完全分布式时,运行在不同主机上。
若我们使用的是完全分布式,需要启动远程主机上的进程,需要通过 SSH 登录到远程主机启动进程,在集群规模较大时,不可能通过手动输入密码登录,因此需要配置 SSH 无密登录。
通过非对称加密,生成公、私秘钥对,将公钥发给需要登录的节点,这样就做到无密登录。
首先,生成公、私秘钥对,使用 ssh-keygen
命令,通过 rsa 加密算法,将公私秘钥保存在 ~/.ssh/id_rsa
中:
$ ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
可以看到目录 ~/.ssh
里面有 id_rsa (私钥) 和 id_rsa.pub (公钥)。
当前处于伪分布模式下,也就是需要登录本机,所以应该把公钥追加到本机的 ~/.ssh/authorized_keys
文件中:
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
修改 authorized_keys 文件权限
$ chmod 600 ~/.ssh/authorized_keys
终于,激动人心的时刻到了,可以启动集群了:
$ start-all.sh
启动完成后,打开 http://localhost:9870
,如果出现下图界面,恭喜,说明 HDFS 启动成功了。
再打开 http://localhost:8088
,如果出现下图界面,说明 YARN 启动成功。
五、Fully-Distributed Mode
完全分布式与伪分布式的工作原理完全相同,只是在完全分布式时,Hadoop 的不同的进程分配至不同主机,每台主机各司其职。
为了让伪分布式和完全分布式模式共存,我们可以复制
${HADOOP_HOME}/etc/hadoop
文件夹分别为 pseudo 和 full,然后再创建 hadoop
符号链接。当我们需要伪分布式时,将符号链接指向 pseudo,当需要完全分布式时,将符号链接指向 full。
$ cd /soft/hadoop/etc
$ cp -r hadoop pseudo
$ cp -r hadoop full
$ rm -rf hadoop
$ ln -s full hadoop
$ ll
drwxr-xr-x 3 user user 4096 May 7 17:48 full
lrwxrwxrwx 1 user user 4 May 7 17:49 hadoop -> full
drwxr-xr-x 3 user user 4096 May 7 17:48 pseudo
完全分布式下,需要多台服务器,这里使用 4 台虚拟机,分别命名为 s201 ~ s204,其中 s201 是我们主要操作的主机,通过 s201 去操作 s202 ~ s204。就是说把 s201 作为 master 节点,s202 ~ s204 作为 worker 节点。具体操作如下:
- 修改
/etc/hostname
文件为当前主机名。例如当前主机是 s201 则编辑/etc/hostname
中的内容为 s201。 - 配置 IP,配置
/etc/sysconfig/network-scripts/ifcfg-ethxxxx
中的 IPADDR 为静态 IP。 - 修改
/etc/hosts
如下,:
127.0.0.1 localhost
192.168.xxx.201 s201
192.168.xxx.202 s202
192.168.xxx.203 s203
192.168.xxx.204 s204
- 重启网络服务:
$ sudo service network restart
。
注意:以上 4 步操作需要在每台服务器上都执行。
为了能让 s201 免密登录到 s202 ~ s204,应将 s201 的公钥文件 id_rsa.pub 内容复制到 s201 ~ s204 主机的 authorized_keys 文件中。
$ scp id_rsa.pub user@s201:/home/user/.ssh/authorized_keys
$ scp id_rsa.pub user@s202:/home/user/.ssh/authorized_keys
$ scp id_rsa.pub user@s203:/home/user/.ssh/authorized_keys
$ scp id_rsa.pub user@s204:/home/user/.ssh/authorized_keys
接下来,修改 ${HADOOP_HOME}/etc/hadoop
目录下的文件。
编辑 core-site.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://s201</value>
</property>
<!--- 配置数据存放目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/home/data/hadoop</value>
</property>
</configuration>
编辑 hdfs-site.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
</configuration>
编辑 yarn-site.xml 文件:
<?xml version="1.0"?>
<configuration>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>s201</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
编辑 workers 文件:
s202
s203
s204
配置完成之后,将整个 ${HADOOP_HOME}
目录复制到 s202 ~ s204,然后在 s201 上格式化文件系统,重启 Hadoop 进程即可:
$ hadoop namenode -format
$ start-all.sh
如果在 http://s201:9870
中,出现了 3 个数据节点,说明 HDFS 启动成功:
如果在 http://s201:8088
中,也出现了 3 个节点,说明 YARN 启动成功:
六、啥?启动失败了?
至此,Hadoop 的两大主要模块 HDFS 和 YARN 已经启动完成。不过理想是美好的,现实是残酷的,在实际过程中可能遇到各种各样的问题,比如防火墙阻拦,端口被占用等等,不可能一一列举,所以我们需要分析是哪些进程启动失败了。
使用 jps
查看当前有哪些进程是正常运行的。
$ jps
35138 NameNode
35574 ResourceManager
35670 NodeManager
35239 DataNode
35740 Jps
35374 SecondaryNameNode
其中,HDFS 相关的进程有 NameNode、DataNode、SecondaryNameNode,YARN 相关进程有 NodeManager、ResourceManager。
如果搭建的是完全分布式,那么不同的进程将在不同的主机上,在 master 节点有 NameNode、SecondaryNameNode、ResourceManager 进程,在每个 worker 节点运行 DataNode、NodeManager 进程。
现在,需要查看日志了,日志在 ${HADOOP_HOME}/logs
目录下。
如果 NameNode 启动失败,那么应该查看 hadoop-xxx-namenode-xxx.log
文件,如果 NodeManager 启动失败,那么应该查看 hadoop-xxx-nodemanager-xxx.log
文件。每个进程都有与之对应的日志文件,通过查看日志文件就能知道为什么启动失败,发现问题,解决问题。
在下一篇《大数据(2):Hadoop 启动进程》中将详细分析 Hadoop 具体启动方式。