文章目录
- 1、服务概述
-
- [1.1 HDFS](#1.1 HDFS)
-
- [1.1.1 架构解析](#1.1.1 架构解析)
-
- [1.1.1.1 Block 数据块](#1.1.1.1 Block 数据块)
- [1.1.1.2 NameNode 名称节点](#1.1.1.2 NameNode 名称节点)
- [1.1.1.3 Secondary NameNode 第二名称节点](#1.1.1.3 Secondary NameNode 第二名称节点)
- [1.1.1.4 DataNode 数据节点](#1.1.1.4 DataNode 数据节点)
- [1.1.1.5 Block Caching 块缓存](#1.1.1.5 Block Caching 块缓存)
- [1.1.1.6 HDFS Federation 联邦](#1.1.1.6 HDFS Federation 联邦)
- [1.1.1.7 Rack Awareness 机架感知](#1.1.1.7 Rack Awareness 机架感知)
- [1.1.2 读写操作与可靠性](#1.1.2 读写操作与可靠性)
-
- [1.1.2.1 写操作](#1.1.2.1 写操作)
- [1.1.2.2 读操作](#1.1.2.2 读操作)
- [1.1.2.3 可靠性](#1.1.2.3 可靠性)
- [1.1.3 NameNode元数据解析](#1.1.3 NameNode元数据解析)
- [1.2 YARN](#1.2 YARN)
-
- [1.2.1 架构演变](#1.2.1 架构演变)
- [1.2.2 基本流程](#1.2.2 基本流程)
- [1.2.3 进程组件](#1.2.3 进程组件)
-
- [1.2.3.1 ResourceManager 资源管理](#1.2.3.1 ResourceManager 资源管理)
- [1.2.3.2 NodeManager 节点管理](#1.2.3.2 NodeManager 节点管理)
- [1.2.3.3 ApplicationMaster 应用管理](#1.2.3.3 ApplicationMaster 应用管理)
- [1.2.3.4 Container 容器](#1.2.3.4 Container 容器)
- [1.2.3.5 Failover 故障处理](#1.2.3.5 Failover 故障处理)
- [1.3 MapReduce](#1.3 MapReduce)
-
- [1.3.1 Map](#1.3.1 Map)
- [1.3.2 Reduce](#1.3.2 Reduce)
- [1.3.3 读取数据](#1.3.3 读取数据)
-
- [1.3.3.1 InputFormat 输入格式化](#1.3.3.1 InputFormat 输入格式化)
- [1.3.3.2 InputSplit 输入分割](#1.3.3.2 InputSplit 输入分割)
- [1.3.3.3 RecordReader 记录读者](#1.3.3.3 RecordReader 记录读者)
- [1.3.3.4 Mapper 映射器](#1.3.3.4 Mapper 映射器)
- [1.3.3.5 Shuffle 清洗器](#1.3.3.5 Shuffle 清洗器)
- 2、配置文件常用参数
-
- [2.1 core-site.xml](#2.1 core-site.xml)
- [2.2 hdfs-site.xml](#2.2 hdfs-site.xml)
- [2.3 mapred-site.xml](#2.3 mapred-site.xml)
- [2.4 yarn-site.xml](#2.4 yarn-site.xml)
- 3、环境安装
-
- [3.1 安装包下载](#3.1 安装包下载)
- [3.2 单机部署](#3.2 单机部署)
- [3.3 集群部署(推荐)](#3.3 集群部署(推荐))
-
- [3.3.1 HDFS](#3.3.1 HDFS)
-
- [3.3.1.1 部署](#3.3.1.1 部署)
- [3.3.1.2 验证](#3.3.1.2 验证)
- [3.3.1.3 数据存储](#3.3.1.3 数据存储)
- [3.3.2 YARN](#3.3.2 YARN)
-
- [3.3.2.1 部署](#3.3.2.1 部署)
- [3.3.2.2 验证](#3.3.2.2 验证)
- [3.3.2.3 资源控制](#3.3.2.3 资源控制)
- [3.3.3 集群控制脚本](#3.3.3 集群控制脚本)
- 4、常见操作
-
- [4.1 NN异常恢复](#4.1 NN异常恢复)
- [4.2 安全模式](#4.2 安全模式)
- [4.3 数据平衡](#4.3 数据平衡)
- [4.4 集群扩/缩容](#4.4 集群扩/缩容)
-
- [4.4.1 扩容](#4.4.1 扩容)
- [4.4.2 缩容](#4.4.2 缩容)
- [4.5 回收站](#4.5 回收站)
- [4.6 Snapshot 快照](#4.6 Snapshot 快照)
-
- [4.6.1 操作命令](#4.6.1 操作命令)
- [4.6.2 快照使用](#4.6.2 快照使用)
-
- 4.6.2.1开启快照
- [4.6.2.2 对指定目录创建快照](#4.6.2.2 对指定目录创建快照)
- [4.6.2.3 重命名快照](#4.6.2.3 重命名快照)
- [4.6.2.4 列出当前用户所有可以快照的目录](#4.6.2.4 列出当前用户所有可以快照的目录)
- [4.6.2.5 比较两个快照不同之处](#4.6.2.5 比较两个快照不同之处)
- [4.6.2.6 删除快照](#4.6.2.6 删除快照)
- [4.6.2.7 删除有快照的目录](#4.6.2.7 删除有快照的目录)
- 5、错误记录
-
- [5.1 Java版本不兼容](#5.1 Java版本不兼容)
- [5.2 无法正常查看文件内容](#5.2 无法正常查看文件内容)
1、服务概述
Hadoop是一个开源的分布式计算和存储框架,由Apache基金会开发和维护。Hadoop 为庞大的计算机集群提供可靠的、可伸缩的应用层计算和存储支持,它允许使用简单的编程模型跨计算机群集分布式处理大型数据集,并且支持在单台计算机到几千台计算机之间进行扩展。
Hadoop使用Java开发,所以可以在多种不同硬件平台的计算机上部署和使用。其核心部件包括分布式文件系统 (Hadoop DFS,HDFS) 和MapReduce。
1.1 HDFS
Hadoop Distributed File System,Hadoop分布式文件系统,简称HDFS
1.1.1 架构解析
1.1.1.1 Block 数据块
- 基本存储单元 ,1.x版本默认64M,2.x版本之后默认128M;
- 单个文件会被拆分成为一个个大小相同的块数据,存储在不同的机器上,当一个文件小于Block设置的大小,那么实际占用的空间为其文件的大小;
- 基本读写单位,类似于磁盘的页,每次都是读写一个块;
- 每个块都会被复制到多个机器上,默认副本数量为3。
Hadoop 1.x版本默认为64M,Hadoop 2.x版本之后默认为128M。
- 减少搜索时间,一般情况下硬盘传输速率比寻道时间更快,较大的块可以减少寻道时间;
- 减少管理块的数据开销,每个块都需要在NameNode上有对应记录,数量少可以减少这些记录;
- 对较大的数据块进行读写,可以降低网络通信的次数和成本。
1.1.1.2 NameNode 名称节点
- 存储文件的metadata,运行时所有数据都保存到内存(因此推荐部署节点性能内存偏大),整个HDFS可存储的文件数受限于NameNode的内存大小;
- NameNode主要存放文件系统树及所有文件、目录的元数据。元数据持久化为2种形式:namespcae image 镜像文件 + edit log 日志文件,持久化数据中不包括Block所在的节点列表,及文件的Block分布在集群中的哪些节点上,这些信息是在系统重启的时候重新构建(通过Datanode汇报的Block信息)。
- 一个Block在NameNode中对应一条记录(一般一个Block占用150字节),如果是大量的小文件,会消耗大量内存;同时map task的数量是由splits来决定的,所以用MapReduce处理大量的小文件时,就会产生过多的map task,线程管理开销将会增加作业时间;处理大量小文件的速度远远小于处理同等大小的大文件的速度。因此Hadoop建议存储大文件;
- 数据会定时保存到本地磁盘,但不保存Block的位置信息,而是由DataNode注册时上报和运行时维护(NameNode中与DataNode相关的信息并不保存到NameNode的文件系统中,而是NameNode每次重启后,动态重建);
- NameNode失效则整个HDFS都会失效,因此优先保证NameNode的可用性,HDFS针对单点故障提供了2种解决机制: 备份持久化元数据 / 使用Secondary NameNode。
1.1.1.3 Secondary NameNode 第二名称节点
SecondaryNameNode有两个作用:一是镜像备份,二是日志与镜像的定期合并。两个过程同时进行,称为checkpoint。
镜像备份:定期备份fsimage文件;
Checkpoint:将日志与镜像的定期合并操作,避免edit log过大,通过创建检查点checkpoint来合并(合并周期与镜像大小可以通过core-site.xml设置)。它会维护一个合并后的namespace image副本, 可用于在Namenode完全崩溃时恢复数据,因此SNN并非是NN的备用节点,并不会再NN异常时主动切换。具体流程如下:
- SecondaryNameNode通知NameNode准备提交edits文件,此时主节点产生edits.new;
- SecondaryNameNode通过http get方式获取NameNode的fsimage与edits文件(在SecondaryNameNode的current同级目录下可见到 temp.check-point或者previous-checkpoint目录,这些目录中存储着从namenode拷贝来的镜像文件);
- SecondaryNameNode开始合并获取的上述两个文件,产生一个新的fsimage文件fsimage.ckpt;
- SecondaryNameNode用http post方式发送fsimage.ckpt至NameNode;
- NameNode将fsimage.ckpt与edits.new文件分别重命名为fsimage与edits,然后更新fstime,整个checkpoint过程到此结束。 在新版本的hadoop中(hadoop0.21.0),SecondaryNameNode两个作用被两个节点替换, checkpoint node与backup node. SecondaryNameNode备份由三个参数控制fs.checkpoint.period控制周期,fs.checkpoint.size控制日志文件超过多少大小时合并, dfs.http.address表示http地址,这个参数在SecondaryNameNode为单独节点时需要设置。
Secondary Namenode通常运行在另一台机器,因为合并操作需要耗费大量的CPU和内存。其数据落后于Namenode,因此当Namenode完全崩溃时,会出现数据丢失问题。 通常做法是拷贝NFS中的备份元数据到Secondary NameNode,将其作为新的Namenode。
1.1.1.4 DataNode 数据节点
- 存储具体的Block数据;
- 负责数据的读写操作和复制操作;
- DataNode启动时会向NameNode报告当前存储的数据块信息,后续也会定时报告修改信息;
- DataNode之间会进行通信,复制数据块,保证数据的冗余性;
1.1.1.5 Block Caching 块缓存
DataNode通常直接从磁盘读取数据,但是频繁使用的Block可以在内存中缓存。
默认情况下,一个Block只有一个数据节点会缓存。但是可以针对每个文件设置个性化配置,作业调度器可以利用缓存提升性能,例如MapReduce可以把任务运行在有Block缓存的节点上,用户或者应用可以向NameNode发送缓存指令(缓存哪个文件,缓存多久), 缓存池的概念用于管理一组缓存的权限和资源。
1.1.1.6 HDFS Federation 联邦
我们知道NameNode的内存会制约文件数量,HDFS Federation提供了一种横向扩展NameNode的方式。在Federation模式中,每个NameNode管理命名空间的一部分,例如一个NameNode管理/user目录下的文件, 另一个NameNode管理/share目录下的文件。
每个NameNode管理一个namespace volumn,所有volumn构成文件系统的元数据。每个NameNode同时维护一个Block Pool,保存Block的节点映射等信息。各NameNode之间是独立的,一个节点的失败不会导致其他节点管理的文件不可用。
客户端使用mount table将文件路径映射到NameNode。mount table是在Namenode群组之上封装了一层,这一层也是一个Hadoop文件系统的实现,通过viewfs:协议访问。
1.1.1.7 Rack Awareness 机架感知
在读取和写入的过程中,namenode在分配Datanode的时候,会考虑节点之间的距离。HDFS中距离没有
采用带宽来衡量,因为实际中很难准确度量两台机器之间的带宽。
Hadoop把机器之间的拓扑结构组织成树结构,并且用到达公共父节点所需跳转数之和作为距离。事实上这是一个距离矩阵的例子。下面的例子简明地说明了距离的计算:
- 同一数据中心,同一机架,同一节点距离为0;
- 同一数据中心,同一机架,不同节点距离为2;
- 同一数据中心,不同机架,不同节点距离为4;
- 不同数据中心,不同机架,不同节点距离为6。
注意:Hadoop集群的拓扑结构需要手动配置,如果没配置,Hadoop默认所有节点位于同一个数据中心的同一机架上!
1.1.2 读写操作与可靠性
1.1.2.1 写操作
- 客户端将文件写入本地磁盘的HDFS Client文件中;
- 当临时文件大小达到一个Block大小时,HDFS Client通知NameNode申请写入文件;
- NameNode在HDFS的文件系统中创建一个文件,并把该Block ID和要写入的DataNode列表返回给HDFS Client;
- HDFS Client收到这个信息后,将文件内容写入第一个DataNode(一般以4Kb单位进行传输,集群读写操作时缓冲区大小可在core-site.xml配置io.file.buffer.size);
- 当第一个DataNode接收后,将数据写入本地磁盘,同时传输给第二个DataNode,以此类推当第三个DataNode写入本地磁盘(默认副本数量为3),数据在DataNode之间是通过pipeline的方式进行复制的;
- 当写入操作完成后,DataNode会发现一个确认给前一个DataNode,最后由第一个DataNode返回确认写入完成给HDFS Client;
- 当HDFS Client接收到这个确认写入数据后,会向NameNode发送一个最终的确认;
- 当某个DataNode写入失败时,数据会继续写入其他的DataNode,然后NameNode会寻找另一个正常的DataNode继续复制,以保证数据副本数;
- 每个Block都会有一个校验码,并存储在独立的文件中,以便读操作时校验其完整性;
- 文件写完后(HDFS Client关闭),NameNode提交文件(这时文件才可见,如果提交前,NameNode垮掉,那文件也就丢失了。fsync:只保证数据的信息写到NameNode上,但并不保证数据已经被写到DataNode中)。
1.1.2.2 读操作
- HDFS Client向NameNode发送读请求;
- NameNode返回文件的所有Block和这些Block所在的DataNodes(包括复制节点);
- 客户端直接从DataNode中读取数据,如果该DataNode读取失败(DataNode失效或校验码不对),则从复制节点中读取(如果读取的数据就在本机,则直接读取,否则通过网络读取)。
1.1.2.3 可靠性
- 多副本机制:DataNode中存储的Block均拥有多个副本数,默认为3,支持在hdfs-site.xml中设置。
- 机架感知:通过节点之间发送一个数据包,来感应它们是否在同一个机架,不同副本存放在不同机架上节点。
- 心跳机制:NameNode周期性从DataNode接受心跳信息和块报告,NameNode根据块报告验证元数据,没有按时发送心跳的DataNode会被标记为宕机,NameNode不会发送任何I/O请求到异常节点,若是DataNode失效造成副本数不足设定值,NameNode会在合适的时机重新下发复制操作到正常的DataNode。
- 安全模式:NameNode启动时会先经过一个"安全模式"阶段,安全模式阶段不会产生数据写操作,在此阶段NameNode收集各个DataNode的报告,当数据块达到最小副本数以上时,会被认为是"安全"的,在一定比例(支持自定义设置)的数据块被确定为"安全" 后,在过若干时间后安全模式结束;当检测到副本数不足的数据块时,该数据块会被复制,直到满足最小副本数要求。
- 校验机制:在文件创立时,每个数据块都产生效验和,效验和会作为单独一个隐藏文件保存在命名空间下,客户端获取数据时可以检查效验和是否相同,从而发现数据块是否损坏,如果正在读取的数据块损坏,则可以继续读取其他副本。
- 回收站:删除文件时,其实是放入回收站 /trash路径,回收站里的文件支持快速恢复,支持设置一个时间阈值,当回收站里文件的存放时间超过了这个阈值,就被彻底删除,并且释放占用的数据块;
- 元数据保护:映像文件和事物日志是NameNode的核心数据,可配置为多副本,副本会降低NameNode的处理速度,但是会增加安全性,NameNode依然是单点,弱发生故障需要手工进行切换。
1.1.3 NameNode元数据解析
元数据持久化为2种形式:namespcae image 镜像文件 + edit log 日志文件,存储路径通过在core-site.xml配置文件里设置参数hadoop.tmp.dir的值。
可以看到在dfs文件下的name目录存放edits与fsimage文件,其内容均为二进制,无法直接查看(由于数据量较大,因此HDFS取消了编码效果,可以通过工具查看)
bash
$ hdfs oev -i <edits/fsimage_file> -o <tmp_file.xml>
# 将二进制文件输出为xml格式文件查看,文件路径和名称支持自定义
1.2 YARN
1.2.1 架构演变
Hadoop 1.x 架构
- JobTracker: 负责资源管理,跟踪资源消耗和可用性,作业生命周期管理(调度作业任务,跟踪进度,为任务提供容错);
- TaskTracker: 加载或关闭任务,定时报告任务状态。
此架构会有以下问题:
- JobTracker是MapReduce的集中处理点,存在单点故障风险;
- JobTracker完成了太多的任务,造成了过多的资源消耗,当MapReduce job非常多的时候,会造成很大的内存开销。这也是业界普遍总结出老Hadoop的 MapReduce只能支持4000节点主机的上限;
- 在TaskTracker端,以Map/Reduce Task的数目作为资源的表示过于简单,没有考虑到CPU/Mem的占用情况,如果两个大内存消耗的Task被调度到了一块,很容易出现OOM风险;
- 在TaskTracker端,把资源强制划分为Map Task Slot 和Reduce Task Slot , 如果当系统中只有Map Task 或者只有Reduce Task的时候,会造成资源的浪费,也就集群资源利用的问题。
Hadoop 2.x 架构
YARN就是将JobTracker的职责进行拆分,将资源管理和任务调度监控拆分成独立的进程:一个全局的资源管理和一个每个作业的管理(ApplicationMaster)ResourceManager和NodeManager提供了计算资源的分配和管理,而ApplicationMaster则完成应用程序的运行。
- ResourceManager: 全局资源管理和任务调度;
- NodeManager: 单个节点的资源管理和监控;
- ApplicationMaster: 单个作业的资源管理和任务监控;
- Container: 资源申请的单位和任务运行的容器。
两种版本架构对比
YARN架构下形成了一个通用的资源管理平台和一个通用的应用计算平台,避免了旧架构的单点问题和资源利用率问题,同时也让运行的应用不再局限于MapReduce形式。
1.2.2 基本流程
- Job submission 提交Job:从ResourceManager中获取一个Application ID检查作业输出配置,计算输入分片copy job资源(job jar、配置文件、分片信息)到HDFS,以便后面任务的执行;
- Job initialization 初始化job:ResourceManager将作业递交给Scheduler(有很多调度算法,一般是根据优先级)Scheduler为作业分配一个Container,ResourceManager就加载一个Application master process并交给NodeManager;管理ApplicationMaster主要是创建一系列的监控进程来跟踪作业的进度,同时获取输入分片,为每一个分片创建一个Map task和相应的reduce task,Application Master还决定如何运行作业,如果作业很小(可配置),则直接在同一个JVM下运行;
- Task assignment 任务分配:ApplicationMaster向Resource Manager申请资源(一个个的Container,指定任务分配的资源要求)一般是根据data locality来分配资源;
- Task execution 任务执行:ApplicationMaster根据ResourceManager的分配情况,在对应的NodeManager中启动Container从HDFS中读取任务所需资源(job jar,配置文件等),然后执行该任务
- Progress and status update 进度与状态更新:定时将任务的进度和状态报告给ApplicationMaster Client定时向ApplicationMaster获取整个任务的进度和状态
- Job completion 任务完成:Client定时检查整个作业是否完成,作业完成后会自动清空临时文件、目录等。
1.2.3 进程组件
YARN将JobTracker拆分为四个组件 + 一个故障组件。
1.2.3.1 ResourceManager 资源管理
负责全局的资源管理和任务调度,把整个集群当成计算资源池,只关注分配,不负责应用与容错。
资源管理
- 以前资源是每个节点分成一个个的Map slot和Reduce slot,现在是一个个Container,每个Container可以根据需要运行ApplicationMaster、Map、Reduce或者任意的程序;
- 以前的资源分配是静态的,目前是动态的,资源利用率更高;
- Container是资源申请的单位,一个资源申请格式:<resource-name, priority, resource-requirement, number-of-containers>,resource-name:主机名、机架名或*(代表任意机器), resource-requirement:目前只支持CPU和内存;
- 用户提交作业到ResourceManager,然后在某个NodeManager上分配一个Container来运行ApplicationMaster,ApplicationMaster再根据自身程序需要向ResourceManager申请资源;
- YARN有一套Container的生命周期管理机制,而ApplicationMaster和其Container之间的管理是应用程序自己定义的。
任务调度
- 只关注资源的使用情况,根据需求合理分配资源;
- Scheluer可以根据申请的需要,在特定的机器上申请特定的资源(ApplicationMaster负责申请资源时的数据本地化的考虑,ResourceManager将尽量满足其申请需求,在指定的机器上分配Container,从而减少数据移动)。
内部结构
- Client Service: 应用提交、终止、输出信息(应用、队列、集群等的状态信息);
- Adaminstration Service: 队列、节点、Client权限管理;
- ApplicationMasterService: 注册、终止ApplicationMaster, 获取ApplicationMaster的资源申请或取消的请求,并将其异步地传给Scheduler, 单线程处理;
- ApplicationMaster Liveliness Monitor: 接收ApplicationMaster的心跳消息,如果某个ApplicationMaster在一定时间内没有发送心跳,则被任务失效,其资源将会被回收,然后ResourceManager会重新分配一个ApplicationMaster运行该应用(默认尝试2次);
- Resource Tracker Service: 注册节点, 接收各注册节点的心跳消息;
- NodeManagers Liveliness Monitor: 监控每个节点的心跳消息,如果长时间没有收到心跳消息,则认为该节点无效, 同时所有在该节点上的Container都标记成无效,也不会调度任务到该节点运行;
- ApplicationManager: 管理应用程序,记录和管理已完成的应用;
- ApplicationMaster Launcher: 一个应用提交后,负责与NodeManager交互,分配Container并加载ApplicationMaster,也负责终止或销毁;
- YarnScheduler: 资源调度分配, 有FIFO(with Priority),Fair,Capacity方式;
- ContainerAllocationExpirer: 管理已分配但没有启用的Container,超过一定时间则将其回收。
1.2.3.2 NodeManager 节点管理
Node节点下的Container管理。
- 启动时向ResourceManager注册并定时发送心跳消息,等待ResourceManager的指令;
- 监控Container的运行,维护Container的生命周期,监控Container的资源使用情况;
- 启动或停止Container,管理任务运行时的依赖包(根据ApplicationMaster的需要,启动Container之前将需要的程序及其依赖包、配置文件等拷贝到本地)
内部结构
-
NodeStatusUpdater: 启动向ResourceManager注册,报告该节点的可用资源情况,通信的端口和后续状态的维护;
-
ContainerManager: 接收RPC请求(启动、停止),资源本地化(下载应用需要的资源到本地,根据需要共享这些资源)
PUBLIC: /filecache
PRIVATE: /usercache//filecache
APPLICATION: /usercache//appcache//(在程序完成后会被删除)
-
ContainersLauncher: 加载或终止Container;
-
ContainerMonitor: 监控Container的运行和资源使用情况;
-
ContainerExecutor: 和底层操作系统交互,加载要运行的程序。
1.2.3.3 ApplicationMaster 应用管理
单个作业的资源管理和任务监控。
功能描述
- 计算应用的资源需求,资源可以是静态或动态计算的,静态的一般是Client申请时就指定了,动态则需要ApplicationMaster根据应用的运行状态来决定;
- 根据数据来申请对应位置的资源(Data Locality);
- 向ResourceManager申请资源,与NodeManager交互进行程序的运行和监控,监控申请的资源的使用情况,监控作业进度;
- 跟踪任务状态和进度,定时向ResourceManager发送心跳消息,报告资源的使用情况和应用的进度信息;
- 负责本作业内的任务的容错。
ApplicationMaster可以是用任何语言编写的程序,它和ResourceManager和NodeManager之间是通过ProtocolBuf交互,以前是一个全局的JobTracker负责的,现在每个作业都一个,可伸缩性更强,至少不会因为作业太多,造成JobTracker瓶颈。同时将作业的逻辑放到一个独立的ApplicationMaster中,使得灵活性更加高,每个作业都可以有自己的处理方式,不用绑定到MapReduce的处理模式上。
一般的MapReduce是根据Block数量来定Map和Reduce的计算数量,然后一般的Map或Reduce就占用一个Container;数据本地化是通过HDFS的Block分片信息获取的。
1.2.3.4 Container 容器
- 基本的资源单位(CPU、内存等);
- Container可以加载任意程序,而且不限于Java;
- 一个Node可以包含多个Container,也可以是一个大的Container;
- ApplicationMaster可以根据需要,动态申请和释放Container。
1.2.3.5 Failover 故障处理
Job任务失败
-
运行时异常或者JVM退出都会报告给ApplicationMaster;
-
通过心跳来检查挂住的任务(timeout),会检查多次(可配置)才判断该任务是否失效;
-
一个作业的任务失败率超过配置,则认为该作业失败;
-
失败的任务或作业都会有ApplicationMaster重新运行。
ApplicationMaster失败
- ApplicationMaster定时发送心跳信号到ResourceManager,通常一旦ApplicationMaster失败,则认为失败,但也可以通过配置多次后才失败;
- 一旦ApplicationMaster失败,ResourceManager会启动一个新的ApplicationMaster;
- 新的ApplicationMaster负责恢复之前错误的ApplicationMaster的状态(yarn.app.mapreduce.am.job.recovery.enable=true),这一步是通过将应用运行状态保存到共享的存储上来实现的,ResourceManager不会负责任务状态的保存和恢复;
- Client也会定时向ApplicationMaster查询进度和状态,一旦发现其失败,则向ResouceManager询问新的ApplicationMaster。
NodeManager失败
- NodeManager定时发送心跳到ResourceManager,如果超过一段时间没有收到心跳消息,ResourceManager就会将其移除;
- 任何运行在该NodeManager上的任务和ApplicationMaster都会在其他NodeManager上进行恢复;
- 如果某个NodeManager失败的次数太多,ApplicationMaster会将其加入黑名单(ResourceManager没有),任务调度时不在其上运行任务。
ResourceManager失败
- 通过checkpoint机制,定时将其状态保存到磁盘,然后失败的时候,重新运行;
- 通过zookeeper同步状态和实现透明的HA。
1.3 MapReduce
MapReduce的思想就是"分而治之",Map负责 分,Reduce负责 治。
一种分布式的计算方式指定一个Map函数,用来把一组键值对映射成一组新的键值对,指定并发的Reduce(归约)函数,用来保证所有映射的键值对中的每一个共享相同的键组。
map: (K1, V1) → list(K2, V2) combine: (K2, list(V2)) → list(K2, V2) reduce: (K2, list(V2)) → list(K3, V3)
MapReduce主要是先读取文件数据,然后进行Map处理,接着Reduce处理,最后把处理结果写到文件中,因此Map输出格式和Reduce输入格式一定是相同的。
1.3.1 Map
Mapper负责"分",即把复杂的任务分解为若干个"简单的任务"来处理。"简单的任务"包含三层含义:
- 数据或计算的规模相对原任务要大大缩小;
- 就近计算,即任务会分配到存放着所需数据的节点上进行计算;
- 并行计算,彼此间几乎没有依赖关系。
1.3.2 Reduce
Reducer 负责对map阶段的结果进行汇总。至于需要多少个Reducer,用户可以根据具体问题,通过在mapred-site.xml配置文件里设置参数mapred.reduce.tasks的值,默认为1。
1.3.3 读取数据
通过InputFormat决定读取的数据的类型,然后拆分成一个个InputSplit,每个InputSplit对应一个Map处理,RecordReader读取InputSplit的内容给Map。
1.3.3.1 InputFormat 输入格式化
决定读取数据的格式,可以是文件或数据库等。
- 验证作业输入的正确性,如格式等;
- 将输入文件切割成逻辑分片(InputSplit),一个InputSplit将会被分配给一个独立的Map任务;
- 提供RecordReader实现,读取InputSplit中的"K-V对"供Mapper使用。
1.3.3.2 InputSplit 输入分割
代表一个个逻辑分片,并没有真正存储数据,只是提供了一个如何将数据分片的方法,Split内有Location信息,利于数据局部化,一个InputSplit给一个单独的Map处理。
1.3.3.3 RecordReader 记录读者
将InputSplit拆分成一个个<key,value>对给Map处理,也是实际的文件读取分隔对象</key,value>。
1.3.3.4 Mapper 映射器
主要是读取InputSplit的每一个Key,Value对并进行处理
1.3.3.5 Shuffle 清洗器
对Map的结果进行排序并传输到Reduce进行处理 Map的结果并不是直接存放到硬盘,而是利用缓存做一些预排序处理 Map会调用Combiner,压缩,按key进行分区、排序等,尽量减少结果的大小 每个Map完成后都会通知Task,然后Reduce就可以进行处理。
2、配置文件常用参数
bash
[root@master hadoop]# ll
total 116
drwxr-xr-x 2 1024 1024 4096 Jul 29 2022 bin
drwxr-xr-x 3 1024 1024 4096 Jul 29 2022 etc
drwxr-xr-x 2 1024 1024 4096 Jul 29 2022 include
drwxr-xr-x 3 1024 1024 4096 Jul 29 2022 lib
drwxr-xr-x 4 1024 1024 4096 Jul 29 2022 libexec
-rw-rw-r-- 1 1024 1024 24707 Jul 29 2022 LICENSE-binary
drwxr-xr-x 2 1024 1024 4096 Jul 29 2022 licenses-binary
-rw-rw-r-- 1 1024 1024 15217 Jul 17 2022 LICENSE.txt
-rw-rw-r-- 1 1024 1024 29473 Jul 17 2022 NOTICE-binary
-rw-rw-r-- 1 1024 1024 1541 Apr 22 2022 NOTICE.txt
-rw-rw-r-- 1 1024 1024 175 Apr 22 2022 README.txt
drwxr-xr-x 3 1024 1024 4096 Jul 29 2022 sbin
drwxr-xr-x 4 1024 1024 4096 Jul 29 2022 share
[root@master hadoop]# ll etc/hadoop/
total 180
-rw-r--r-- 1 1024 1024 9213 Jul 29 2022 capacity-scheduler.xml
-rw-r--r-- 1 1024 1024 1335 Jul 29 2022 configuration.xsl
-rw-r--r-- 1 1024 1024 2567 Jul 29 2022 container-executor.cfg
-rw-r--r-- 1 1024 1024 970 Jul 11 14:08 core-site.xml # 核心站点配置
-rw-r--r-- 1 1024 1024 3999 Jul 29 2022 hadoop-env.cmd
-rw-r--r-- 1 1024 1024 16721 Jul 11 14:15 hadoop-env.sh # Hadoop环境变量
-rw-r--r-- 1 1024 1024 3321 Jul 29 2022 hadoop-metrics2.properties
-rw-r--r-- 1 1024 1024 11765 Jul 29 2022 hadoop-policy.xml
-rw-r--r-- 1 1024 1024 3414 Jul 29 2022 hadoop-user-functions.sh.example
-rw-r--r-- 1 1024 1024 683 Jul 29 2022 hdfs-rbf-site.xml
-rw-r--r-- 1 1024 1024 1040 Jul 11 14:02 hdfs-site.xml # HDFS配置
-rw-r--r-- 1 1024 1024 1484 Jul 29 2022 httpfs-env.sh
-rw-r--r-- 1 1024 1024 1657 Jul 29 2022 httpfs-log4j.properties
-rw-r--r-- 1 1024 1024 620 Jul 29 2022 httpfs-site.xml
-rw-r--r-- 1 1024 1024 3518 Jul 29 2022 kms-acls.xml
-rw-r--r-- 1 1024 1024 1351 Jul 29 2022 kms-env.sh
-rw-r--r-- 1 1024 1024 1860 Jul 29 2022 kms-log4j.properties
-rw-r--r-- 1 1024 1024 682 Jul 29 2022 kms-site.xml
-rw-r--r-- 1 1024 1024 13700 Jul 29 2022 log4j.properties
-rw-r--r-- 1 1024 1024 951 Jul 29 2022 mapred-env.cmd
-rw-r--r-- 1 1024 1024 1764 Jul 29 2022 mapred-env.sh # MapReduce环境变量
-rw-r--r-- 1 1024 1024 4113 Jul 29 2022 mapred-queues.xml.template
-rw-r--r-- 1 1024 1024 758 Jul 29 2022 mapred-site.xml # MapReduce配置
drwxr-xr-x 2 1024 1024 4096 Jul 29 2022 shellprofile.d
-rw-r--r-- 1 1024 1024 2316 Jul 29 2022 ssl-client.xml.example
-rw-r--r-- 1 1024 1024 2697 Jul 29 2022 ssl-server.xml.example
-rw-r--r-- 1 1024 1024 2681 Jul 29 2022 user_ec_policies.xml.template
-rw-r--r-- 1 1024 1024 10 Jul 29 2022 workers
-rw-r--r-- 1 1024 1024 2250 Jul 29 2022 yarn-env.cmd
-rw-r--r-- 1 1024 1024 6329 Jul 29 2022 yarn-env.sh # YARN环境变量
-rw-r--r-- 1 1024 1024 2591 Jul 29 2022 yarnservice-log4j.properties
-rw-r--r-- 1 1024 1024 690 Jul 29 2022 yarn-site.xml # YARN配置
2.1 core-site.xml
- hadoop.tmp.dir:数据临时存放目录,默认/tmp/hadoop-${user.name};
- fs.defaultFS:定义HDFS文件系统的主机信息与端口号,hdfs://[ip|hostname]:port,hadoop1.x默认端口9000,hadoop2.x默认端口8020;
- io.file.buffer.size:集群读写操作时缓冲区大小,默认4K;
2.2 hdfs-site.xml
- dfs.namenode.name.dir:DFS 名称节点在文件系统内存储名称表 fsimage 的路径,多个目录使用逗号间隔,名称表会复制存储到所有目录中,默认为file://${hadoop.tmp.dir}/dfs/name;
- dfs.datanode.data.dir:DFS 数据节点在文件系统内存储数据的路径,多个目录使用逗号间隔,数据将存储在所有目录中,通常存储在不同设备上,默认为file://${hadoop.tmp.dir}/dfs/data;
- dfs.replication:DFS 数据库的副本数量,默认为3;
- dfs.blocksize:文件系统中块大小,以字节为单位,可以使用k/m/g/t/p/e指定大小,默认为128M;
- dfs.namenode.http-address:WebHDFS UI监听地址与端口,默认为0.0.0.0:50070;
- dfs.webhdfs.enabled:是否启用WebHDFS UI,默认为false,开启为true;
- fs.checkpoint.period:多长时间记录一次hdfs的镜像,默认1小时;
- fs.checkpoint.size:一次记录多大的size的镜像,默认64M。
2.3 mapred-site.xml
若是在etc/hadoop/目录下没有mapred-site.xml文件,倒是有一个mapred-site.xml.template样板,可以复制一份进行修改配置。
- mapreduce.framework.name:指定执行MapReduce作业的运行时框架,属性值可以是local,classic或yarn;
- mapreduce.jobhistory.address:指定查看运行完mapreduce程序的服务器的IP协议的主机名和端口号,默尔为0.0.0.0:10020;
- mapreduce.jobhistory.webapp.address:指定使用WebUI查看mapreduce程序的主机名和端口号,默认为0.0.0.0:19888;
2.4 yarn-site.xml
- yarn.nodemanager.aux-services:指定在进行mapreduce作业时,yarn使用mapreduce_shuffle混洗技术;
- yarn.nodemanager.aux-services.mapreduce_shuffle.class:指定混洗技术对应的字节码文件,value = org.apache.hadoop.mapred.ShuffleHandler;
- yarn.resourcemanager.hostname:指定resourcemanager的主机名,默认为0.0.0.0;
- yarn.resourcemanager.address:指定在RM中的应用程序管理器接口的地址,默认为${yarn.resourcemanager.hostname}:8032;
- yarn.resourcemanager.scheduler.address:指定RM调度程序接口的地址,默认为${yarn.resourcemanager.hostname}:8030;
- yarn.resourcemanager.resource-tracker.address:指定RM下的resource-tracker的地址,默认为${yarn.resourcemanager.hostname}:8031;
- yarn.resourcemanager.admin.address:指定RM管理界面的地址,默认为${yarn.resourcemanager.hostname}:8033;
- yarn.resourcemanager.webapp.address:指定RM的web访问的地址,默认为${yarn.resourcemanager.hostname}:8088;
3、环境安装
3.1 安装包下载
官网安装包下载链接:https://hadoop.apache.org/releases.html
,下载二进制文件即可。
3.2 单机部署
Hadoop单机部署的情况下没有太大必要部署YARN服务,只是单纯部署HDFS作为测试环境完成实验即可。
bash
[root@master tar]# tar -xf hadoop-3.3.4.tar.gz -C /middleware/
[root@master tar]# cd /middleware/
[root@master middleware]# ln -s hadoop-3.3.4/ hadoop
[root@master middleware]# cd hadoop
[root@master hadoop]# ll
total 116
drwxr-xr-x 2 1024 1024 4096 Jul 29 2022 bin
drwxr-xr-x 3 1024 1024 4096 Jul 29 2022 etc
drwxr-xr-x 2 1024 1024 4096 Jul 29 2022 include
drwxr-xr-x 3 1024 1024 4096 Jul 29 2022 lib
drwxr-xr-x 4 1024 1024 4096 Jul 29 2022 libexec
-rw-rw-r-- 1 1024 1024 24707 Jul 29 2022 LICENSE-binary
drwxr-xr-x 2 1024 1024 4096 Jul 29 2022 licenses-binary
-rw-rw-r-- 1 1024 1024 15217 Jul 17 2022 LICENSE.txt
-rw-rw-r-- 1 1024 1024 29473 Jul 17 2022 NOTICE-binary
-rw-rw-r-- 1 1024 1024 1541 Apr 22 2022 NOTICE.txt
-rw-rw-r-- 1 1024 1024 175 Apr 22 2022 README.txt
drwxr-xr-x 3 1024 1024 4096 Jul 29 2022 sbin
drwxr-xr-x 4 1024 1024 4096 Jul 29 2022 share
[root@master hadoop]# vim etc/hadoop/hadoop-env.sh
export JAVA_HOME=/middleware/jdk
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root
[root@master hadoop]# source etc/hadoop/hadoop-env.sh
[root@master hadoop]# ./bin/hadoop version
Hadoop 3.3.4
Source code repository https://github.com/apache/hadoop.git -r a585a73c3e02ac62350c136643a5e7f6095a3dbb
Compiled by stevel on 2022-07-29T12:32Z
Compiled with protoc 3.7.1
From source with checksum fb9dd8918a7b8a5b430d61af858f6ec
This command was run using /middleware/hadoop-3.3.4/share/hadoop/common/hadoop-common-3.3.4.jar
[root@master hadoop]# vim etc/hadoop/core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/middleware/hadoop/</value>
</property>
</configuration>
[root@master hadoop]# vim etc/hadoop/hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.namenode.http-address</name>
<value>0.0.0.0:50070</value>
</property>
</configuration>
[root@master hadoop]# bin/hdfs namenode -format
~
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at master/9.134.244.180
************************************************************/
[root@master hadoop]# tree dfs/
dfs/
└── name
└── current
├── fsimage_0000000000000000000
├── fsimage_0000000000000000000.md5
├── seen_txid
└── VERSION
2 directories, 4 files
[root@master hadoop]# ./sbin/start-dfs.sh
WARNING: HADOOP_SECURE_DN_USER has been replaced by HDFS_DATANODE_SECURE_USER. Using value of HADOOP_SECURE_DN_USER.
Starting namenodes on [localhost]
Last login: Tue Jul 11 13:55:17 CST 2023 from 10.95.19.138 on pts/0
localhost: ssh: connect to host localhost port 22: Connection refused
Starting datanodes
Last login: Tue Jul 11 14:10:44 CST 2023 on pts/0
localhost: ssh: connect to host localhost port 22: Connection refused
Starting secondary namenodes [master]
Last login: Tue Jul 11 14:10:44 CST 2023 on pts/0
master: ssh: connect to host master port 22: Connection refused
[root@master hadoop]# vim etc/hadoop/hadoop-env.sh
export HADOOP_SSH_OPTS="-p 36000"
[root@master hadoop]# ./sbin/start-dfs.sh
3.3 集群部署(推荐)
环境准备:JDK安装与升级 + 集群免密登录。
bash
# 制作密钥文件(持续回车保持默认配置)
[root@master hadoop]# ssh-keygen -t rsa -b 4096 # t为加密算法类型,b为秘钥长度
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): # 秘钥文件存储位置
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:FbNOpySF2pNAo2vR9L53bm91fSgJf/MYnHBwTenf35o root@localhost.localhost
The key's randomart image is:
+---[RSA 4096]----+
| .+ .+ oo|
| +.o.. +. ...|
| o .+o.= .o. |
| o..+*.o. .. |
| o S.oo = o+|
| . . + B B|
| . . .o *=|
| . o. o.+|
| ..oE. |
+----[SHA256]-----+
# 集群节点互相发放密钥文件,首次发放需要进行登录密码验证,三台机器共计发放秘钥文件六次(本机不需要发送到本机)
[root@master hadoop]# ssh-copy-id master
[root@master hadoop]# ssh-copy-id node1
[root@master hadoop]# ssh-copy-id node2
# 配置hosts,将IP替换为当前环境下地址即可
[root@master hadoop]# vim /etc/hosts
# [hadoop_cluster]
$ip1 master
$ip2 node1
$ip3 node2
3.3.1 HDFS
3.3.1.1 部署
bash
# 解压过程省略
[root@master hadoop]# vim etc/hadoop/hadoop-env.sh
export JAVA_HOME=/middleware/jdk
export HADOOP_SSH_OPTS="-p 36000"
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root
[root@master hadoop]# vim etc/hadoop/core-site.xml
<configuration>
<!--指定HDFS的数量-->
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<!--secondary namenode 所在主机的IP和端口-->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>node1:50090</value>
</property>
<property>
<name>dfs.namenode.http-address</name>
<value>master:50090</value>
</property>
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
</configuration>
[root@master hadoop]# vim etc/hadoop/hdfs-site.xml
<configuration>
<!--指定HDFS的数量-->
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<!--secondary namenode 所在主机的IP和端口-->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>node1:50090</value>
</property>
</configuration>
[root@master hadoop]# vim etc/hadoop/mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
[root@master hadoop]# vim etc/hadoop/yarn-site.xml
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>master:8031</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>master:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>master:8034</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>master:8088</value>
</property>
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
</configuration>
[root@master hadoop]# vim workers
master
node1
node2
# 格式化HDFS
[root@master hadoop]# ./bin/hdfs namenode -format
~
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at master/9.134.244.180
************************************************************/
# 启动服务
[root@master hadoop]# ./sbin/start-dfs.sh
Starting namenodes on [master]
Last login: Fri Sep 8 12:30:14 CST 2023 from 10.91.28.109 on pts/2
Starting datanodes
Last login: Fri Sep 8 15:24:19 CST 2023 on pts/1
node2: WARNING: /middleware/hadoop-3.3.4/logs does not exist. Creating.
node1: WARNING: /middleware/hadoop-3.3.4/logs does not exist. Creating.
Starting secondary namenodes [node1]
Last login: Fri Sep 8 15:24:21 CST 2023 on pts/1
# 进程验证
[root@master hadoop]# jps
806826 Jps
801889 DataNode
801667 NameNode
[root@node1 middleware]# jps
1109584 Jps
1095393 DataNode
1095563 SecondaryNameNode
[root@node2 /middleware]# jps
29733 Jps
12063 DataNode
3.3.1.2 验证
HDFS Web端验证:http://9.134.244.180:50090,端口配置参考本文2.1章节core-site.xml中dfs.namenode.http-address参数详解。
bash
HDFS参数详解:
-ls # 查看目录
-mkdir # 创建目录
-rmdir # 删除空目录
-rm # 删除文件或文件夹
-r # 强制删除非空目录
-moveFromLocal # 从本地剪切到HDFS
-copyFromLocal # 从本地复制到HDFS
-copyToLocal # 从HDFS复制到本地
-appendToFile # 追加文件到末尾
-cat # 查看文件内容
-cp # 在HDFS上复制文件
-mv # 在HDFS上移动文件
-get # = copyToLocal
-put # = copyFromLocal
-getmerge # 合并下载多个文件
-tail # 从末尾查看
-chgrp/-chmod/-chwon # 修改文件所属权限
-du # 统计文件夹的大小
-setrep # 设置HDFS中文件副本数(取决于DN数量)
# 上传或下载测试
[root@master hadoop]# echo "this is test!" > ./aaa.txt
[root@master hadoop]# ./bin/hdfs dfs -put ./aaa.txt /
[root@master hadoop]# ./bin/hdfs dfs -ls /
Found 1 items
-rw-r--r-- 3 root supergroup 14 2023-09-11 14:29 /aaa.txt
3.3.1.3 数据存储
HDFS的数据存储路径为core-site.xml内dfs.datanode.data.dir参数的值。
bash
[root@master hadoop]# tree dfs/data/current/BP-1096417423-9.134.244.180-1694157712400/current/finalized/subdir0/subdir0/
dfs/data/current/BP-1096417423-9.134.244.180-1694157712400/current/finalized/subdir0/subdir0/
├── blk_1073741825
├── blk_1073741825_1001.meta
0 directories, 2 files
[root@master hadoop]# cd dfs/data/current/BP-1096417423-9.134.244.180-1694157712400/current/finalized/subdir0/subdir0/
[root@master subdir0]# cat blk_1073741825
this is test!
[root@node1 hadoop]# cd dfs/data/current/BP-1096417423-9.134.244.180-1694157712400/current/finalized/subdir0/subdir0/
[root@node1 subdir0]# cat blk_1073741825
this is test!
[root@node2 hadoop]# cd dfs/data/current/BP-1096417423-9.134.244.180-1694157712400/current/finalized/subdir0/subdir0/
[root@node2 subdir0]# cat blk_1073741825
this is test!
# 三台机器的存储数据完全一致,原因:core-site.xml内dfs.replication的副本数量默认值为3
3.3.2 YARN
3.3.2.1 部署
bash
# 配置MapReduce、YARN并分发到node1与node2
[root@master hadoop]# vimetc/hadoop/mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
[root@master hadoop]# vim etc/hadoop/yarn-site.xml
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>master:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>master:8030</value>
</property>
<property>
<name>yarn.nodemanager.resource-tracker.address</name>
<value>master:8031</value>
</property>
</configuration>
[root@master hadoop]# ./sbin/start-yarn.sh
Starting resourcemanager
Last login: Mon Sep 11 14:35:42 CST 2023 on pts/2
Starting nodemanagers
Last login: Mon Sep 11 15:19:31 CST 2023 on pts/1
# 进程验证
[root@master hadoop]# jps
809885 Jps
809508 NodeManager
809302 ResourceManager
801889 DataNode
801667 NameNode
[root@node1 hadoop]# jps
1095393 DataNode
1117415 Jps
1095563 SecondaryNameNode
1116957 NodeManager
[root@node2 /middleware]# jps
6407 NodeManager
6909 Jps
12063 DataNode
3.3.2.2 验证
YARN Web端验证:http://9.134.244.180:8088,端口配置参考本文2.4章节yarn-site.xml中yarn.resourcemanager.webapp.address参数详解。
bash
# 创建测试环境,上传一个文本文档到HDFS中
[root@master hadoop]# ./bin/hdfs dfs -mkdir -p /input
[root@master hadoop]# vim word.txt
I'm LiHua , a Chinese student taking summer course in your university . I'm writing to ask for help . I came here last month and found my courses interesting .But I have some difficulty with note-taking and I have no idea of how to use the library . I was told the learning center provides help for students and I'm anxious to get help from you. I have no class on Tuesdays mornings and Friday afternoons . Please let me know which day is ok with you. You may email or phone me . Here are my email address and phone number :lihua@1236.com ; 1234567.
[root@master hadoop]# ./bin/hdfs dfs -put ./word.txt /input
# 使用YARN进行文件单词统计操作,输入文件(存储在HDFS服务):/input/word.txt,输出文件:/output/count.txt
[root@master hadoop]# ./bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.4.jar wordcount /input/word.txt /output/count.txt
2023-09-11 15:52:39,678 INFO client.DefaultNoHARMFailoverProxyProvider: Connecting to ResourceManager at master/9.134.244.180:8032
2023-09-11 15:52:39,932 INFO mapreduce.JobResourceUploader: Disabling Erasure Coding for path: /tmp/hadoop-yarn/staging/root/.staging/job_1694418178447_0001
2023-09-11 15:52:42,335 INFO input.FileInputFormat: Total input files to process : 1
2023-09-11 15:52:42,762 INFO mapreduce.JobSubmitter: number of splits:1
2023-09-11 15:52:45,028 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1694418178447_0001
2023-09-11 15:52:45,029 INFO mapreduce.JobSubmitter: Executing with tokens: []
2023-09-11 15:52:45,141 INFO conf.Configuration: resource-types.xml not found
2023-09-11 15:52:45,141 INFO resource.ResourceUtils: Unable to find 'resource-types.xml'.
2023-09-11 15:52:45,326 INFO impl.YarnClientImpl: Submitted application application_1694418178447_0001
2023-09-11 15:52:45,359 INFO mapreduce.Job: The url to track the job: http://master:8088/proxy/application_1694418178447_0001/
2023-09-11 15:52:45,360 INFO mapreduce.Job: Running job: job_1694418178447_0001
2023-09-11 15:52:50,413 INFO mapreduce.Job: Job job_1694418178447_0001 running in uber mode : false
2023-09-11 15:52:50,414 INFO mapreduce.Job: map 0% reduce 0%
2023-09-11 15:52:50,426 INFO mapreduce.Job: Job job_1694418178447_0001 failed with state FAILED due to: Application application_1694418178447_0001 failed 2 times due to AM Container for appattempt_1694418178447_0001_000002 exited with exitCode: 1
Failing this attempt.Diagnostics: [2023-09-11 15:52:49.413]Exception from container-launch.
Container id: container_1694418178447_0001_02_000001
Exit code: 1
[2023-09-11 15:52:49.446]Container exited with a non-zero exit code 1. Error file: prelaunch.err.
Last 4096 bytes of prelaunch.err :
Last 4096 bytes of stderr :
Error: Could not find or load main class org.apache.hadoop.mapreduce.v2.app.MRAppMaster
Please check whether your <HADOOP_HOME>/etc/hadoop/mapred-site.xml contains the below configuration:
<property>
<name>yarn.app.mapreduce.am.env</name>
<value>HADOOP_MAPRED_HOME=${full path of your hadoop distribution directory}</value>
</property>
<property>
<name>mapreduce.map.env</name>
<value>HADOOP_MAPRED_HOME=${full path of your hadoop distribution directory}</value>
</property>
<property>
<name>mapreduce.reduce.env</name>
<value>HADOOP_MAPRED_HOME=${full path of your hadoop distribution directory}</value>
</property>
[2023-09-11 15:52:49.447]Container exited with a non-zero exit code 1. Error file: prelaunch.err.
Last 4096 bytes of prelaunch.err :
Last 4096 bytes of stderr :
Error: Could not find or load main class org.apache.hadoop.mapreduce.v2.app.MRAppMaster
Please check whether your <HADOOP_HOME>/etc/hadoop/mapred-site.xml contains the below configuration:
<property>
<name>yarn.app.mapreduce.am.env</name>
<value>HADOOP_MAPRED_HOME=${full path of your hadoop distribution directory}</value>
</property>
<property>
<name>mapreduce.map.env</name>
<value>HADOOP_MAPRED_HOME=${full path of your hadoop distribution directory}</value>
</property>
<property>
<name>mapreduce.reduce.env</name>
<value>HADOOP_MAPRED_HOME=${full path of your hadoop distribution directory}</value>
</property>
For more detailed output, check the application tracking page: http://master:8088/cluster/app/application_1694418178447_0001 Then click on links to logs of each attempt.
. Failing the application.
2023-09-11 15:52:50,440 INFO mapreduce.Job: Counters: 0
# 失败原因:mapreduce配置缺失
[root@master hadoop]# ./bin/hadoop classpath # 将下面输出的':'修改为','
/middleware/hadoop-3.3.4/etc/hadoop:/middleware/hadoop-3.3.4/share/hadoop/common/lib/*:/middleware/hadoop-3.3.4/share/hadoop/common/*:/middleware/hadoop-3.3.4/share/hadoop/hdfs:/middleware/hadoop-3.3.4/share/hadoop/hdfs/lib/*:/middleware/hadoop-3.3.4/share/hadoop/hdfs/*:/middleware/hadoop-3.3.4/share/hadoop/mapreduce/*:/middleware/hadoop-3.3.4/share/hadoop/yarn:/middleware/hadoop-3.3.4/share/hadoop/yarn/lib/*:/middleware/hadoop-3.3.4/share/hadoop/yarn/*
# 追加配置到MapReduce,并且分发到node1与node2
[root@master hadoop]# vim etc/hadoop/mapred-site.xml
<property>
<name>mapreduce.application.classpath</name>
<value>$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/*:$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/lib/*</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>
<property>
<name>yarn.application.classpath</name>
<value>/middleware/hadoop-3.3.4/etc/hadoop,
/middleware/hadoop-3.3.4/share/hadoop/common/lib/*,
/middleware/hadoop-3.3.4/share/hadoop/common/*,
/middleware/hadoop-3.3.4/share/hadoop/hdfs,
/middleware/hadoop-3.3.4/share/hadoop/hdfs/lib/*,
/middleware/hadoop-3.3.4/share/hadoop/hdfs/*,
/middleware/hadoop-3.3.4/share/hadoop/mapreduce/*,
/middleware/hadoop-3.3.4/share/hadoop/yarn,
/middleware/hadoop-3.3.4/share/hadoop/yarn/lib/*,
/middleware/hadoop-3.3.4/share/hadoop/yarn/*</value>
</property>
# 服务重启
[root@master hadoop]# ./sbin/stop-yarn.sh && ./sbin/start-yarn.sh
Stopping nodemanagers
Last login: Mon Sep 11 15:42:57 CST 2023 on pts/1
master: WARNING: nodemanager did not stop gracefully after 5 seconds: Trying to kill with kill -9
node1: WARNING: nodemanager did not stop gracefully after 5 seconds: Trying to kill with kill -9
Stopping resourcemanager
Last login: Mon Sep 11 16:04:48 CST 2023 on pts/1
Starting resourcemanager
Last login: Mon Sep 11 16:04:56 CST 2023 on pts/1
Starting nodemanagers
Last login: Mon Sep 11 16:04:58 CST 2023 on pts/1
# 重新执行
[root@master hadoop]# ./bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.4.jar wordcount /input/word.txt /output/count.txt
2023-09-11 16:06:15,116 INFO client.DefaultNoHARMFailoverProxyProvider: Connecting to ResourceManager at master/9.134.244.180:8032
2023-09-11 16:06:15,361 INFO mapreduce.JobResourceUploader: Disabling Erasure Coding for path: /tmp/hadoop-yarn/staging/root/.staging/job_1694419501011_0001
2023-09-11 16:06:15,826 INFO input.FileInputFormat: Total input files to process : 1
2023-09-11 16:06:16,259 INFO mapreduce.JobSubmitter: number of splits:1
2023-09-11 16:06:16,591 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1694419501011_0001
2023-09-11 16:06:16,591 INFO mapreduce.JobSubmitter: Executing with tokens: []
2023-09-11 16:06:16,706 INFO conf.Configuration: resource-types.xml not found
2023-09-11 16:06:16,707 INFO resource.ResourceUtils: Unable to find 'resource-types.xml'.
2023-09-11 16:06:16,904 INFO impl.YarnClientImpl: Submitted application application_1694419501011_0001
2023-09-11 16:06:16,945 INFO mapreduce.Job: The url to track the job: http://master:8088/proxy/application_1694419501011_0001/
2023-09-11 16:06:16,945 INFO mapreduce.Job: Running job: job_1694419501011_0001
2023-09-11 16:06:25,035 INFO mapreduce.Job: Job job_1694419501011_0001 running in uber mode : false
2023-09-11 16:06:25,035 INFO mapreduce.Job: map 0% reduce 0%
2023-09-11 16:06:30,080 INFO mapreduce.Job: map 100% reduce 0%
2023-09-11 16:06:35,100 INFO mapreduce.Job: map 100% reduce 100%
2023-09-11 16:06:36,110 INFO mapreduce.Job: Job job_1694419501011_0001 completed successfully
2023-09-11 16:06:36,191 INFO mapreduce.Job: Counters: 54
File System Counters
FILE: Number of bytes read=915
FILE: Number of bytes written=555667
FILE: Number of read operations=0
FILE: Number of large read operations=0
FILE: Number of write operations=0
HDFS: Number of bytes read=654
HDFS: Number of bytes written=601
HDFS: Number of read operations=8
HDFS: Number of large read operations=0
HDFS: Number of write operations=2
HDFS: Number of bytes read erasure-coded=0
Job Counters
Launched map tasks=1
Launched reduce tasks=1
Data-local map tasks=1
Total time spent by all maps in occupied slots (ms)=2216
Total time spent by all reduces in occupied slots (ms)=2858
Total time spent by all map tasks (ms)=2216
Total time spent by all reduce tasks (ms)=2858
Total vcore-milliseconds taken by all map tasks=2216
Total vcore-milliseconds taken by all reduce tasks=2858
Total megabyte-milliseconds taken by all map tasks=2269184
Total megabyte-milliseconds taken by all reduce tasks=2926592
Map-Reduce Framework
Map input records=1
Map output records=106
Map output bytes=980
Map output materialized bytes=915
Input split bytes=98
Combine input records=106
Combine output records=77
Reduce input groups=77
Reduce shuffle bytes=915
Reduce input records=77
Reduce output records=77
Spilled Records=154
Shuffled Maps =1
Failed Shuffles=0
Merged Map outputs=1
GC time elapsed (ms)=99
CPU time spent (ms)=1150
Physical memory (bytes) snapshot=595423232
Virtual memory (bytes) snapshot=5482131456
Total committed heap usage (bytes)=546832384
Peak Map Physical memory (bytes)=325435392
Peak Map Virtual memory (bytes)=2638544896
Peak Reduce Physical memory (bytes)=269987840
Peak Reduce Virtual memory (bytes)=2843586560
Shuffle Errors
BAD_ID=0
CONNECTION=0
IO_ERROR=0
WRONG_LENGTH=0
WRONG_MAP=0
WRONG_REDUCE=0
File Input Format Counters
Bytes Read=556
File Output Format Counters
Bytes Written=601
# 执行完成
[root@master hadoop]# ./bin/hdfs dfs -ls /output/count.txt
Found 2 items
-rw-r--r-- 3 root supergroup 0 2023-09-11 16:06 /output/count.txt/_SUCCESS # 执行结果标识
-rw-r--r-- 3 root supergroup 601 2023-09-11 16:06 /output/count.txt/part-r-00000 # 执行结果
[root@master hadoop]# ./bin/hdfs dfs -cat /output/count.txt/part-r-00000
, 1
. 5
.But 1
1234567. 1
:lihua@1236.com 1
~
# 结果太多,此处省略
新任务job_1694419501011_0001执行成功,网页展示如下:
点击任务可查看详细信息:Attempt:应用Application的尝试任务;Logs:尝试任务日志;Node:执行尝试任务节点。
Attempt尝试任务详情:
- Num Node Local Containers (satisfied by)表示在同一节点上启动任务的容器数量。即,任务需要的资源可以满足在同一节点上启动,而不需要通过网络从其他节点上获取资源的容器数量。
- Num Rack Local Containers (satisfied by)表示在同一机架上启动任务的容器数量。即,任务需要的资源可以从同一机架上的其他节点上获取,而不需要通过网络从不同机架上获取资源的容器数量。
- Num Off Switch Containers (satisfied by)表示需要跨机架获取资源的容器数量。即,任务需要的资源无法从同一机架上的其他节点上获取,而需要通过网络从不同机架上获取资源的容器数量。
这些指标对于优化Hadoop集群的性能和资源利用率非常重要。例如,如果Num Node Local Containers的数量太少,可能表示某些节点的资源利用率不足;如果Num Off Switch Containers的数量太多,可能表示集群的网络拓扑结构需要优化。
3.3.2.3 资源控制
YARN资源控制流程如下:
- MR程序提交到客户端所在的节点;
- YarnRunner向ResourceManager申请一个Application;
- RM将该应用程序的资源路径返回给YarnRunner;
- 该程序将运行所需资源提交到HDFS上;
- 程序资源提交完毕后,申请运行mrAppMaste;
- RM将用户的请求初始化成一个Task;
- 其中一个NodeManager领取到Task任务;
- 该NodeManager创建容器Container,并产生MRAppmaster;
- Container从HDFS上拷贝资源到本地;
- MRAppmaster向RM 申请运行MapTask资源;
- RM将运行MapTask任务分配给另外两个NodeManager,另两个NodeManager分别领取任务并创建容器;
- MR向两个接收到任务的NodeManager发送程序启动脚本,这两个NodeManager分别启动MapTask,MapTask对数据分区排序;
- MrAppMaster等待所有MapTask运行完毕后,向RM申请容器,运行ReduceTask;
- ReduceTask向MapTask获取相应分区的数据;
- 程序运行完毕后,MR会向RM申请注销自己;
YARN执行任务案例:
bash
[root@master hadoop]# ./bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.4.jar wordcount /input/word.txt /output/count.txt
2023-09-12 11:03:02,112 INFO client.DefaultNoHARMFailoverProxyProvider: Connecting to ResourceManager at master/9.134.244.180:8032 # 客户端申请RM连接
2023-09-12 11:03:02,385 INFO mapreduce.JobResourceUploader: Disabling Erasure Coding for path: /tmp/hadoop-yarn/staging/root/.staging/job_1694487467398_0001 # RM返回客户端HDFS的job id存储路径
# 插入当时查看记录
[root@master bin]# ./hdfs dfs -ls /tmp/hadoop-yarn/staging/root/.staging/job_1694487467398_0002
Found 6 items
-rw-r--r-- 10 root supergroup 280990 2023-09-12 11:23 /tmp/hadoop-yarn/staging/root/.staging/job_1694487467398_0002/job.jar
-rw-r--r-- 10 root supergroup 105 2023-09-12 11:23 /tmp/hadoop-yarn/staging/root/.staging/job_1694487467398_0002/job.split
-rw-r--r-- 3 root supergroup 34 2023-09-12 11:23 /tmp/hadoop-yarn/staging/root/.staging/job_1694487467398_0002/job.splitmetainfo
-rw-r--r-- 3 root supergroup 236995 2023-09-12 11:23 /tmp/hadoop-yarn/staging/root/.staging/job_1694487467398_0002/job.xml
-rw-r--r-- 3 root supergroup 0 2023-09-12 11:23 /tmp/hadoop-yarn/staging/root/.staging/job_1694487467398_0002/job_1694487467398_0002_1.jhist
-rw-r--r-- 3 root supergroup 273861 2023-09-12 11:23 /tmp/hadoop-yarn/staging/root/.staging/job_1694487467398_0002/job_1694487467398_0002_1_conf.xml
2023-09-12 11:03:03,491 INFO input.FileInputFormat: Total input files to process : 1 # 需要处理的文件总数
2023-09-12 11:03:03,993 INFO mapreduce.JobSubmitter: number of splits:1
2023-09-12 11:03:04,356 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1694487467398_0001 # 任务令牌
2023-09-12 11:03:04,356 INFO mapreduce.JobSubmitter: Executing with tokens: []
2023-09-12 11:03:04,477 INFO conf.Configuration: resource-types.xml not found
2023-09-12 11:03:04,477 INFO resource.ResourceUtils: Unable to find 'resource-types.xml'.
2023-09-12 11:03:04,667 INFO impl.YarnClientImpl: Submitted application application_1694487467398_0001 # 提交的job任务
2023-09-12 11:03:04,703 INFO mapreduce.Job: The url to track the job: http://master:8088/proxy/application_1694487467398_0001/
# 跟踪查看job任务执行的URL
2023-09-12 11:03:04,704 INFO mapreduce.Job: Running job: job_1694487467398_0001 # 运行中的job任务
2023-09-12 11:03:12,785 INFO mapreduce.Job: Job job_1694487467398_0001 running in uber mode : false
2023-09-12 11:03:12,785 INFO mapreduce.Job: map 0% reduce 0% # MapReduce进度
2023-09-12 11:03:16,824 INFO mapreduce.Job: map 100% reduce 0% # 当Map执行完成开始Reduce
2023-09-12 11:03:21,846 INFO mapreduce.Job: map 100% reduce 100% # Map+Reduce均完成
2023-09-12 11:03:22,855 INFO mapreduce.Job: Job job_1694487467398_0001 completed successfully # job任务完成标识
2023-09-12 11:03:22,934 INFO mapreduce.Job: Counters: 54
File System Counters # 文件系统计数统计
FILE: Number of bytes read=915
FILE: Number of bytes written=555663
FILE: Number of read operations=0
FILE: Number of large read operations=0
FILE: Number of write operations=0
HDFS: Number of bytes read=654
HDFS: Number of bytes written=601
HDFS: Number of read operations=8
HDFS: Number of large read operations=0
HDFS: Number of write operations=2
HDFS: Number of bytes read erasure-coded=0
Job Counters # job任务计数统计
Launched map tasks=1
Launched reduce tasks=1
Data-local map tasks=1
Total time spent by all maps in occupied slots (ms)=2280
Total time spent by all reduces in occupied slots (ms)=1981
Total time spent by all map tasks (ms)=2280
Total time spent by all reduce tasks (ms)=1981
Total vcore-milliseconds taken by all map tasks=2280
Total vcore-milliseconds taken by all reduce tasks=1981
Total megabyte-milliseconds taken by all map tasks=2334720
Total megabyte-milliseconds taken by all reduce tasks=2028544
Map-Reduce Framework # MapReduce框架信息
Map input records=1
Map output records=106
Map output bytes=980
Map output materialized bytes=915
Input split bytes=98
Combine input records=106
Combine output records=77
Reduce input groups=77
Reduce shuffle bytes=915
Reduce input records=77
Reduce output records=77
Spilled Records=154
Shuffled Maps =1
Failed Shuffles=0
Merged Map outputs=1
GC time elapsed (ms)=72
CPU time spent (ms)=880
Physical memory (bytes) snapshot=553959424
Virtual memory (bytes) snapshot=5285777408
Total committed heap usage (bytes)=591921152
Peak Map Physical memory (bytes)=327335936
Peak Map Virtual memory (bytes)=2640453632
Peak Reduce Physical memory (bytes)=226623488
Peak Reduce Virtual memory (bytes)=2645323776
Shuffle Errors # Shuffle错误统计
BAD_ID=0
CONNECTION=0
IO_ERROR=0
WRONG_LENGTH=0
WRONG_MAP=0
WRONG_REDUCE=0
File Input Format Counters # 文件输入格式计数器
Bytes Read=556
File Output Format Counters # 文件输出格式计数器
Bytes Written=601
3.3.3 集群控制脚本
bash
#!/bin/bash
read -p "please input 'hdfs/yarn/all/help':" a1
cd /middleware/hadoop/sbin # hadoop安装路径
case ${a1:-help} in
hdfs )
read -p "please input 'start/stop/restart':" b2
case ${b2:-help} in
start )
bash start-dfs.sh
;;
stop )
bash stop-dfs.sh
;;
restart )
bash stop-dfs.sh && bash start-dfs.sh
;;
* )
echo "ERROR,please input 'start/stop/restart'!"
;;
esac
;;
yarn )
read -p "please input 'start/stop/restart':" c3
case ${c3:-help} in
start )
bash start-yarn.sh
;;
stop )
bash stop-yarn.sh
;;
restart )
bash stop-yarn.sh && bash start-yarn.sh
;;
* )
echo "ERROR,please input 'start/stop/restart'!"
;;
esac
;;
all )
read -p "please input 'start/stop/restart':" d4
case ${d4:-help} in
start )
bash start-all.sh
;;
stop )
bash stop-all.sh
;;
restart )
bash stop-all.sh && bash start-all.sh
;;
* )
echo "ERROR,please input 'start/stop/restart'!"
;;
esac
;;
* )
echo "ERROR,please input 'hdfs/yarn/all/help'!"
;;
esac
cd - > /dev/null 2>&1
4、常见操作
4.1 NN异常恢复
模拟NN节点异常,将SNN fsimage数据导入NN进行恢复的场景。
bash
[root@master hadoop]# kill -9 19514 # NameNode进程
1.2
[root@node1 hadoop]# ll dfs/
total 8
drwx------ 3 root root 4096 Sep 11 14:35 data
drwxr-xr-x 3 root root 4096 Sep 11 14:35 namesecondary
# 备份NN数据
[root@master hadoop]# mkdir /tmp/nn_backup/
[root@master hadoop]# mv dfs/name/* /tmp/nn_backup/
# 将SNN的数据拷贝到NN
[root@node1 hadoop]# scp -r -P 36000 dfs/namesecondary/* master:/middleware/hadoop/dfs/name/
# 导入元数据
[root@master hadoop]# ./bin/hadoop namenode --importCheckpoint
# 启动HDFS
[root@master hadoop]# ./sbin/start-dfs.sh
# 导入fsimage文件后,可能需要等待一段时间才能完成所有块的复制和状态更新。在此期间,HDFS可能无法对外提供完全正常的服务
4.2 安全模式
HDFS集群正常开启时处于短暂的安全模式,不能执行重要操作(写操作),待集群启动完成后,自动退出安全模式。
bash
# 查看
[root@master hadoop-1]# ./bin/hdfs dfsadmin -safemode get
Safe mode is OFF
# 开启
[root@master hadoop-1]# ./bin/hdfs dfsadmin -safemode enter
Safe mode is ON
# 关闭
[root@master hadoop-1]# ./bin/hdfs dfsadmin -safemode leave
Safe mode is OFF
# 等待
[root@master hadoop-1]# ./bin/hdfs dfsadmin -safemode wait
Safe mode is OFF
4.3 数据平衡
新加入的节点,没有数据块的存储,或HDFS长期使用过程发现其数据分布不均衡,部分节点远超其他节点时,使得集群整体来看负载还不均衡。因此需要对HDFS数据存储设置负载均衡。
bash
# 默认的数据传输带宽比较低,可以设置为64M
[root@master hadoop]# ./bin/hdfs dfsadmin -setBalancerBandwidth 67108864
# 默认balancer的threshold为10%(各个节点与集群总的存储使用率相差不超过10%)
[root@master hadoop]# ./sbin/start-balancer.sh -threshold 5
4.4 集群扩/缩容
4.4.1 扩容
bash
# 配置免密登录,参考本文3.3章节环境准备操作
[root@master hadoop]# ssh-keygen -t rsa -b 4096
# 下发密钥到其他节点,并拷贝其他节点密钥到本地,共计6次(对外3次,对内3次)
[root@master hadoop]# ssh-copy-id master
# 附加hosts
[root@node3 hadoop]# vim /etc/hosts
~
$ip4 node3
# 附加workers
[root@node3 hadoop]# vim workers
~
node3
# 启动node3 DdataNode与NodeManager
[root@node3 hadoop]# hadoop-daemon.sh start datanode
[root@node3 hadoop]# yarn-daemon.sh start nodemanager
# 可以使用工具查看YARN NM机器列表;HDFS DN列表可通过浏览器查看ip:50090中DataNodes页面
[root@master hadoop]# ./bin/yarn node -list
2023-09-12 14:28:47,291 INFO client.DefaultNoHARMFailoverProxyProvider: Connecting to ResourceManager at master/9.134.244.180:8032
Total Nodes:4
Node-Id Node-State Node-Http-Address Number-of-Running-Containers
master:41295 RUNNING master:8042 0
node2:38853 RUNNING node2:8042 0
node1:41665 RUNNING node1:8042 0
node3:41573 RUNNING node3:8042 0
# 开启node3为DN后数据块不会立刻存储到node3上,可以使用数据平衡操作重新平衡数据分配
[root@node3 hadoop]# ./bin/hdfs dfsadmin -setBalancerBandwidth 104857600
[root@node3 hadoop]# ./bin/hdfs balancer -threshold 1 # 集群数据较少,因此阈值设置为1,平衡操作参考本文4.3章节,等待集群自均衡完成即可
4.4.2 缩容
DataNode缩容不像扩容那样启动一个节点即可, 缩容需要把当前节点数据移出去,Hadoop已经提供了下线功能,前提是在NameNode机器的hdfs-site.xml配置文件中需要提前配置dfs.hosts.exclude属性,该属性指向的文件就是所谓的黑名单列表,会被NameNode排除在集群之外。如果文件内容为空,则意味着不禁止任何机器。所以在安装Hadoop的时候就需要指定好改配置,如果最开始没有配置该参数,则需要添加后重启NameNode 。
bash
# 在NameNode所在服务器的配置目录etc/hadoop下创建dfs.hosts.exclude文件,并添加需要退役的主机名称。
[root@master hadoop]# vim hdfs-site.xml
~
<property>
<name>dfs.hosts.exclude</name>
<value>/middleware/hadoop/etc/hadoop/excludes</value>
</property>
# 重启NN使其配置生效
[root@master hadoop]# vim /middleware/hadoop/etc/hadoop/excludes
node3
# 如果副本数是3,在线的节点小于等于3,是不能下线成功的,需要修改副本数后才能下线。
# 刷新NameNode、刷新ResourceManager进程
[root@master hadoop]# ./bin/hdfs dfsadmin -refreshNodes
[root@master hadoop]# ./bin/yarn rmadmin --refreshNodes
# 等待退役节点状态为decommissioned(所有块已经复制完成),停止该节点及节点资源管理器
# 停止node3进程
[root@master hadoop]# ./sbin/hadoop-daemon.sh stop datanode
[root@master hadoop]# ./sbin/yarn-daemon.sh stop nodemanager
4.5 回收站
在HDFS中删除的文件不会直接彻底清掉,会先丢弃到回收站中(HDFS回收站路径:/user/root/.Trash/),过一段时间之后,自动清空垃圾桶当中的文件。
在core-site.xml配置中fs.trash.interval=0代表禁用回收站,大于0时表示启用回收站,以分钟为单位的垃圾回收时间;默认值fs.trash.checkpoint.interval=0,如果是0,值等同于fs.trash.interval,以分钟为单位的垃圾回收检查间隔。要求fs.trash.checkpoint.interval<=fs.trash.interval。
bash
[root@master hadoop]# vim core-site.xml
<!-- 开启hdfs的垃圾桶机制,删除掉的数据可以从垃圾桶中回收,单位分钟 -->
<property>
<name>fs.trash.interval</name>
<value>10</value>
</property>
[root@master hadoop]# ./sbin/stop-dfs.sh && ./sbin/start-dfs.sh
# 测试删除
[root@master hadoop]# ./bin/hdfs dfs -put ./aaa.txt /delete.txt
[root@master hadoop]# ./bin/hdfs dfs -rm /delete.txt
2023-09-11 19:37:43,757 INFO fs.TrashPolicyDefault: Moved: 'hdfs://master:9000/delete.txt' to trash at: hdfs://master:9000/user/root/.Trash/Current/delete.txt
[root@master hadoop]# ./bin/hdfs dfs -ls /user/root/.Trash/Current/
Found 1 items
-rw-r--r-- 3 root supergroup 14 2023-09-11 19:37 /user/root/.Trash/Current/delete.txt
# 恢复数据
[root@master hadoop]# ./bin/hadoop fs -mv /user/root/.Trash/Current/delete.txt /
[root@master hadoop]# ./bin/hdfs dfs -ls /delete.txt
-rw-r--r-- 3 root supergroup 14 2023-09-11 19:37 /delete.txt
# 清空回收站
[root@master bin]# ./hadoop fs -expunge
2023-09-12 11:02:07,077 INFO fs.TrashPolicyDefault: TrashPolicyDefault#deleteCheckpoint for trashRoot: hdfs://master:9000/user/root/.Trash
2023-09-12 11:02:07,077 INFO fs.TrashPolicyDefault: TrashPolicyDefault#deleteCheckpoint for trashRoot: hdfs://master:9000/user/root/.Trash
2023-09-12 11:02:07,087 INFO fs.TrashPolicyDefault: TrashPolicyDefault#createCheckpoint for trashRoot: hdfs://master:9000/user/root/.Trash
2023-09-12 11:02:07,094 INFO fs.TrashPolicyDefault: Created trash checkpoint: /user/root/.Trash/230912110207
4.6 Snapshot 快照
Snapshot是HDFS整个文件系统,或者某个目录在某个时刻的镜像。**快照不是数据的简单拷贝,快照只做差异的记录!**HDFS 快照的核心功能包括:数据恢复、数据备份、数据测试。
- 差异拷贝:在 HDFS 中,如果在其中一个目录比如/A下创建一个快照,则快照文件中将会存在与/A目录下完全一致的子目录文件结构以及相应的属性信息,通过命令也能看到快照里面具体的文件内容。但是这并不意味着快照已经对此数据进行完全的拷贝 。这里遵循一个原则:对于大多不变的数据,你所看到的数据其实是当前物理路径所指的内容,而发生变更的inode数据才会被快照额外拷贝;
- HDFS快照不会复制Datanode中的块,只记录了块列表和文件大小;
- HDFS快照不会对常规HDFS操作产生不利影响,修改记录按逆时针顺序进行,因此可以直接访问当前数据,通过从当前数据中减去修改来计算快照数据;
4.6.1 操作命令
HDFS 中可以针对整个文件系统或者文件系统中某个目录创建快照,但是创建快照的前提是相应的目录开启快照的功能。
bash
# 启用快照功能
[root@master hadoop]# ./hdfs dfsadmin -allowSnapshot $path
# 禁用快照功能
[root@master hadoop]# ./hdfs dfsadmin -disallowSnapshot $path
# 对目录创建快照
[root@master hadoop]# ./hdfs dfs -createSnapshot $path
# 指定名称创建快照
[root@master hadoop]# ./hdfs dfs -createSnapshot $path $name
# 重命名快照
[root@master hadoop]# ./hdfs dfs -renameSnapshot $path $name1 $name2
# 列出当前用户所有可快照目录
[root@master hadoop]# ./hdfs lsSnapshottableDir
# 比较两个快照目录的不同之处
[root@master hadoop]# ./hdfs snapshotDiff $path1 $path2
# # 删除快照
[root@master hadoop]# ./hdfs dfs -deleteSnapshot $path $name
4.6.2 快照使用
4.6.2.1开启快照
bash
[root@master hadoop]# ./bin/hdfs dfsadmin -allowSnapshot /input
Allowing snapshot on /input succeeded
4.6.2.2 对指定目录创建快照
bash
[root@master hadoop]# ./bin/hdfs dfs -createSnapshot /input
Created snapshot /input/.snapshot/s20230912-144829.624
bash
[root@master hadoop]# ./bin/hdfs dfs -createSnapshot /input mysnap1
Created snapshot /input/.snapshot/mysnap1
4.6.2.3 重命名快照
bash
[root@master hadoop]# ./bin/hdfs dfs -renameSnapshot /input mysnap1 mysnap2
Renamed snapshot mysnap1 to mysnap2 under hdfs://master:9000/input
4.6.2.4 列出当前用户所有可以快照的目录
bash
[root@master hadoop]# ./bin/hdfs lsSnapshottableDir
drwxr-xr-x 0 root supergroup 0 2023-09-12 14:49 2 65536 /input
4.6.2.5 比较两个快照不同之处
bash
[root@master hadoop]# echo 222 > 2.txt
[root@master hadoop]# ./bin/hadoop fs -appendToFile 2.txt /input/1.txt
[root@master hadoop]# ./bin/hadoop fs -cat /input/1.txt
222
[root@master hadoop]# ./bin/hdfs dfs -createSnapshot /input mysnap3
Created snapshot /input/.snapshot/mysnap3
[root@master hadoop]# ./bin/hadoop fs -put 2.txt /input
[root@master hadoop]# ./bin/hdfs dfs -createSnapshot /input mysnap4
Created snapshot /input/.snapshot/mysnap4
[root@master hadoop]# ./bin/hdfs snapshotDiff /input mysnap2 mysnap4
Difference between snapshot mysnap2 and snapshot mysnap4 under directory /input:
M .
+ ./1.txt
+ ./2.txt
# 表头备注:
# + The file/directory has been created.
# - The file/directory has been deleted.
# M The file/directory has been modified.
# R The file/directory has been renamed.
4.6.2.6 删除快照
bash
[root@master hadoop]# ./bin/hdfs dfs -deleteSnapshot /input mysnap4
Deleted snapshot mysnap4 under hdfs://master:9000/input
4.6.2.7 删除有快照的目录
bash
# 拥有快照的目录不允许被删除(强制-r仍不可删除),某种程度上也保护了文件安全
[root@master hadoop]# ./bin/hadoop fs -rm -r /input
rm: Failed to move to trash: hdfs://master:9000/input: The directory /input cannot be deleted since /input is snapshottable and already has snapshots
5、错误记录
5.1 Java版本不兼容
java版本过高,与当前Hadoop部分代码不兼容导致功能异常,报错如下:
降低Java版本,本环境使用TencentJDK 17(为何不用Oracle JDK的原因:虚拟机为测试机器,版权问题无法使用),降低为TencentJDK 8。
bash
[root@node2 ~]# tar -xf /root/TencentKona8.0.15.b2_jdk_linux-x86_64_8u382.tar.gz -C /middleware/
[root@node2 ~]# cd /middleware/
# 由于之前JDK部署为软链接,因此降低版本只需要更新软链接即可
export JAVA_HOME=/middleware/jdk
export PATH=${JAVA_HOME}/bin:$PATH
export CLASSPATH=.:${JAVA_HOME}/lib
[root@node2 /middleware]# unlink jdk
[root@node2 /middleware]# ln -s TencentKona-8.0.15-382/ jdk
[root@node2 /middleware]# source /etc/profile
[root@node2 /middleware]# java -version
openjdk version "1.8.0_382"
OpenJDK Runtime Environment (Tencent Kona 8.0.15) (build 1.8.0_382-b2)
OpenJDK 64-Bit Server VM (Tencent Kona 8.0.15) (build 25.382-b2, mixed mode, sharing)
# 重启服务
[root@master hadoop]# ./sbin/stop-dfs.sh && ./sbin/start-dfs.sh
重新使用浏览器登录或刷新页面即可查看到数据展示正常。
5.2 无法正常查看文件内容
上传一个文件后,使用Head eth file或Tail the file时无法正常查看文件内容,报错如下:
这是因为机器内部发送请求为http://node2:9864/webhdfs/v1/aaa.txt
请求时,当前物理机器无法识别node2的ip地址导致异常,需要更改本地Hosts,添加master、node1、node2三个机器的ip地址。
-
MAC:/etc/hosts
-
Windows:C:\Windows\System32\drivers\etc\hosts
修改完成后刷新页面重新访问即可恢复。