前言
俗话说,工欲善其事必先利其器。我们要学习Hadoop,首先得把环境装好。学习一门技术,一定要实践、实践、再实践。千万不要光看不练,否则过几天你就忘了。本章我们先把环境搭好,运行一些基本的示例程序。
Hadoop集群可以在三种模式下运行:
本地模式
,所有的组件运行在一个JVM进程中,主要用于调试伪分布式模式
,在一个节点上启动所有的组件,一般用于学习环境完全分布式模式
,在多个节点上启动相应的组件,通常用于生产环境
那么我们在学习阶段应该采用哪种模式呢?如果你的机器环境允许的话,建议还是直接使用完全分布式模式
来学习,能够更好的模拟生产环境。此外,一些故障问题只会在该模式下出现,在学习阶段出现的问题越多,对于你后续的成长进步就越大。不过在此我们对这三种模式都会进行演示。
环境准备
我们采用VMWare
搭建三个节点的虚拟机,操作系统使用CentOS 7
。创建好虚拟机后,分别设置主机名与IP地址,如下所示。
主机名 | IP地址 |
---|---|
hadoop01 | 192.168.100.11 |
hadoop02 | 192.168.100.12 |
hadoop03 | 192.168.100.13 |
设置完成后,别忘了在/etc/hosts
中配置主机名映射,使之能够互相ping
通。
在Hadoop的官网中,点击菜单栏中的Download,进入下载页面,下载hadoop-3.1.2
安装包。
在Oracle的官网中,下载jdk8u201
安装包。
关于JDK版本的选择,可以查看JDK版本兼容性。
最后,在三个节点上创建hadoop
用户,并将安装包上传到software
目录下。
1 | $ useradd hadoop |
将上传的jdk和hadoop安装包进行解压,并创建软连接,如图所示。
这里多说一句,为什么要创建
hadoop
用户,我直接在root
用户下搞,不也一样么?当然可以,没有任何问题,但是有几点建议要说明:
- 不建议使用
root
用户进行操作,因为你拥有所有的权限,操作的风险很高- 以后我们还会学习
Spark
、Kafka
、Flink
等框架,并且这些框架都要同时运行,你认为是全部使用一个用户来管理方便,还是使用独立的用户来操作合适呢- 在稍微有些规模的公司,集群的
root
权限都是不开放的,你可以申请sudo
权限,但是所有的操作都会被监控,稍微不注意就会有违规- 在实际的生产环境中,不同的服务也是在不同的用户下启动的,我们最好遵循这种约定
在$HADOOP_HOME/etc/hadoop/hadoop-env.sh
中设置JAVA_HOME。
1 | export JAVA_HOME=/home/hadoop/software/java |
这里就体现出了软连接的好处了,软连接是为了方便软件的维护和升级,比如后期想换一个JDK版本,只需要把软连接指向新的JDK目录就行了,其他服务无需任何改动。
本地模式
默认情况下,hadoop被配置为本地模式,不需要我们进行过多的配置,就能运行。
下面我们参照官方的例子,运行一个简单的示例程序。
1 | $ hostname |
上面的例子是运行一个hadoop自带的MapReduce程序,对输入的文件每一行进行正则表达式匹配,并将匹配到的结果输出到指定目录。
当你运行$ bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.2.jar
时,会显示所支持的其他例子,你也可以尝试运行其他例子。
伪分布式模式
伪分布式模式是在一个节点上运行hadoop的所有组件,下面我仍然以hadoop01节点为例,配置并运行伪分布式模式。
服务配置
配置$HADOOP_HOME/etc/hadoop/core-site.xml
,如下所示。
1 | <configuration> |
配置$HADOOP_HOME/etc/hadoop/hdfs-site.xml
,如下所示。
1 | <configuration> |
配置$HADOOP_HOME/etc/hadoop/mapred-site.xml
,如下所示。
1 | <configuration> |
配置$HADOOP_HOME/etc/hadoop/yarn-site.xml
,如下所示。
1 | <configuration> |
配置本机的免密登录,如下所示。
1 | $ ssh-keygen -t rsa |
配置完成后,使用ssh localhost
登录进行测试。
注意,暂且不用考虑这些配置的含义是什么,先照着配置下来,能把服务启动起来就行。
启动服务
伪分布式模式下,需要启动多个JVM进程,也就是我们后面要学习到的NameNode
、DataNode
、ResourceManager
、NodeManager
等,暂且不考虑这些角色的作用,先启动它们再说。
1 | $ bin/hadoop namenode -format |
命令执行完成后,我们可以通过jps
查看当前已启动的进程。
我们也可以打开浏览器,访问NameNode和ResourceManager的Web页面。
1 | http://hadoop01:9870/ |
测试
这次我们运行一个不同的MapReduce程序,统计文件中单词的个数。
创建一个文件,输入要统计的单词,例如我这里就创建一个words.txt
文件,文件内容如下。
1 | hadoop yarn spark mr |
将文件上传到HDFS。
1 | $ bin/hadoop fs -mkdir -p /test/input |
运行MapReduce程序。
1 | $ bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.2.jar wordcount /test/input /test/output |
查看执行结果。
1 | $ bin/hadoop fs -cat /test/output/* |
完全分布式模式
前面的两种模式都是在单个节点上进行的,完全分布式是指hadoop相关的组件在不同的节点启动,我们使用3个节点来完成环境搭建。
在完全分布式模式中,我们尽量将每一步都说明清楚,尽量使得大家在此过程中少出错。(本节的配置较多,请大家认真操作)
使用root
用户进行如下操作,注意三台节点都要进行此操作:
1 | $ mkdir /data |
使用hadoop
用户进行如下操作,注意三台节点都要进行此操作:
1 | $ ssh-keygen -t rsa |
服务配置
我们在hadoop01
节点上进行配置,然后将配置文件复制到剩余两个节点上。
配置$HADOOP_HOME/etc/hadoop/hadoop-env.sh
,如下所示。
1 | export JAVA_HOME=/home/hadoop/software/java |
注意,这里配置了HADOOP_PID_DIR
以及HADOOP_LOG_DIR
,用于指定日志文件以及PID文件的存放位置。
配置$HADOOP_HOME/etc/hadoop/core-site.xml
,如下所示。
1 | <configuration> |
配置说明:
fs.defaultFS
,设置NameNode的URI,客户端通过此地址与其进行通信hadoop.tmp.dir
,设置Hadoop数据存放的根目录fs.trash.interval
,开启回收站功能,数据被删除后会进行回收站,保留时间是1440分钟(24小时),该配置默认为0,即不开启回收站
配置$HADOOP_HOME/etc/hadoop/hdfs-site.xml
,如下所示。
1 | <configuration> |
配置说明:
dfs.replication
,指定HDFS文件的副本数量,这里我们配置为3,相当于一个文件会保存三份dfs.blocksize
,指定HDFS的块大小,HDFS会将上传的文件切分为块,存储到不同的节点上,这里指定块大小为256MB(如果不设置,默认为128MB),即一个1GB的文件会被切分为4块dfs.namenode.secondary.http-address
,设置SecondaryNameNode的HTTP地址与端口
配置$HADOOP_HOME/etc/hadoop/yarn-site.xml
,如下所示。
1 | <configuration> |
配置说明:
yarn.nodemanager.aux-services
,对于MapReduce程序设置的shuffle服务yarn.resourcemanager.hostname
,设置ResourceManager服务在哪台节点启动yarn.log-aggregation-enable
,是否要开启日志聚合服务,即保留提交到YARN程序的运行日志yarn.nodemanager.resource.memory-mb
,设置NodeManager最多能分配的物理内容大小,单位是MByarn.nodemanager.remote-app-log-dir
,设置日志聚合的目录yarn.log-aggregation.retain-seconds
,聚合日志的保留时间,单位是秒yarn.log-aggregation.retain-check-interval-seconds
,多久时间检查一次聚合的日志保留时间yarn.nodemanager.env-whitelist
,容器可以从NodeManager继承下来的环境变量
配置$HADOOP_HOME/etc/hadoop/mapred-site.xml
,如下所示。
1 | <configuration> |
配置说明:
mapreduce.framework.name
,设置运行MapReduce任务的框架mapreduce.jobhistory.address
,设置运行任务历史服务的节点即端口mapreduce.jobhistory.webapp.address
,设置任务历史服务的Web节点和端口mapreduce.map.memory.mb
,设置MapReduce任务中每个map任务可以申请的内存总数,单位为MBmapreduce.reduce.memory.mb
,设置MapReduce任务中每个reduce任务可以申请的内容总数,单位为MBmapreduce.application.classpath
,设置MapReduce应用的classpath
配置$HADOOP_HOME/etc/hadoop/workers
文件,如下所示:
1 | hadoop01 |
该文件中每行都是一个节点地址,用于执行启动脚本时,自动使用ssh
的方式登录到其他节点启动相关服务,这也是我们设置节点之间免密登录的原因。
配置就此完成,我们需要将配置复制到其他节点。
1 | $ pwd |
启动服务
在hadoop01
节点上,执行如下命令。
1 | $ pwd |
hadoop01节点进程如下所示。
在hadoop02
节点上,执行如下命令。
1 | $ sbin/start-yarn.sh |
hadoop02节点进程如下所示。
在hadoop03
节点上,执行如下命令。
1 | $ bin/mapred --daemon start historyserver |
hadoop03节点进程如下所示。
如果发现没有启动相应的进程,可以在$HADOOP_HOME/hadoop/logs
目录下查看相关日志,找出问题原因。
测试
本次测试我们仍然使用自带的MapReduce程序来完成,不过为了更加有乐趣,我们通过脚本来生成测试数据。
下面是生成测试数据的脚本。
1 |
|
脚本很简单,用户指定要生成的行数,就可以生成指定行数的随机单词,每行10个,可以通过以下的方式进行调用。
1 | $ sh generate.sh 100000 >> words1.txt |
我们生成了3个数据文件,每个文件中分别有十万行数据,每行数据10个单词。当然,生成数据的时间根据各人环境有所不同,你也可以生成少量的数据来进行测试,没有任何影响。
下面我们将生成后的数据上传到HDFS,并提交MapReduce程序来完成WordCount。
1 | $ bin/hadoop fs -mkdir -p /wordcount/input |
小结
本章介绍了hadoop的三种运行模式:本地模式、伪分布式模式以及完全分布式模式。并针对每种模式进行了环境搭建、服务配置以及测试。本章配置较多,稍微不留意就会出错,需要结合日志文件定位错误的原因。