如下备忘本身学习 Hadoop 过程当中学到的内容。html
如 Hadoop 官网 所说,Hadoop 项目包含四部分:java
The project includes these modules:node
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.linux
随着大数据技术的蓬勃发展,人们提起 Hadoop 时,已经将其做为大数据生态的代名词。后续大量的大数据相关项目都或多或少地基于或提供了对 Hadoop 模块的支持。apache
如下对 Hadoop 中 hdfs 和 YARN 模块的架构进行介绍。编程
在 hdfs 架构中,文件按照配置被拆分红多个文件块进行存储( 默认为 128M )。基于此,在 hdfs 中主要有两个角色。其中,NameNode,简称 NN,负责应对客户端的请求、并记录文件块的元信息,如文件被如何拆分、如何存储等;而 DataNode,简称 DN,则负责对文件块进行读写,并以心跳包的方式按时上报本身的存活状况及所存储文件块的状况,用于 NameNode 进行实时容错排查。安全
在 hdfs 中,有如下内容须要注意:bash
在集群中,hdfs 会根据配置对文件块进行冗余存储。其副本存储策略为:首先挑选网络拓扑中距离最近的一个节点(通常在同一机架)存储一份;而后在相邻机架上挑选两个节点各存储一份;若是副本因子大于 3,则后续的副本存储会随机挑选节点进行。服务器
对于一个 User 端的请求( 来自 hdfs 交互式终端或编程接口 ),首先会在向 NameNode 中获取元数据信息。因为每个文件可能被拆分为多个文件块进行存储,且每个文件块都含有若干备份,因此 NameNode 会返回该文件所对应的全部文件块,且对于每个文件块,都附带其备份所在的 DataNode 以用于读取( 备份 DataNode 列表是已排序的 )。网络
对于每个文件块,Client Node 会进行以下操做:
上图中所示的 InputStream
对象是文件系统为用户建立的操做节点进行读取操做的对象。
对于一个 User 端的请求( 来自 hdfs 交互式终端或编程接口 ),首先会在 Client Node 中按照用户配置的块大小进行拆分,而后对于每个文件块,会有以下步骤执行:
上图中所示的 OutputStream
对象是文件系统为用户建立的操做节点进行写入操做的对象。
有关上述过程的 API 操做过程能够参考:Hadoop之HDFS文件读写过程
对分布式文件存储而言,因为其产生的最初场景就是针对大规模廉价存储介质,于是其对高可用的保证是足够到位的。如下就介绍多种故障场景及其容错机制。
NameNode 上不只记录了全部文件的元数据,还记录了全部节点的信息。即每个文件所对应的文件块及其存储的 DataNode 列表、以及每个 DataNode 上存储的文件块信息与健康状态。
每隔一段时间,DataNode 都会上报本身所维护的全部文件块状况,这一周期性的心跳包机制能够起到以下做用:
此外,对于「丢失链接」的节点,NameNode 还会按期试探其是否恢复了链接。
若是发生这种事件,在单 NameNode 状况下,整个 hdfs 集群就彻底崩溃了。由于即便文件真正存储的地方—— DataNode 没有损坏,因为失去了元数据,于是也没法将文件块拼凑成完整的文件。
但如今通常都会默认开启 SecondaryNameNode,或采用多 NameNode 节点的方式来规避这一问题。但因为同一时间只会有一个 NameNode 起做用,且备用 NameNode 中的元信息并非彻底一致的。于是当这一状况发生时,也极可能发生必定的文件丢失。
只要备份系数是大于一的( 且有多个 DataNode ),则出现这一状况时,文件不会发生丢失。且因为心跳包机制,丢失节点上所负责的备份会转移到其余节点上。
若是某一文件对应文件块所存储于的全部 DataNode 都发生了损坏,则该文件也就丢失了。
但考虑到 NameNode 会在心跳包中对损坏节点上所维护的文件块进行再分配,除非这些节点在很短期内所有损坏,不然是不会发生这种状况的。
因为每个文件块都有若干个备份,被存储在不一样的 DataNode 上,在读取过程当中,若是有 DataNode 发生了损坏,则会顺延地到 DataNode 列表的下一个节点上读取。
因为每个文件块以后都存在校验机制,若是某一文件块中的数据发生了损坏,在读取该文件块后,能够经过对比发现这一问题。
此外,因为 DataNode 也会周期性自检内部数据的完整性和正确性,并周期性上报这一信息,于是这样的状况也不易发生。
若是在某一文件块的写入过程当中,须要写入的 DataNode 列表中存在某一个损坏的节点,则会返回错误,Client Node 会将成功的节点和失败的节点上报 NameNode。因为在这一状况发生时,文件块的备份 DataNode 状况是不符合要求的,在以后的调整机制中,会对此进行弥补。
如上图所示,在 Hadoop 1.x 中,任务调度采用 JobTracker 和 TaskTracker 的机制。
对集群而言,这一架构使得资源调度模型只能适用于 MapReduce 任务。主要基于这个缘由( 还包括如 JobTracker 承担过多指责而致使的性能问题、单点故障等 ),催生了 YARN 的诞生。YARN 可使得集群资源为其上运行的多种框架共享,从而提升了资源的利用率。
在 YARN 架构中,由如下四个重要的角色:
如图所示,当有 Client 提交任务时,会发生如下步骤:
有关 MapReduce 能够参考 MapReduce原理与设计思想 或其余文章。
因为 NameNode 在启动后会经过 SSH 完成对 DataNode 节点上守护进程的启动和中止,因此咱们须要在 NameNode 上配置好对 DataNode 的免密登录( 注意这里是单机模式,NameNode 和 DataNode 启动在同一台主机上 )。
执行如下命令,生成公私钥对:
ssh-keygen -t rsa
一路回车后,执行如下命令,配置本地对本地的免登录:
ssh-copy-id -i ~/.ssh/id_rsa.pub localhost
此后,执行:
ssh root@localhost
即可以无密码登陆了。
因为大部分较新版本的大数据软件都要求使用 JDK1.8 以上,这里也依次为准。
首先,由 官网 下载 jdk-8u151-linux-x64.tar.gz。然后解压到某一目录( 这里选择 /app
,后续均为此目录 ):
tar -zxvf jdk-8u151-linux-x64.tar.gz -C /app
以后将其 bin
子目录添加到环境变量之中。修改 ~/.bash_profile
文件:
JAVA_HOME=/app/jdk1.8.0_151 export PATH=$PATH:$JAVA_HOME/bin
因为 CDH 版本在企业中使用的比例较高,这里也选用这个版本。在如下网址中下载 hadoop-2.6.0-cdh5.7.0.tar.gz :
http://archive-primary.cloudera.com/cdh5/cdh/5/
将下载后的文件解压:
tar -zxvf hadoop-2.6.0-cdh5.7.0.tar.gz -C /app
并将子目录 bin
其配置到环境变量之中。修改 ~/.bash_profile
,并添加:
HADOOP_HOME=/app/hadoop-2.6.0-cdh5.7.0 export PATH=$PATH:$HADOOP_HOME/bin
$HADOOP_HOME/etc/hadoop/hadoop-env.sh
:将:
export JAVA_HOME=${JAVA_HOME}
修改成:
export JAVA_HOME=/app/jdk1.8.0_151
$HADOOP_HOME/etc/hadoop/core-site.xml
在 configuration
标签中添加:
<property> <name>fs.default.name</name> <value>hdfs://localhost:8082</value> </property>
$HADOOP_HOME/etc/hadoop/slaves
文件因为咱们这里使用的是单机模式的 Hadoop,此文件无需改动。
修改 $HADOOP_HOME/etc/hadoop/hdfs-site.xml
,在 configuration
标签中添加:
<property> <name>dfs.replication</name> <value>1</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/app/hdfs_tmp/dfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/app/hdfs_tmp/dfs/data</value> </property>
执行如下命令以格式化 NameNode。此命令的执行与 hdfs-site.xml
中配置的 dir
有关。此外,因为每次执行都会重置文件系统,须要特别注意误操做。
hdfs namenode -format
执行如下指令:
cd $HADOOP_HOME/sbin ./start-dfs.sh
咱们可使用如下两种方式检验 hdfs 的启动状况:
jps
命令执行如下命令:
jps
查看是否已经启动了以下进程:
DataNode NameNode SecondaryNameNode
经过访问:
http://${IP}:50070
能够查看 hdfs 的启动状况。
当对 hdfs 进行操做,如使用 hdfs dfs -mkdir /test
时,可能会出现:Hadoop Name node is in safe mode
的提示。此时能够经过如下命令移除安全模式:
hdfs dfsadmin -safemode leave
将 $HADOOP_HOME/etc/hadoop/mapred-site.xml.template
复制一份名为: mapred-site.xml
,为其 configuration
添加内容:
<property> <name>mapreduce.framework.name</name> <value>yarn</value> </property>
修改 $HADOOP_HOME/etc/hadoop/yarn-site.xml
,为其 configuration
添加内容:
<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property>
使用如下命令启动 YARN:
$HADOOP_HOME/sbin/start-yarn.sh
一样的,咱们可使用如下两种方式检验 YARN 的启动状况:
jps
命令:jps
查看是否已经启动了以下进程:
ResourceManager NodeManager
经过访问:
http://${IP}:8088
能够查看 yarn 的启动状况。
咱们可使用官方提供的测试用例来测试效果:
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0-cdh5.7.0.jar pi 2 3
在 $HADOOP_HOME/sbin
下,咱们能够经过:
./start-all.sh
的方式启动 YARN 和 hdfs,但咱们会收到提示:
This script is Deprecated. Instead use start-dfs.sh and start-yarn.sh
这里只介绍搭建集群时,须要额外进行的配置。
假设咱们如今有三台机器,分别为:
192.168.0.1(主) 192.168.0.2(从) 192.168.0.3(从)
如上,咱们把 192.168.0.1
当作主节点。由上述内容可知,该机器会在以后承担 hdfs 中 NameNode
和 YARN 中 ResourceManager
的角色。
由此,咱们能够知道,在预期搭建的集群中,承担 DataNode
和 NodeManager
的为:
192.168.0.1 192.168.0.2 192.168.0.3
首先,咱们要确保三台机器都已经安装了 SSH。且都已执行如下代码生成了公私钥对:
ssh-keygen -t rsa
因为 NameNode
须要经过 SSH 对 DataNode
进行操做,因此咱们须要为 192.168.0.1
配置好对其余节点( 包括本身 )的免登录,即在 192.168.0.1
上执行:
ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.0.1 ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.0.2 ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.0.3
首先,咱们须要在主节点 192.168.0.1
上将 JDK 和 Hadoop 下载解压到 /app
目录,并按照单节点方式对其进行了配置( 包括环境变量和 Hadoop 配置 )。
接着咱们须要针对集群状况对以前的配置进行必定修改。
该文件无需额外修改。
该文件无需额外修改。
咱们须要将副本系数改成 3,而关于 name.dir
和 data.dir
的配置能够不作修改:
<property> <name>dfs.replication</name> <value>3</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/app/hdfs_tmp/dfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/app/hdfs_tmp/dfs/data</value> </property>
因为 hdfs 默认的副本系数即为 3,这里也能够省略有关 dfs.replication
的配置。
除了以前对 nodemanager.aux-services
的修改,咱们还须要添加一些配置,修改后的结果为:
<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.resourcemanager.hostname</name> <value>192.168.0.1</value> </property>
注意:因为这些配置文件会被分发到各个子节点,resourcemanager.hostname
切勿写成 localhost
该文件无需额外修改。
该文件与上述文件在同一路径下,在集群配置中,咱们须要对此进行修改:
192.168.0.1 192.168.0.2 192.168.0.3
注意,因为咱们在主节点上也运行了一个 DataNode
和 NodeManager
,故而该节点既起到了主节点做用,也承担了从节点的服务。
按照以前的作法,咱们已经对主节点完成了 JDK、Hadoop 的安装和配置,此时能够直接将该文件夹经过如下指令发送到其余其余两台机器上:
scp -r /app 192.168.0.2:/ scp -r /app 192.168.0.3:/
这样一来,只需等待传输结束,就能够在其余两台机器上完成相关软件的安装和配置。
因为咱们还在 ~/.bash_profile
中配置了环境变量,因此该文件也须要发送到两台从服务器上:
scp ~/.bash_profile 192.168.0.2:~/ scp ~/.bash_profile 192.168.0.3:~/
这以后,咱们须要登陆到两台从服务器上,使用如下命令使该配置文件生效:
source ~/.bash_profile
在主节点上,执行如下指令,进行 NameNode 的格式化:
hdfs namenode -format
注意,若是在先前的单机配置中已经进行过了格式化,须要将原有的 hdfs_tmp
文件夹删除(该目录与 hdfs-site.xml
中配置的 dir
有关),再从新进行格式化。
在主节点上,进入 $HADOOP_HOME/sbin
,执行:
./start-all
在主节点上,使用 jps
能够查看有如下进程启动:
DataNode NameNode SecondaryNameNode ResourceManager NodeManager
而在从节点上,则为:
DataNode NodeManager
自此,集群已经成功的搭建。