Hadoop 是一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。经过多年的发展,Hadoop 的含义已经超出 Hadoop 这个软件,还指代以 Hadoop 为基石的大数据生态圈,包括 Kafka、Zookeeper、Spark、Flink 等众多软件。
本文主要介绍 Apache 和 CDH 两个版本 Hadoop 的安装,安装形式包括虚拟机以及 Docker 环境。
概述
Hadoop 的框架核心的设计是 HDFS 和 MapReduce。HDFS 为海量的数据提供了存储,MapReduce 为海量的数据提供了计算。现在 Hadoop 生态圈中像 MapReduce 一样做数据处理计算的分布式并行计算框架还有很多,目前流行的有 Spark,Flink 等。
历史版本
0.x 版本:Hadoop 中最早的开源版本。
1.x 版本
HDFS:负责数据存储
- NameNode:主节点,管理元数据以及从节点 DataNode 的数据。
- SecondaryNameNode:帮助主节点 NameNode 进行元数据管理。
- DataNode:从节点,存储数据。
MapReduce:负责数据处理
- JobTracker:通过调度 TaskTracker 上运行的任务来协调所有运行在系统上的作业;记录每项作业任务的整体进度情况;如果其中一个任务失败,可以在另一个 TaskTracker 上重新调度该任务。
- TaskTracker:执行 JobTracker 分配的计算任务,在运行的同时将运行进度报告发送给 JobTracker。
2.x 版本
JDK 版本要求最低为 JDK7;解决 Hadoop1.x 存在的单点故障、内存限制约束等问题;引入了通用的资源调度框架 YARN;支持 Spark、Flink 等其他计算框架;拆分 JobTracker,减轻调度资源的负担。
HDFS:负责数据存储
- NameNode:主节点,可以有主备两个,分别处于 Active 和 StandBy 状态。
- DataNode:从节点,存储数据。
- ZKFC(Zookeeper Failover Controller):用于灾难备份,负责 NameNode 的主备切换。
- JournalNode:保证主备 NameNode 元数据的一致性,帮助主节点 NameNode 进行元数据管理。
注:JournalNode 只有在 HA 模式下存在,非 HA 模式启动的仍然是 SecondaryNameNode。
YARN:通用的资源调度框架
- ResourceManager:资源管理器,管理集群上资源的使用。
- NodeManager:节点管理器,运行在集群中所有节点上,能够启动和监控容器。
- ApplicationMaster:负责计算任务的监控与控制,由计算框架实现。
3.x版本
JDK 版本要求最低为 JDK8;使用 EC 纠错码技术保障数据完整,解决 HDFS 副本方式导致的存储空间翻倍问题;支持2个以上的 NameNode……
发行版本
Hadoop的三大发行版本:
- Apache版 :拥有全世界的开源贡献者,代码更新迭代版本比较快。版本的升级、维护、兼容性等方面可能考虑不周。
- HDP版 :HortonWorks 公司提供的发行版,通过 Ambari 管理平台提供一套直观的 WEB 界面,用于管理集群。该公司已与 Cloudera 合并。
- CDH版 :Cloudera 公司提供的发行版,通过公司内部的各种补丁及充分的测试,实现 Hadoop 与大数据生态圈的 其他软件 平稳运行,在兼容性、安全性、稳定性上有所增强,通过 Cloudera Manager 进行集群的软件分发及管理监控平台,推荐生产环境使用。
部署模式
Hadoop 有三种部署模式:
- 本地模式(Standalone):无守护进程,用户程序和 Hadoop 程序运行在同一个 Java 进程,使用本地文件系统而非分布式文件系统。一般用于本地调试。
- 伪分布式(Pseudo-Distributed):在单机上模拟集群模式,各守护进程运行在单独的 Java 进程中,使用的文件系统是 HDFS。一般用于学习和测试。
- 分布式(Fully-Distributed):守护进程运行在集群上,使用的文件系统是 HDFS。一般用于生产环境。
Apache版
Apache 版本的 Hadoop 在升级、维护、兼容性等方面可能会遇到很多问题,除非是积累了丰富经验的大厂,否则不推荐用于生产环境。 Apache Hadoop 文档
本地模式
该模式一般用于本地调试。
服务规划:
运行服务 | 服务器IP | 功能概述 |
---|---|---|
NameNode | 192.168.153.100 | 主节点,管理元数据以及从节点 DataNode 的数据 |
SecondaryNameNode | 192.168.153.100 | 帮助主节点 NameNode 进行元数据管理 |
DataNode | 192.168.153.100 | 从节点,存储数据 |
ResourceManager | 192.168.153.100 | 主节点,接收用户的计算任务,负责集群的资源分配 |
NodeManager | 192.168.153.100 | 从节点,执行主节点ApplicationMaster分配的任务 |
- 下载安装 Hadoop
1 | cd /export/softwares/ |
- 修改配置文件
修改core-site.xml
1 | <configuration> |
修改hdfs-site.xml
1 | <configuration> |
修改hadoop-env.sh
1 | export JAVA_HOME=/usr/java/jdk1.8.0_211 |
修改mapred-site.xml
1 | <configuration> |
修改yarn-site.xml
1 | <configuration> |
修改mapred-env.sh
1 | export JAVA_HOME=/export/servers/jdk1.8.0_211 |
修改slaves
1 | localhost |
- 启动
要启动 Hadoop,需要启动 HDFS 和 YARN 两个模块。
首次启动 HDFS 时,必须对其进行格式化操作。本质上是一些清理和准备工作,因为此时的 HDFS 在物理上还是不存在的。
1 | hdfs namenode -format |
创建数据存放文件夹:
1 | cd /export/servers/hadoop-2.7.5 |
启动服务:
1 | cd /export/servers/hadoop-2.7.5/ |
通过WEB界面查看Hadoop状态:
- 查看HDFS: http://node01:50070
- 查看YARN集群: http://node01:8088
- 查看历史任务: http://node01:19888/jobhistory
伪分布式
该模式一般用于学习测试开发集群模式。未验证
服务规划:
服务器IP | 主机名 | NameNode | SecondaryNameNode | dataNode | ResourceManager | NodeManager |
---|---|---|---|---|---|---|
192.168.153.100 | node01.hadoop.com | √ | √ | √ | √ | √ |
192.168.153.101 | node02.hadoop.com | √ | √ | |||
192.168.153.102 | node03.hadoop.com | √ | √ |
停止 node01 上的单节点集群:
1 | cd /export/servers/hadoop-2.7.5 |
删除hadoopDatas
文件夹后再重新创建:
1 | # 删除数据存放文件夹 |
修slaves
文件:
1 | node01 |
分发安装包:
1 | scp -r hadoop-2.7.5 node02:$PWD |
启动集群:
1 | cd /export/servers/hadoop-2.7.5 |
分布式
完全分布式,实现 NameNode 高可用,ResourceManager 高可用。未验证
服务规划:
- 停止之前的Hadoop集群的所有服务,并删除所有机器的hadoop安装包,然后重新解压hadoop压缩包。
1 | cd /export/softwares |
- 修改配置文件
修改core-site.xml
,官方文档
1 | <configuration> |
修改hdfs-site.xml
,官方文档
1 | <configuration> |
修改yarn-site.xml
,注意更改 node02 和 node03 中<value>rm1</value>
的值。官方文档
1 | <configuration> |
修改mapred-site.xml
,官方文档
1 | <configuration> |
修改slaves
1 | node01 |
修改hadoop-env.sh
1 | export JAVA_HOME=/usr/java/jdk1.8.0_211 |
修改mapred-env.sh
(?或无需修改)
1 | export JAVA_HOME=/export/servers/jdk1.8.0_211 |
- 创建数据存放文件夹,分发安装包
1 | # 创建数据存放文件夹 |
- 修改 node02 上
yarn-site.xml
的配置
1 | <property> |
- 启动HDFS
在 Zookeeper 集群启动的前提下
node01 执行以下命令:
1 | cd /export/servers/hadoop-2.7.5 |
node02 执行以下命令:
1 | cd /export/servers/hadoop-2.7.5 |
- 启动YARN
node02、node03 执行以下命令:
1 | /export/servers/hadoop-2.7.5/sbin/start-yarn.sh |
- 查看resourceManager状态
node03 执行以下命令:
1 | /export/servers/hadoop-2.7.5/bin/yarn rmadmin -getServiceState rm1 |
node02 执行以下命令:
1 | /export/servers/hadoop-2.7.5/bin/yarn rmadmin -getServiceState rm2 |
- 启动 JobHistory
node03 执行以下命令:
1 | /export/servers/hadoop-2.7.5/sbin/mr-jobhistory-daemon.sh start historyserver |
查看Hadoop状态:
- 查看HDFS: http://node01:50070 , http://node02:50070
- 查看YARN: http://node03:8088
- 查看历史任务: http://node03:19888/jobhistory
CDH版
CDH 版是 Cloudera 公司提供的发行版,通过公司内部的各种补丁及充分的测试,实现 Hadoop 与大数据生态圈的 其他组件 平稳运行,在兼容性、安全性、稳定性上有所增强。
Cloudera Manager 是用于管理 CDH 群集(Cluster)的应用程序,提供了良好的 Web UI 界面。借助 Cloudera Manager,可以轻松地部署和集中操作完整的 CDH 和其他托管服务,想要了解 Cloudera Manager 搭建大数据平台的方法可以参看 搭建CDH6大数据平台 。这里使用 Cloudera 提供的压缩包手动搭建,搭建过程和 Apache 版 Hadoop 类似,无需收费。
组件内容
说明一下 CDH 5.14.0 的组件内容:
Component | Package Version | Tarball | Release Notes | Changes File |
---|---|---|---|---|
Apache Avro | avro-1.7.6+cdh5.14.0+137 | Tarball | Release notes | Changes |
Apache Crunch | crunch-0.11.0+cdh5.14.0+103 | Tarball | Release notes | Changes |
Apache DataFu | pig-udf-datafu-1.1.0+cdh5.14.0+26 | Tarball | Release notes | Changes |
Apache Flume | flume-ng-1.7.0+cdh5.14.0+181 | Tarball | Release notes | Changes |
Apache Hadoop | hadoop-2.6.0+cdh5.14.0+2715 | Tarball | Release notes | Changes |
Apache Hadoop MRv1 | hadoop-0.20-mapreduce-2.6.0+cdh5.14.0+2715 | (none) | (none) | (none) |
Apache HBase | hbase-1.2.0+cdh5.14.0+440 | Tarball | Release notes | Changes |
Apache HBase-Solr | hbase-solr-1.5+cdh5.14.0+73 | Tarball | Release notes | Changes |
Apache Hive | hive-1.1.0+cdh5.14.0+1331 | Tarball | Release notes | Changes |
Hue | hue-3.9.0+cdh5.14.0+7830 | (none) | Release notes | Changes |
Apache Impala | impala-2.11.0+cdh5.14.0+0 | (none) | Release notes | Changes |
Kite SDK | kite-1.0.0+cdh5.14.0+146 | Tarball | Release notes | Changes |
Apache Kudu | kudu-1.6.0+cdh5.14.0+0 | (none) | Release notes | Changes |
Llama | llama-1.0.0+cdh5.14.0+0 | Tarball | Release notes | Changes |
Apache Mahout | mahout-0.9+cdh5.14.0+35 | Tarball | Release notes | Changes |
Apache Oozie | oozie-4.1.0+cdh5.14.0+473 | Tarball | Release notes | Changes |
Apache Parquet | parquet-1.5.0+cdh5.14.0+192 | Tarball | Release notes | Changes |
Parquet-format | parquet-format-2.1.0+cdh5.14.0+19 | Tarball | Release notes | Changes |
Apache Pig | pig-0.12.0+cdh5.14.0+112 | Tarball | Release notes | Changes |
Cloudera Search | search-1.0.0+cdh5.14.0+0 | Tarball | Release notes | Changes |
Apache Sentry | sentry-1.5.1+cdh5.14.0+432 | Tarball | Release notes | Changes |
Apache Solr | solr-4.10.3+cdh5.14.0+522 | (none) | Release notes | Changes |
Apache Spark | spark-1.6.0+cdh5.14.0+537 | Tarball | Release notes | Changes |
Apache Sqoop | sqoop-1.4.6+cdh5.14.0+127 | Tarball | Release notes | Changes |
Apache Sqoop2 | sqoop2-1.99.5+cdh5.14.0+47 | Tarball | Release notes | Changes |
Apache Whirr | whirr-0.9.0+cdh5.14.0+24 | Tarball | Release notes | Changes |
Apache ZooKeeper | zookeeper-3.4.5+cdh5.14.0+136 | Tarball | Release notes | Changes |
编译
由于 Cloudera 提供的 Hadoop 压缩包没有提供带 C 程序访问的接口,使用本地库(本地库可以提供对 Snappy 压缩的支持)会出问题,如果需要使用 Snappy 压缩需要自行编译。
配置编译环境
软件环境:Linux 系统使用 CentOS 6.9 x64;JDK 选择 JDK1.7.0_75,使用 JDK8 在编译时会报错。
修改系统环境:关闭防火墙和 Linux 内核的安全模组
1 | # 关闭防火墙 |
安装与配置 Maven:需要使用 maven3.x 以上的版本,建议使用 3.0.5。
解压安装 Maven:
1
tar -zxvf apache-maven-3.0.5-bin.tar.gz -C /export/servers/
配置 Maven 环境变量:
1
2
3
4
5
6
7$ vim /etc/profile
export MAVEN_HOME=/export/servers/apache-maven-3.0.5
export MAVEN_OPTS="-Xms4096m -Xmx4096m"
export PATH=:$MAVEN_HOME/bin:$PATH
# 让修改立即生效
$ source /etc/profile解压 Maven 仓库
1
tar -zxvf mvnrepository.tar.gz -C /export/servers/
修改 Maven 配置文件,指定仓库路径和阿里云镜像地址
/export/servers/apache-maven-3.0.5/conf/settings.xml 1
2
3
4
5
6
7
8
9
10<localRepository>/export/servers/mavenrepo</localRepository>
<mirrors>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>central</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
安装findbugs
- 下载 findbugs:
/export/softwares/ 1
wget --no-check-certificate https://sourceforge.net/projects/findbugs/files/findbugs/1.3.9/findbugs-1.3.9.tar.gz/download -O findbugs-1.3.9.tar.gz
- 解压安装 findbugs:
/export/softwares/ 1
tar -zxvf findbugs-1.3.9.tar.gz -C ../servers/
- 配置 findbugs 的环境变量:
1
2
3
4
5
6$ vim /etc/profile
export FINDBUGS_HOME=/export/servers/findbugs-1.3.9
export PATH=:$FINDBUGS_HOME/bin:$PATH
# 让修改立即生效
$ source /etc/profile
安装依赖:使用 yum 在线安装一些依赖包
1 | yum install autoconf automake libtool cmake |
安装protobuf:解压安装protobuf,并进行编译
1 | cd /export/softwares/ |
安装Snappy:解压安装Snappy,并进行编译
1 | cd /export/softwares/ |
开始编译
下载 CDH 版 Hadoop 源码,进行编译:
1 | # 下载Hadoop源码 |
编译后的压缩包位于 hadoop-2.6.0-cdh5.14.0/hadoop-dist/target/
。
编译常见错误
如果编译时候出现这个错误:
An Ant BuildException has occured: exec returned: 2
说明 Tomcat 压缩包下载失败,可以自行下载 apache-tomcat-6.0.53.tar.gz
放到以下两个路径下:
1 | /export/servers/hadoop-2.6.0-cdh5.14.0/hadoop-hdfs-project/hadoop-hdfs-httpfs/downloads/ |
伪分布式
使用 CDH 搭建伪分布式集群,服务规划如下:
安装
解压安装:
1 | tar -zxvf hadoop-2.6.0-cdh5.14.0.tar.gz -C /export/servers/ |
检查本地库支持
检查 Hadoop 本地库是否支持 Snappy 压缩:
1 | $ bin/hadoop checknative |
如果 openssl
显示为false,需要在所有机器上进行安装:
1 | yum -y install openssl-devel |
修改配置文件
修改
core-site.xml
:hadoop-2.6.0-cdh5.14.0/etc/hadoop/core-site.xml 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://node01:8020</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/tempDatas</value>
</property>
<!-- 缓冲区大小,实际工作中根据服务器性能动态调整 -->
<property>
<name>io.file.buffer.size</name>
<value>4096</value>
</property>
<!-- 开启hdfs的垃圾桶机制,删除掉的数据可以从垃圾桶中回收,单位分钟 -->
<property>
<name>fs.trash.interval</name>
<value>10080</value>
</property>
</configuration>修改
hdfs-site.xml
:hadoop-2.6.0-cdh5.14.0/etc/hadoop/hdfs-site.xml 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58<configuration>
<!-- NameNode存储元数据信息的路径,实际工作中,一般先确定磁盘的挂载目录,然后多个目录用,进行分割 -->
<!-- 集群动态上下线
<property>
<name>dfs.hosts</name>
<value>/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop/accept_host</value>
</property>
<property>
<name>dfs.hosts.exclude</name>
<value>/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop/deny_host</value>
</property>
-->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>node01:50090</value>
</property>
<property>
<name>dfs.namenode.http-address</name>
<value>node01:50070</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/namenodeDatas</value>
</property>
<!-- 定义dataNode数据存储的节点位置,实际工作中,一般先确定磁盘的挂载目录,然后多个目录用,进行分割 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/datanodeDatas</value>
</property>
<property>
<name>dfs.namenode.edits.dir</name>
<value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/dfs/nn/edits</value>
</property>
<property>
<name>dfs.namenode.checkpoint.dir</name>
<value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/dfs/snn/name</value>
</property>
<property>
<name>dfs.namenode.checkpoint.edits.dir</name>
<value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/dfs/nn/snn/edits</value>
</property>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
<property>
<name>dfs.blocksize</name>
<value>134217728</value>
</property>
</configuration>修改
hadoop-env.sh
:/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop/hadoop-env.sh 1
export JAVA_HOME=/usr/java/jdk1.8.0_211
修改
mapred-site.xml
:hadoop-2.6.0-cdh5.14.0/etc/hadoop/mapred-site.xml 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.job.ubertask.enable</name>
<value>true</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>node01:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>node01:19888</value>
</property>
</configuration>修改
yarn-site.xml
:hadoop-2.6.0-cdh5.14.0/etc/hadoop/yarn-site.xml 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<configuration>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>node01</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
</configuration>修改
slaves
:
1 | node01 |
创建目录
创建文件存放目录:
1 | mkdir -p /export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/tempDatas |
分发
分发安装包:
1 | scp -r hadoop-2.6.0-cdh5.14.0/ node02:$PWD |
配置环境变量
配置 Hadoop 的环境变量:
1 | export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin |
修改环境变量后刷新使其生效:
1 | source /etc/profile |
启动集群
首次启动 HDFS 时,必须对其进行格式化操作:
1 | hdfs namenode -format |
启动集群:
1 | sbin/start-dfs.sh |
停止集群:
1 | sbin/stop-dfs.sh |
查看Hadoop状态:
- 查看 HDFS: http://node01:50070
- 查看 YARN: http://node01:8088
- 查看历史任务: http://node01:19888/jobhistory
测试
测试 HDFS
从 Linux 本地磁盘上传文件到 HDFS:
1 | # 在HDFS上创建目录 |
测试 MapReduce
使用 MapReduce 估算圆周率:
1 | hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0-cdh5.14.0.jar pi 2 5 |
调优
HDFS参数调优
修改 hdfs-site.xml
:
- 编辑日志存储路径
dfs.namenode.edits.dir
与镜像文件存储路径dfs.namenode.name.dir
尽量分开,以降低写入延迟。 - 调整 NameNode 工作线程池的大小:
dfs.namenode.handler.count
=20 * log2(Cluster Size)
,比如集群规模为 8台时,此参数设置为 60。
NameNode 有一个工作线程池,用来处理不同 DataNode 的并发心跳以及客户端并发的元数据操作。对于大集群或者有大量客户端的集群来说,通常需要增大参数 dfs.namenode.handler.count
的值。
YARN参数调优
情景一:数据统计主要用 HiveSQL,没有数据倾斜,小文件做了合并处理,开启了 JVM 重用,没有 IO 阻塞,**内存用了不到 50%**。但是跑的非常慢,数据量洪峰来时,整个集群都会宕掉。
解决办法:内存利用率不够。这个一般是 Yarn 的两个配置造成的,单个任务可以申请的最大内存大小,和 Hadoop 单个节点可用内存大小。调节这两个参数能提高系统内存的利用率。
修改 yarn-site.xml
:
yarn.nodemanager.resource.memory-mb
:表示该节点上YARN可使用的物理内存总量,默认是 8192(MB)。yarn.scheduler.maximum-allocation-mb
:单个任务可申请的最多物理内存量,默认是 8192(MB)。
情景二:Hadoop 宕机。
- 如果 MR 造成系统宕机。此时要控制 Yarn 同时运行的任务数,和每个任务申请的最大内存。调整参数:
yarn.scheduler.maximum-allocation-mb
。 - 如果写入文件过量造成 NameNode 宕机。那么调高 Kafka 的存储大小,控制从 Kafka 到 HDFS 的写入速度。高峰期的时候用 Kafka 进行缓存,高峰期过去数据同步会自动跟上。