Hadoop 入门

Hadoop 入门

1 大数据概率

大数据是指在一定时间内无法用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息增长。

主要解决海量的存储和海量数据的分析计算问题。

1.1 大数据的特点

Volume(大量)

Velocity(高速)

Variety(多样)

Value(低价值密度)

1.2 大数据应用场景

物流仓储:大数据分析系统助力商家精细化运营、提升销量、节约成本。

零售:分析用户消费习惯,为用户购买商品提供方便,从而提升商品销量。

旅游:深度结合大数据能力与旅游行业需求,共建旅游产业智慧管理、智慧服务和智慧营销的未来。

商品推荐:根据用户购买记录推荐商品。

保险:海量数据挖掘及风险预测,助力保险行业精准营销,提升精细化定价能力。

金融:多维度体现用户特征,帮助金融机构推荐优质客户,防范欺诈风险。

房地产:大数据全面助力房地产行业,打造精准投策与营销,选出更合适的地,建造更合适的楼,卖给更合适的人。

人工智能:以大数据为依托。

2 从 Hadoop 框架讨论大数据生态

2.1 Hadoop 是什么?

Hadoop是一个由Apache基金会所开发的分布式系统基础架构。

主要解决,海量数据的存储和海量数据的分析计算问题。

广义上来说,Hadoop通常是指一个更广泛的概念——Hadoop生态圈。
Hadoop 入门

2.2 Hadoop 发行版本

Apache版本最原始(最基础)的版本,对于入门学习最好。

Cloudera在大型互联网企业中用的较多。

Hortonworks文档较好。

2.3 Hadoop 的优势

高可靠性:Hadoop 底层维护多个数据副本,所以即使 Hadoop 某个计算元素或存储出现故障,也不会导致数据的丢失。

高扩展性:在集群间分配任务数据,可方便的扩展数以千计的节点。

高效性:在 MapReduce 的思想下,Hadoop 是并行工作的,以加快任务处理速度。

高容错性:能够自动将失败的任务重新分配。

2.4 Hadoop 组成

Hadoop 入门

2.4.1 HDFS架构概述

NameNode(nn):存储文件的元数据,如文件名,文件目录结构,文件属性(生成时间、副本数、文件权限),以及每个文件的块列表和块所在的DataNode等。

DataNode(dn):在本地文件系统存储文件块数据,以及块数据的校验和。

Secondary NameNode(2nn):用来监控 HDFS 状态的辅助后台程序,每隔一段时间获取 HDFS 元数据的快照。

2.4.2 YARN架构概述

Hadoop 入门

2.4.3 MapReduce 架构概述

MapReduce 将计算过程分为两个阶段:Map 和 Reduce

Map 阶段并行处理输入数据

Reduce 阶段对 Map 结果进行汇总

2.5 大数据技术生态体系

Hadoop 入门

图中涉及的技术名词解释如下:

1)Sqoop:Sqoop 是一款开源的工具,主要用于在 Hadoop、Hive 与传统的数据库(MySQL)间进行数据的传递,可以将一个关系型数据库中的数据导进到 Hadoop 的 HDFS 中,也可以将 HDFS 的数据导进到关系型数据库中。

2)Flume:Flume 是 Cloudera 提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统,Flume 支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume 提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力。

3)Kafka:Kafka 是一种高吞吐量的分布式发布订阅消息系统,有如下特性:

(1)通过O(1)的磁盘数据结构提供消息的持久化,这种结构对于即使数以 TB 的消息存储也能够保持长时间的稳定性能。

(2)高吞吐量:即使是非常普通的硬件 Kafka 也可以支持每秒数百万的消息。

(3)支持通过 Kafka 服务器和消费机集群来分区消息。

(4)支持 Hadoop 并行数据加载。

4)Storm:Storm 用于“连续计算”,对数据流做连续查询,在计算时就将结果以流的形式输出给用户。

5)Spark:Spark 是当前最流行的开源大数据内存计算框架,可以基于 Hadoop 上存储的大数据进行计算。

6)Oozie:Oozie 是一个管理 Hdoop 作业(job)的工作流程调度管理系统。

7)Hbase:HBase 是一个分布式的、面向列的开源数据库,HBase 不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。

8)Hive:Hive 是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的 SQL查询功能,可以将 SQL 语句转换为 MapReduce 任务进行运行, 其优点是学习成本低,可以通过类 SQL 语句快速实现简单的 MapReduce 统计,不必开发专门的 MapReduce 应用,十分适合数据仓库的统计分析。

10)R语言:R 是用于统计分析、绘图的语言和操作环境。R 是属于 GNU 系统的一个*、免费、源代码开放的软件,它是一个用于统计计算和统计制图的优秀工具。

11)Mahout:Apache Mahout 是个可扩展的机器学习和数据挖掘库。

12)ZooKeeper:Zookeeper 是 Google 的 Chubby 一个开源的实现,它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护、名字服务、 分布式同步、组服务等,ZooKeeper 的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。

2.6 推荐系统框架图

Hadoop 入门

3 Hadoop 运行环境搭建

3.1 虚拟机环境准备

关闭防火墙

# 关闭防火墙
systemctl stop firewalld
# 开机禁用防火墙
systemctl disable firewalld

创建用户

# 创建用户
useradd djm
# 修改密码
passwd djm

配置用户具有 root 权限

djm     ALL=(ALL)       NOPASSWD:ALL

在 /opt 目录下创建文件夹

sudo mkdir /opt/software
sudo mkdir /opt/module

3.2 安装 JDK

卸载现有 Java

rpm -qa | grep java | xargs sudo rpm -e --nodeps

解压到 /opt/module 目录

tar -zxvf jdk-8u144-linux-x64.tar.gz -C /opt/module/

配置环境变量

sudo vim /etc/profile
#JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_144
export PATH=$PATH:$JAVA_HOME/bin

刷新配置

source /etc/profile

测试是否安装成功

java -version

3.3 安装 Hadoop

解压到 /opt/module 目录

tar -zxvf hadoop-2.7.2.tar.gz -C /opt/module/

配置环境变量

sudo vim /etc/profile
#HADOOP_HOME
export HADOOP_HOME=/opt/module/hadoop-2.7.2
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

刷新配置

source /etc/profile

测试是否安装成功

hadoop version

3.4 Hadoop 目录结构

bin 目录:存放对 Hadoop 相关服务(HDFS,YARN)进行操作的脚本

etc 目录:Hadoop 的配置文件目录,存放 Hadoop 的配置文件

lib 目录:存放 Hadoop 的本地库(对数据进行压缩解压缩功能)

sbin 目录:存放启动或停止 Hadoop 相关服务的脚本

share 目录:存放 Hadoop 的依赖 jar 包、文档、和官方案例

4 Hadoop 运行模式

4.1 本地运行模式

创建一个 input 文件夹

[djm@hadoop101 hadoop-2.7.2]$ mkdir input

将 Hadoop 的 xml 配置文件复制到 input

[djm@hadoop101 hadoop-2.7.2]$ cp etc/hadoop/*.xml input

执行 share 目录下的 MapReduce 程序

# output 必须是一个不存在的文件夹
[djm@hadoop101 hadoop-2.7.2]$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar grep input output 'dfs[a-z.]+'

查看输出结果

[djm@hadoop101 hadoop-2.7.2]$ cat output/*

4.2 伪分布式运行模式

4.2.1 启动 HDFS 并运行 MapReduce 程序

配置 hadoop-env.sh

#修改JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_144

配置 core-site.xml

<configuration>
    <!-- 指定HDFS中NameNode的地址 -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hadoop101:9000</value>
    </property>
    <!-- 指定Hadoop运行时产生文件的存储目录 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/module/hadoop-2.7.2/data/tmp</value>
    </property>
</configuration>

配置 hdfs-site.xml

<configuration>
    <!-- 指定HDFS副本的数量 -->
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
</configuration>

启动集群

#格式化NameNode
[djm@hadoop101 hadoop-2.7.2]$ hdfs namenode -format
#启动NameNode
[djm@hadoop101 hadoop-2.7.2]$ hadoop-daemon.sh start namenode
#启动DataNode
[djm@hadoop101 hadoop-2.7.2]$ hadoop-daemon.sh start datanode

查看是否启动成功

jps

web 端查看HDFS文件系统

http://hadoop101:50070/dfshealth.html#tab-overview

操作集群

#在HDFS文件系统上创建input
[djm@hadoop101 hadoop-2.7.2]$ hdfs dfs -mkdir -p /user/djm/input
#将测试文件内容上传到文件系统上
[djm@hadoop101 hadoop-2.7.2]$ hdfs dfs -put wcinput/wc.input /user/djm/input/
#运行MapReduce程序
[djm@hadoop101 hadoop-2.7.2]$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar wordcount /user/djm/input/ /user/djm/output
#查看运行结果
[djm@hadoop101 hadoop-2.7.2]$ hdfs dfs -cat /user/djm/output/*
#删除运行结果
[djm@hadoop101 hadoop-2.7.2]$ hdfs dfs -rm -r /user/djm/output

为什么不能一直格式化 NameNode,格式化 NameNode,要注意什么?

当我们执行文件系统格式化时,会在 NameNode 数据文件夹(即配置文件中 dfs.name.dir 在本地系统的路径)中保存一个 dfs/data/current/VERSION 文件,记录了 clusterID 和 datanodeUuid,格式化 NameNode 会产生新的 clusterID,但是 VERSION 文件只记录第一次格式化时保存的 clusterID,因此造成 DataNode 与 NameNode 之间的 ID 不一致,解决方法是删除 VERSION 文件。

4.2.2 启动 YARN 并运行 MapReduce 程序

配置 yarn-env.sh

#修改JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_144

配置 yarn-site.xml

<configuration>
    <!-- Reducer获取数据的方式 -->
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <!-- 指定YARN的ResourceManager的地址 -->
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>hadoop101</value>
    </property>
</configuration>

配置 mapred-env.sh

#修改JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_144

配置 mapred-site.xml

#将mapred-site.xml.template重命名为mapred-site.xml
[djm@hadoop101 hadoop-2.7.2]$ mv mapred-site.xml.template mapred-site.xml
<configuration>
    <!-- 指定MR运行在YARN上 -->
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
</configuration>

启动集群

#启动NameNode
[djm@hadoop101 hadoop-2.7.2]$ hadoop-daemon.sh start namenode
#启动DataNode
[djm@hadoop101 hadoop-2.7.2]$ hadoop-daemon.sh start datanode
#启动ResourceManager
[djm@hadoop101 hadoop-2.7.2]$ sbin/yarn-daemon.sh start resourcemanager
#启动NodeManager
[djm@hadoop101 hadoop-2.7.2]$ sbin/yarn-daemon.sh start nodemanager

web 端查看 YARN

http://hadoop101:8088/cluster

集群操作

#删除文件系统上的output文件
[djm@hadoop101 hadoop-2.7.2]$ hdfs dfs -rm -R /user/djm/output
#执行MapReduce程序
[djm@hadoop101 hadoop-2.7.2]$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar wordcount /user/djm/input  /user/djm/output
4.2.3 配置历史服务器

配置 mapred-site.xml

<configuration>
    <!-- 历史服务器端地址 -->
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>hadoop101:10020</value>
    </property>
    <!-- 历史服务器web端地址 -->
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>hadoop101:19888</value>
    </property>
</configuration>

启动历史服务器

mr-jobhistory-daemon.sh start historyserver

查看 JobHistory

http://hadoop101:19888/jobhistory

4.2.4 配置日志的聚集

日志聚集概念:应用运行完成以后,将程序运行日志信息上传到 HDFS 系统上。

日志聚集功能好处:可以方便的查看到程序运行详情,方便开发调试。

<configuration>
    <!-- 日志聚集功能使能 -->
    <property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
    </property>
    <!-- 日志保留时间设置7天 -->
    <property>
        <name>yarn.log-aggregation.retain-seconds</name>
        <value>604800</value>
    </property>
</configuration>

重启 NodeManager 、ResourceManager 和 HistoryServer

[djm@hadoop101 hadoop-2.7.2]$ yarn-daemon.sh stop resourcemanager
[djm@hadoop101 hadoop-2.7.2]$ yarn-daemon.sh stop nodemanager
[djm@hadoop101 hadoop-2.7.2]$ mr-jobhistory-daemon.sh stop historyserver
[djm@hadoop101 hadoop-2.7.2]$ yarn-daemon.sh start resourcemanager
[djm@hadoop101 hadoop-2.7.2]$ yarn-daemon.sh start nodemanager
[djm@hadoop101 hadoop-2.7.2]$ mr-jobhistory-daemon.sh start historyserver

删除 HDFS 上已经存在的输出文件

[djm@hadoop101 hadoop-2.7.2]$ hdfs dfs -rm -R /user/djm/output

执行 WordCount 程序

[djm@hadoop101 hadoop-2.7.2]$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar wordcount /user/djm/input  /user/djm/output

查看日志

http://hadoop101:19888/jobhistory

4.2.5 配置文件说明

Hadoop 配置文件分两类:默认配置文件和自定义配置文件,只有用户想修改某一默认配置值时,才需要修改自定义配置文件,更改相应属性值。

自定义配置文件:

core-site.xml、hdfs-site.xml、yarn-site.xml、mapred-site.xml 四个配置文件存放在 $HADOOP_HOME/etc/hadoop 这个路径上,用户可以根据项目需求重新进行修改配置。

4.3 完全分布式运行模式

4.3.1 编写集群分发脚本 xsync

创建 xsync

[djm@hadoop102 ~]$ mkdir bin
[djm@hadoop102 ~]$ cd bin/
[djm@hadoop102 bin]$ touch xsync
[djm@hadoop102 bin]$ vi xsync

在该文件中编写如下代码

#!/bin/bash
#1 获取输入参数个数,如果没有参数,直接退出
pcount=$#
if ((pcount==0)); then
echo no args;
exit;
fi

#2 获取文件名称
p1=$1
fname=`basename $p1`
echo fname=$fname

#3 获取上级目录到绝对路径
pdir=`cd -P $(dirname $p1); pwd`
echo pdir=$pdir

#4 获取当前用户名称
user=`whoami`

#5 循环
for((host=103; host&lt;105; host++)); do
        echo ------------------- hadoop$host --------------
        rsync -av $pdir/$fname $user@hadoop$host:$pdir
done

分发

[djm@hadoop102 ~]$ xsync /opt/module/jdk1.8.0_144
[djm@hadoop102 ~]$ xsync /opt/module/hadoop-2.7.2
[djm@hadoop102 ~]$ xsync /etc/profile
4.3.2 集群配置

集群部署规划

hadoop102 hadoop103 hadoop104
HDFS NameNode、DataNode DataNode SecondaryNameNode、DataNode
YARN NodeManager ResourceManager、NodeManager NodeManager

配置 core-site.xml

<configuration>
    <!-- 指定HDFS中NameNode的地址 -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hadoop101:9000</value>
    </property>
    <!-- 指定Hadoop运行时产生文件的存储目录 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/module/hadoop-2.7.2/data/tmp</value>
    </property>
</configuration>

配置 hadoop-env.sh

#修改JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_144

配置 hdfs-site.xml

<configuration>
    <!-- 指定HDFS副本的数量 -->
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <!-- 指定Hadoop辅助名称节点主机配置 -->
    <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>hadoop104:50090</value>
    </property>
</configuration>

配置 yarn-env.sh

#修改JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_144

配置 yarn-site.xml

<configuration>
    <!-- Reducer获取数据的方式 -->
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <!-- 指定YARN的ResourceManager的地址 -->
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>hadoop103</value>
    </property>
</configuration>

配置 mapred-env.sh

#修改JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_144

配置 mapred-site.xml

<configuration>
    <!-- 指定MR运行在YARN上 -->
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
</configuration>

在集群上分发配置好的 Hadoop 配置文件

[djm@hadoop102 ~]$ xsync /opt/module/hadoop-2.7.2/etc/hadoop/
4.3.3 集群单点启动

如果集群是第一次启动,需要格式化 NameNode

[djm@hadoop102 hadoop-2.7.2]$ hdfs namenode -format

在 hadoop102 上启动 NameNode

[djm@hadoop102 hadoop-2.7.2]$ hadoop-daemon.sh start namenode

在 hadoop102、hadoop103 以及 hadoop104 上分别启动 DataNode

[djm@hadoop102 hadoop-2.7.2]$ hadoop-daemon.sh start datanode
[djm@hadoop103 hadoop-2.7.2]$ hadoop-daemon.sh start datanode
[djm@hadoop104 hadoop-2.7.2]$ hadoop-daemon.sh start datanode

为什么三个主机来回切换占用一个 datanode?

分别查看三台主机的 VERSION 文件,发现 datanodeUuid 相同,果断分别删除 VERSION 文件,重新启动 datanode,问题解决

4.3.4 SSH 无密登录配置

Hadoop 入门

生成公钥和私钥

[djm@hadoop102 .ssh]$ ssh-keygen -t rsa

将公钥拷贝到要免密登录的目标机器上

[djm@hadoop102 .ssh]$ ssh-copy-id hadoop102
[djm@hadoop102 .ssh]$ ssh-copy-id hadoop103
[djm@hadoop102 .ssh]$ ssh-copy-id hadoop104
[djm@hadoop103 .ssh]$ ssh-copy-id hadoop102
[djm@hadoop103 .ssh]$ ssh-copy-id hadoop103
[djm@hadoop103 .ssh]$ ssh-copy-id hadoop104
[djm@hadoop104 .ssh]$ ssh-copy-id hadoop102
[djm@hadoop104 .ssh]$ ssh-copy-id hadoop103
[djm@hadoop104 .ssh]$ ssh-copy-id hadoop104

.ssh 下(~/.ssh)的文件功能解释

known_hosts 记录ssh访问过计算机的公钥(public key)
id_rsa 生成的私钥
id_rsa.pub 生成的公钥
authorized_keys 存放授权过得无密登录服务器公钥
4.3.5 群起集群

编写 jpsall 脚本

#!/bin/bash

# 循环
for((host=102; host&lt;105; host++)); do
        echo ------------------- hadoop$host --------------
        ssh hadoop$host "source /etc/profile &amp;&amp; jps"       
done

配置 slaves

hadoop102
hadoop103
hadoop104

同步所有节点配置文件

[djm@hadoop102 hadoop]$ xsync slaves

启动 HDFS

[djm@hadoop102 hadoop-2.7.2]$ start-dfs.sh

启动 YARN

[djm@hadoop103 hadoop-2.7.2]$ start-yarn.sh

启动 HistoryServer

[djm@hadoop103 hadoop-2.7.2]$ mr-jobhistory-daemon.sh start historyserver

查看是否启动成功

[djm@hadoop102 hadoop-2.7.2]$ jpsall 
------------------- hadoop102 --------------
98640 Jps
3266 DataNode
3037 NameNode
3549 NodeManager
------------------- hadoop103 --------------
74929 DataNode
75258 NodeManager
39453 Jps
75054 ResourceManager
------------------- hadoop104 --------------
77123 SecondaryNameNode
76562 DataNode
76786 NodeManager
41475 Jps
76904 JobHistoryServer

删除文件系统上的 output 文件

[djm@hadoop102 hadoop-2.7.2]$ hdfs dfs -rm -R /user/djm/output

执行 MapReduce 程序

[djm@hadoop102 hadoop-2.7.2]$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar wordcount /user/djm/input  /user/djm/output
4.3.6 集群启动/停止方式总结

各个服务组件逐一启动/停止

  • 分别启动/停止 HDFS 组件

    hadoop-daemon.sh  start / stop  namenode / datanode / secondarynamenode
  • 启动/停止 YARN

    yarn-daemon.sh  start / stop  resourcemanager / nodemanager

各个模块分开启动/停止(配置 ssh 是前提)常用

  • 整体启动/停止 HDFS

    start-dfs.sh   /  stop-dfs.sh
  • 整体启动/停止 YARN

    start-yarn.sh  /  stop-yarn.sh
4.3.7 集群时间同步

检查是否安装了 ntp 服务

[root@hadoop102 ~]# rpm -qa | grep ntp

修改 /etc/ntp.conf

将
#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
修改为
restrict 192.168.10.0 mask 255.255.255.0 nomodify notrap
将
server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst
修改为
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
添加
server 127.127.1.0
fudge 127.127.1.0 stratum 10

修改 /etc/sysconfig/ntpd

#同步硬件时间
SYNC_HWCLOCK=yes

重新启动 ntpd 服务

[root@hadoop102 ~]# systemctl restart ntpd

设置ntpd服务开机启动

[root@hadoop102 ~]# chkconfig ntpd on

在其他机器配置 10 分钟与时间服务器同步一次

[root@hadoop102 ~]# crontab -e
添加
*/10 * * * * /usr/sbin/ntpdate hadoop102