二 、 HDFS体系结构
HDFS 采用的是master/slave架构设计 , 一个HDFS集群包含一个单独的 NameNode 和多个DataNode。
2.1 HDFS 组件及作用
NameNode (名称节点)负责整个分布式系统的元数据 , 主要包括:
1) 目录树结构
2) 文件到数据库block的映射关系。
3) block副本及存储位置等管理数据。
4) DataNode 的状态监控。两者通过时间间隔的心跳来传递管理信息和数据信息 , 通过这种方式的信传递 , NameNode 可以获取每个DataNode 保存的 block信息。DataNode 的健康状态。命令DataNode启动停止等 , (如果发现某个DataNode节点故障 , namenode 会将其负责的block 在其他 DataNode 上进行备份)。这些数据保存在内存中 , 同时在磁盘保存两个元数据管理文件 , fsimage(镜像文件) 和editlog(编辑日志)
5) fsimage : 是内存命名空间元数据在外村的镜像文件;
6) editlog : 是各种元数据操作的 write-ahead-log (写入之前日志)文件 , 在体现带内存数据变化前首先会将操作记入editlog中 , 以防止数据丢失。
fsimage 和 editlog 两个文件相结合可以构造完整的内存数据。
Secondary NameNode
1) Secondary NameNode (辅助名称节点) 并不是 NameNode 的热备机 , 而是定期从 NameNode 拉去 fsimage 和 editlog 文件 , 并对这两个文件进行合并 , 形成新的 fsimage 文件并传回 NameNode , 这样做的目的是为了减轻 NameNode 的工作压力 , 本质上 Secondary NameNode 是一个提供检查点功能服务的服务点。
DataNode (数据节点)
1) 负责数据库的实际存储和读写工作 , block默认为64MB (HDFS 2.0 将其改成了128MB) , 当客户端上传一个大文件时 , HDFS 会自动将其切割成固定大小的block , 为了保证数据的可用性 , 每个block会以多备份的形式存储 , 默认为三份。
2.2 HDFS 文件写入过程
1) client 调用 DistributedFileSystem (分布式文件系统) 对象的create 方法 , 创建一个文件输出流(FSDataOutputStream) 对象;
2) 通过 DistributedFileSystem 对象与集群的 NameNode 进行一次 RPC 远程调用 , 在 HDFS 的 Namespace (命名空间) 中创建一个文件条目(Entry) , 此时该条目没有任何 block , NameNode 会返回该数据每一个块需要拷贝的 DataNode 地址信息;
3) 通过 FSDataOutputStream 对象, 开始向 DataNode 写入数据 ,数据首选in被写入 FSDataOutputStream 对象内部的数据队列中,数据队列由 DataStreamer 使用,它通过选择合适的 DataNode 列表来存储副本 , 从何要求 NameNode 分配新的block ;
4) DataStreamer 将数据包以流形式传输的方式传输到分配的第一个 DataNode 中 , 该数据流将数据包存储到第一个 DataNode 中并将其转发到第二个 DataNode 中, 接着第二个 DataNode 节点会将数据包转发到第三个 DataNode 节点;
5) DataNode 确认数据纯属完成,最后由第一个 DataNode 通知 client 数据写入成功;
6) 完成想文件写入数据, client 在文件输出流(FSDataOutputStream) 对象上调用 close 方法,完成文件写入;
7) 调用 DistributedFileSystem (分布式文件系统) 对象的 complete 方法 , 通知 NameNode 文件写入成功, NameNode 会将相关结果记录到 editlog 中.
2.3 HDFS 文件读取过程
1) client 通过 DistributedFileSystem 对象与集群的 NameNode 进行一次 RPC 远程调用, 获取文件 block位置信息;
2) NameNode 返回存储的每一个块的 DataNode 列表;
3) client 将连接到列表中最近的 DataNode ;
4) 一旦 client 获得了所有必须的 block , 它就会将这些 block 组合起来形成一个文件.
在处理 client 的读取请求时, HDFS 会利用机架感知选举最接近 client 位置的副本, 这将会减少读取延迟和带宽消耗 .
2.4 HDFS 1.0 存在的问题及 2.0提供的解决方案
HDFS 1.0 存在的问题
1) NameNode 的单点问题, 如果 NameNode 挂掉了 , 数据读写都会受到影响 , HDFS 整体将变得不可用 , 这种情况在生产环境中是不可接受的;
2) 水平扩展问题 , 随着集群规模的扩大 , 1.0时集群规模达到了3000时,会导致整个句群的文件数目达到上限(因为 NameNode 要管理整个集群的 block 信息, 数据目录信息等)
HDFS 2.0提供了统一的解决方案:
1) HA (High Availbility 高可用方案): 这个是为了解决 NameNode 的单点问题.
2) NameNode Federation : 是用来解决 HDFS 集群的线性扩展能力.
2.5 HDFS 2.0 的 HA 实现
1) Active NameNode 和 Standby NameNode , 两台 NameNode 形成互备 , 一台处于 Active 状态, 为主 NameNode , 另一台处于 Secondary 状态 , 为备用 NameNode , 只有主 NameNode 才能对外提供读写服务;
2) ZKFailoverController (主备切换控制器, FC) , ZKFailoverController 作为独立的进程运行 , 对 NameNode 的主备切换进行总体控制 . ZKFailoverController 能及时检测到 NameNode 的健康状态, 在主 NameNode 故障时借助 Zookeeper 实现自动的主备选举和切换(NameNode 目前不支持依赖于 Zookeeper 的手动主备切换);
3) Zookeeper 集群 , 为主备切换控制器提供主备选举支持 ;
4) 共享存储系统 , 共享存储系统是实现 NameNode 的高可用最为关键的部分 , 共享存储系统保存了 NameNode 在运行过程中产生的 HDFS 的元数据 . 主 NameNode 和备用 NameNode 通过共享存储系统实现数据同步 , 在进行主备切换的时候, 新的主 NameNode 在确认元数据完全同步之后才能继续对外提供服务.
5) DataNode 节点 , 因为主 NameNode 和 备用 NameNode 需要共享 HDFS 的数据块和 DataNode 之间的映射关系 , 为了使故障切换能够快速进行 , DataNode 会同时向主 NameNode 和备用 NameNode 上报数据块的位置信息.
2.6 HDFS Failovercontroller (失效备援控制器)
Failovercontroller 最初的目的是为了实现 Standby NameNode 和 Active NameNode 之间故障自动切换 , Failovercontroller 是独立与 NameNode 之外的故障切换控制器 , ZKFailoverController 作为 NameNode 机器上独立的进程启动 , 它启动的时候回创建 HealthMonitor (健康监听器)和 ActivStandbyElector (活跃备用选举) 这两个主要的内部组件 ,
1) HealthMonitor : 主要负责检测 NameNode 的健康状态 , 如果检测到 NameNode 的状态发生变化 , 会回调 ZKFailoverController 的相应方法进行自动的主备选举.
2) ActivStandbyElector : 主要负责完成自动的主备选举, 内部封装了 Zookeeper 的处理逻辑, 一旦 Zookeeper 主备选举完成 , 会回调 ZKFailoverController 的相应方法来进行 NameNode 的主备状态切换.
2.7 HDFS 脑裂问题
在实际中, NameNode 可能会出现这种情况, NameNode 在垃圾回收(GC) 时 , 可能在长时间内整个系统无响应, 因此, 也就无法向 ZK 写入心跳信息 , 这样的话可能会导致临时节点掉线, 备用 NameNode 会切换到 Active 状态, 在这种情况下, 可能会导致整个集群会有同时两个 NameNode 这就是脑裂问题
解决方案: 通过隔离(Fencing) , 主要是在以下三处采用隔离措施
1) 地撒放共享存储:任何时刻只有一个 NameNode 可以写入
2) DataNode 需要保证只有一个 NameNode 发出管理数据副本有关的删除命令;
3) client 需要保证同一时刻只有一个 NameNode 能够对 client 的请求发出正确的响应
实现方法如下:
1) ActivStandbyElector 为了实现 Fencing , 会在成功创建 Zookeeper 节点 hadoop-ha/${dfs.nameservices}/ActivStandbyElectorLock 从而为 Active NameNode 之后 , 创建另一个路径为 /hadoop-ha/$(dfs.nameservices)/ActiveBreadCrumb 的持久节点, 这个节点里面保存了这个 Active NameNode 的地址信息;
2) Active NameNode 的 ActivStandbyElector 在正常的状态下关闭 Zookeeper Seeion 的时候, 会删除这个持久节点;
3) 但如果 ActivStandbyElector 在异常的状态下 Zookeeper Seeion 关闭(比如前述的 Zookeeper 假死), 那么由于 /hadoop-ha/${dfs.nameservices}/ActiveBreadCrumb 是持久节点, 会一直保留下来,后面当另一个 NameNode 选主成功之后, 会注意到上一个 Active NameNode 遗留下来的这个节点, 从而会回调 ZKFailoverController 的方法对旧的 Active NameNode 进行 Fencing.
在进行隔离的时候, 会进行以下操作;
1) 首先尝试调用这个旧 Active NameNode 的HAServiceProtocolRPC 接口的 transitionToStandby 方法, 看能不能把它转换为 Standby 状态;
2) 如果 transitionToStandby 方法调用失败, 那么会执行 Hadoop 配置文件之中预定义的隔离措施.
Hadoop 目前主要提供两种隔离措施 , 但是通常会选择第一种
1) sshfence : 通过 SSH 登录到目标机器上, 执行 fuser 将对应的进程杀死;
2) shellfence: 执行一个用户自定义的 shell 脚本来将对应的进行隔离.
只有在成功执行完成 Fencing 之后, 选主成功的 ActivStandbyElector 才会回调 ZKFailoverController 的 becomeActive 方法将相对应的 NameNode 转换为 Active 状态 , 开始对外提供服务.
2.8 HDFS 2.0 Federation 实现
在 Hadoop 1.0 时 , HDFS 架构设计有以下缺点:
1) Namespace 扩展性差 , 在单一的 NameNode 情况下 , 因为所有 Namespace 数据都需要加载到内存, 所以物理机内存的大小限制了整个 HDFS 能够容纳文件的最大个数(Namespace 指的是 HDFS 中树形目录和文件结构以及文件对应的 block 信息);
2) 性能扩展性差 , 由于所有请求都需要经过 NameNode , 单一 NameNode 导致所有请求都由一台机器进行处理 , 很容易达到但台机器的吞吐 ;
3) 隔离性差 , 在多租户的情况下 , 单一的 NameNode 架构无法在租户间进行隔离 , 会造成不可避免的相互影响 .
而 Federation 的设计就是为了解决这些问题 , 采用 Federation 的主要原因是设计实现简单 , 而且还能解决问题.
2.9 Federation 架构核心思想
Federation 的核心思想是将一个大的 Namespace 划分多个子 Namespace , 并且每个 Namespace 由单独的 NameNode 负责 , 这些 NameNode 之间相互独立 , 不会影响 , 不需要做任何协调工作(类似于拆集群) , 集群中所有 DataNode 会被多个 NameNode 共享 , 其中每一个子 Namespace 和 DataNode 之间会由数据块管理层作为中介建立映射关系 , 数据块管理层由若干数据块池构成 , 每个数据块指挥唯一属于某个固定的数据块池 , 而一个子 Namespace 可以对应多个数据块池 ,每一个 DataNode 需要向集群中所有的 NameNode 注册 , 且周期性地向所有 NameNode 发送心跳和块报告 , 并执行来自所有 NameNode 的命令 .
1) 一个 block pool 由属于同一个 Namespace 的数据块组成 , 每一个 DataNode 可能会存储集群中虽有 block pool 的数据块 ;
2) 每个 block pool 内部自治 , 也就是说各自管理各自的 block , 不会与其他 block pool 交流 , 如果一个 NameNode 挂掉了 , 不会影响其他 NameNode .
3) 某个 NameNode 上的 Namespace 和它对应的 block pool 一起被称为 Namespace volume , 它是基本的管理单位 , 当一个 NameNode/Namespace 被删除以后 , 其所有 DataNode 上对应的 block pool 也会被删除 , 当集群升级时 , 每一个 Namespace volume 可以作为一个基本单元进行升级 .
三 、 MapReduce
3.1 MapReduce 编程模型
在分布式计算中 , MapReduce 框架主要负责了并行编程中分布式存储 、 工作调度 、 负载均衡 、 容错均衡 、 容错任务以及网络通信等复杂问题 , 把处理过程高度抽象为两个函数 map 和 reduce , map 负责把任务分解成多个任务 , reduce 负责把分解后多任务处理的结果汇总起来 .
通过 MapReduce 来处理的任务必须要具备这样的特点 , 待处理的数据集可以分解为出许多个小的数据集 , 每一个小的数据集都可以完全并行地进行处理 .
3.2 MapReduce 设计目标
MapReduce 诞生于搜索领域 , 主要解决搜索引擎面临的海量数据处理扩展性差的问题 , 它的实现很大程度上借鉴了 Google MapReduce 的设计思想 , 包括简化编程接口 , 提高系统容错性等 . 总结 Hadoop MapReduce 主要有以下几点:
1) 易于编程
2) 良好的扩展性 , 醉着公司业务的发展 , 积累的数据量会越来越大 , 当数据量增加到一定程度后 , 现有的集群可能已经无法满足计算能力和存储能力 , 这个时候管理员可能期望通过添加机器达到线性扩展集群能力的目的 .
3) 高容错性 , 在分布式环境中 , 醉着集群规模的增加 , 集群中的故障率(包括磁盘损坏 、 机器宕机 、 节点间通讯失败等硬件故障和坏数据或者用户程序bug 产生的软件故障)会显著增加 , 进而导致任务失败和数据丢失的可能性增加 , 为此 , Hadoop 通计算迁移或者数据迁移等策略提高集群的可用性与容错性 .
3.3 MapReduce 架构
Hadoop MapReduce 与 Hadoop HDFS 一样 采用了 Master/Slave(M/S) 架构设计, 主要由以下几个组件组成
1) client , 用户编写的 MapReduce 程序通过 client 提交到 JobTracker 端 , 同时用户可以通过 client 提供的一些接口查看作业运行状态 , 在 Hadoop内部用 job 表示 MapReduce 程序 , 一个 MapReduce 程序可以对应若干个作业 , 而每一个作业被分解成若干个 Map/Reduce 任务(Task) .
2) JobTracker , 主要负责资源监控和任务调度 . JobTracker 监控所有的 TaskTracker 与作业的健康状态 , 一旦发现失败情况后 , 其会将相应的任务转移到其他节点 , 同时 , JobTracker 会跟踪任务的执行进度 、 资源使用量等信息 , 并将这些信息告诉任务调度器 , 而调度器会在资源空闲时 , 选择适合的任务使用这些资源 , 在 Hadoop 中 , 任务调度器是一个可插拔的模块 , 用户可以根据自己需要设计相应的调度器 .
3) TaskTracker , TaskTracker 会周期性的通过 Healtbeat 将节点上资源使用情况和任务的运行进度汇报给 JobTracker , 同时接收 JobTracker 发送过来的命令并执行相应的操作 (如启动新任务 、 杀死任务等) .
4) Task 分为 Map Task 和 Reduce Task 两种 , 均有 TaskTracker 启动 , 对于 MapReduce 而言处理基本单位是分片(split).
split 包含一些元数据信息 , 比如数据起始位置 、 数据长度 、 数据所在节点等等 . 划分方法由用户决定 , split 的划分大小与 HDFS 的 block 大小一致 . split 的多少决定了 Map Task 的数目 , 因为每个 split会交由一个 Map Task 处理 .
Map Task 先将对应的 split 迭代解析成一个个键值对 , 依次调用用户自定义的 Map 函数进行处理 , 最终将临时结果存放到本次磁盘上 , 其中临时数据被分成若干个 partition(分区) , 每一个 partition 将会被一个 ReduceTask 处理 .
ReduceTask 分为三个阶段:第一步 , 从远程节点上读取 Map Task 中间结果 , 成为 Shuffle 阶段 , 第二步按照 key 对 key/value 进行排序 , 成为 sort 阶段 , 第三步依次读取 , 调用用户自定义的 reduce 函数处理 , 并将最终的结果存到 HDFS 上 , 称为 Reduce 阶段 .
3.4 MapReduce 作业的生命周期
1) 作业提交与初始化 . 用户提交作业后 , 首先由 JobTracker 实例将作业相关信息 , 比如将程序 jar 包 、 作业配置文件 、 分片远信息文件等上传到 HDFS , 其中分片远信息文件记录了每个输入分片的逻辑位置信息 , 然后 JobTracker 通过 RPC 通知 JobTracker . JobTracker 收到新作业提交请求后 , 由作业调度模块对作业进行初始化 , 为作业创建一个 JobInProgress 对象跟踪作业运行状态 , 而 JobInProgress 则会为每个 Task 创建一个 TaskInProgress 对象以跟踪每个人物的运行状态 , TaskInProgress 可能需要管理多个 Task 尝试运行 .
2) 任务调度与监控 , 任务调度和监控的功能均由JobTracker 完成。 TaskTracker 周期性地通过Heartbeat向JobTracker汇报本节点的资源使用情况,一旦出现空闲资源,JobTracker会按照一定的策略选择一个合适的任务使用该空闲资源,这由任务调 度器完成。任务调度器是一个可插拔的独立模块,且为双层架构,即首先选择作业,然后从该作业中选择任务,其中,选择任务时需要重点考虑数据本地性。此外,JobTracker跟踪作业的整个运行过程,并为作业的成功运行提供全方位的保障。首先,当TaskTracker或者Task失败时,转移计算任务 ;其次,当某个Task执行进度远落后于同一作业的其他 Task 时, 为之启动一个相同 Task,并选取计算快的Task结果作为最终结果。
3) 任务运行环境准备 , 运行环境准备包括JVM启动和资源隔离,均由TaskTracker 实现。TaskTracker为每个Task启动一个独立的JVM 以避免不同Task在运行过程中相互影响;同时,TaskTracker使用了操作系统进程实现资源隔离以防止Task滥用资源。
4) 任务执行 , TaskTracker 为 Task 准备好运行环境后,便会启动Task。在运行过 程中,每个 Task 的最新进度首先由 Task 通过 RPC 汇报给TaskTracker,再由 TaskTracker 汇报给JobTracker。
5) 作业完成 , 待所有 Task 执行完毕后 , 整个作业执行成功 .
3.5 MapReduce 作业的运行机制
按照时间顺序包括: 输入分片(input split) 、 map阶段 、 combiner(化合)阶段 、 shuffle 阶段 、 reduce 阶段
四 、 Hadoop YARN
4.1 YARN 基本架构
1) ReduceManager , 整个集群只有一个 , 负责集群资源的统一管理和调度 , 其主要任务为处理客户端的请求 、 启动/监控 ApplicationMaster 、 监控 NodeManager 、 资源分配与调度 .
2) NodeManager , 整个集群有多个负责单节点资源的管理和使用 , 其主要任务为处理单节点上的资源管理和任务管理 、 处理来自 ReduceManager 的命令 、 处理来自 ApplicationMaster 的命令 .
3) ApplicationMaster , 每一个应用有一个 , 负责应用程序的管理 , 其主要任务是对数据的切分 、为应用程序申请资源并进一步分配给内部任务 , 任务监控与容错 .
4) Container(容器), 对任务运行环境的抽象 , 其主要任务是对任务运行资源(包括节点 、内存 、 CPU) 、任务启动命令 、任务运行环境的管理 .
4.2 YARN 的运行过程
1) 用户向 YARN 中提交应用程序 , 其中包括 ApplicationMaster 程序 , 启动 ApplicationMaster 命令、 用户程序等 .
2) ReduceManager 为该程序分配第一个 Container(容器) , 并与对应的 NodeManager 通信 , 要求它在这个 Container 中启动应用程序的 ApplicationMaster .
3) ApplicationMaster 首先向 ReduceManager 注册 , 这样用户可以直接通过 ReduceManager 查看应用程序的运行状态 , 然后它将为各个任务申请资源 , 并监控它的状态 , 直到运行结束 .
4) ApplicationMaster 采用轮询的方式通过 RPC 协议向 ReduceManager 申请和领取资源 .
5) 一旦 ApplicationMaster 申请到资源后 , 便与对应的 NodeManager 通信 , 要求它启动任务 .
6) NodeManager 为任务设置好运行环境 ,(包括环境变量 、 jar包 、 二进制程序)后 , 将任务启动命令写到另一个脚本中 , 并通过运行该脚本启动任务 .
7) 各个任务通过某个 RPC 协议向 ApplicationMaster 汇报自己的状态和进度 , 让 ApplicationMaster 随时掌握各个任务的运行状态 , 从而可以在任务失败时重新启动任务 , 在应用程序运行过程中 , 用户可以随时通过 RPC 向 ApplicationMaster 查询应用程序的当前运行状态 .
8) 应用程序完成后 , ApplicationMaster 向 ReduceManager 注销并关闭自己 .
4.3 YARN 的容错性
1) ReduceManager 存在单节点故障 , 可以通过 Zookeeper 实现 HA ,
2) NodeManager 运行失败后, ReduceManager 将失败任务告诉对应的 ApplicationMaster .
3) ApplicationMaster 运行失败后 , ApplicationMaster 需处理内部任务的容错问题 , ReduceManager ApplicationMaster 会保存已经运行完成的 Task , 重启后无需重新运行 .
4.4 YARN 调度框架的模型
1) 双层调度框架 , ReduceManager 将资源分配给 ApplicationMaster , ApplicationMaster 将资源进一步分配给 Task .
2) 基于资源预留的调度策略 , 资源不够时 , 会为 Task 预留资源 , 直到资源充足 .
4.5 YARN 资源调度器
4.6 YARN 资源隔离方案
YARN 资源隔离支持两种隔离方式分别为内存隔离与 CPU 隔离
1) 内存隔离是基于线程监控的方案, 可以决定应用程序的'生死'
2) CPU 隔离是基于 Cgroups 的方案 , 默认不对 CPU 资源进行隔离
五 、 Hadoop 机架感知
5.1 HDFS 分布式文件系统内部副本存放策略(以默认的副本数=3为例)
1) 第一个副本块存本机
2) 第二个副本块存跟本机同机架内的其他服务器节点
3) 第三个副本快存不同机架的一个服务器节点上
5.2 副本存放策略的好处
1) 如果本机数据损坏或者丢失 , 那么客户端可以从同机架的相邻节点获取数据 , 速度要比跨机架获取数据快 .
2) 如果本机所在的机架出现问题 , 那么之前在存储的的时候没有把所有的副本都放在一个机架内 , 这就能保证数据的安全性 , 此种情况出现 , 就能保证客户端也能出现问题 .
5.3 HDFS 读取数据副本的顺序
1) 如果本机有数据 , 那么就直接在本机读取数据 .
2) 如果在跟本机痛机架的服务器及诶点中有数据块 , 则会直接读取数据 .
3) 如果该 HDFS 集群跨多个数据中心 , 那么客户端也一定会有限读取本数据中心的数据 .
六 、 节点的服役和退役
6.1 HDFS 节点服役(添加新节点)
1) 在master机器上 Hadoop_HOME/etc/ 下创建一个 dfs.include.txt文件
2) 编辑 dfs.include.txt 文件 , 加入服役 DataNode 节点信息
slave1
slave2
slave3
slave4
3) 在 hdfs-site.xml 文件中添加属性
dfs.hosts
Hadoop_HOME/etc/dfs.include.txt
4) 在 NameNode 节点上刷新节点
hdfs dfsadmin -refresNodes
5) 在 slaves 文件中添加新节点的主机名
6) 单独启动新的节点中的 DataNode
hadoop-demon.sh start datanode
6.2 HDFS 节点的退役(下线旧节点)
1) 在master机器上 Hadoop_HOME/etc/ 下创建黑名单 dfs.hosts.exclude.txt , 将退役节点ip(主机名)添加进去
2) 配置 hdfs-site.xml
dfs.hosts.exclude
Hadoop_HOME/etc/dfs.hosts.exclude.txt
3) 刷新 NameNode 节点信息
hdfs dfsadmin -refresNodes
4) 查看 webUI , 节点状态在 decommisstion progress
5) 当所有退役的节点报告为 decommisstioned , 数据转移工作已经完成 .
6) 从白名单删除退役节点 , 并刷新节点
hdfs dfsadmin -refresNodes
7) 从 slaves 文件中删除退役节点
6.3 YARN 节点的服役
1) 在master机器上 Hadoop_HOME/etc/ 下创建一个 dfs.include.txt文件
2) 编辑 dfs.include.txt 文件 , 加入服役 DataNode 节点信息
slave1
slave2
slave3
slave4
3) 在 hdfs-site.xml 文件中添加属性
yarn.resourcemananger.nodes.include-path
Hadoop_HOME/etc/dfs.include.txt
4) 在 NameNode 节点上刷新节点
yarn rmadmin -refresNodes
5) 在 slaves 文件中添加新节点的主机名
6) 单独启动新的节点中的 NodeManager
yarn-demon.sh start NodeManager
6.4 YARN 节点的退役
1) 在master机器上 Hadoop_HOME/etc/ 下创建黑名单 dfs.hosts.exclude.txt , 将退役节点ip(主机名)添加进去
2) 配置 hdfs-site.xml
dfs.resourcemananger.nodes.exclude-path
Hadoop_HOME/etc/dfs.hosts.exclude.txt
3) 刷新 ReduceManager 节点信息
yarn rmadmin -refresNodes
4) 查看 webUI , 节点状态在 decommisstion progress
5) 当所有退役的节点报告为 decommisstioned , 数据转移工作已经完成 .
6) 从白名单删除退役节点 , 并刷新节点
yarn rmadmin -refresNodes
7) 从 slaves 文件中删除退役节点
6.5 节点退役数据转移
HDFS 能够容忍 DataNode 的故障 , 但是这并不意味着允许随意终止 DataNode , 以三副本为例如果同时关闭不同机架上三个 DataNode , 则数据丢失的概率会非常高 , 用户可以通过将拟退出的若干 DataNode 告知 NameNode , HDFS 系统会将这些 DataNode 在停机之前将块复制到其他 DataNode , 有了 NodeManager 的支持 , Hadoop 对故障的容忍度会更高 , 如果关闭一个正在运行的 MapReduce 任务的 NodeManager , ApplicationMaster 会检测到故障 , 并在其他节点上重新调度任务 .
当节点退役时 , webUI 页面查看待解除的 DataNode 管理状态是否变为 Decommission In Progress(正在解除) , 因为此时相关的 DataNode 正在被解除过程中 , 这些 DataNode 会把它们的数据块复制到其他的 DataNode中 , 当所有的 DataNode 的状态变为 Decommissioned(解除完毕)时 , 表明所有的块已经复制完毕 , (如果副本数是3,服役的节点小于等于3,是不能退役成功的,需要修改副本数后才能退役。)