ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Hadoop数据本地化深度解析:原理、调度策略与性能调优实践

Hadoop数据本地化深度解析:原理、调度策略与性能调优实践 项目标题: Hadoop数据本地化机制深度解析原理、实现与性能影响1. 从一次线上跑批任务变慢说起大概一年多前我在负责一个离线数仓集群的运维。某天下午收到告警一个每天固定 26 分钟左右跑完的核心业务 Hive 作业突然跑到了 4 个多小时还没结束。开始以为是数据量暴涨结果看了一圈输入数据量基本持平队列资源也没被抢占HDFS 状态也正常。后来手动点进 ApplicationMaster 的日志里翻了半天发现一个特别扎眼的指标这个作业的 Map 任务本地化率只有 31%。当时还没来得及细查原因第一反应就是把作业 kill 掉重跑了一次。重跑之后本地化率恢复到了 94%耗时也回到了 30 分钟以内。虽然问题表面上“消失”了但这件事让我意识到一个特别容易被忽略的事实在 Hadoop 集群里数据本地化Data Locality不是一个可以靠默认配置“躺赢”的机制它时时刻刻在影响每一个作业的耗时而且一旦出问题表现可能不是报错而是莫名其妙的慢。后来复盘那次事故根因是有人手动调整了 YARN 调度器的参数导致集群发生了大量任务重分配而新的任务被调度到了没有对应数据副本的节点上。在 1Gbps 网卡的老集群里跨节点去读 HDFS 上的块和本地直接读磁盘相比性能差距可以被拉大到 3 到 8 倍。这就意味着一个 Map 阶段本来只需要读 5 分钟数据的任务硬生生被拖成了 20 到 40 分钟。所以这篇文章我想把数据本地化这件事从头到尾拆开讲清楚它到底在解决什么问题Hadoop 是怎么判断“数据在哪个节点”的调度器是怎么利用这些信息分配任务的以及我们在实际运维中怎么监控和调优本地化率。全文基于我自己的实践和踩坑经验不是那种“复制官网文档”的科普。2. 数据本地化的核心思想移动计算而不是移动数据2.1 分布式系统里的“搬运成本”理解数据本地化之前得先建立一个最朴素的概念在海量数据面前网络是有成本的而且成本很高。假设你要处理一份 1TB 的数据。如果这份数据在节点 A 的本地磁盘上处理它的代码在节点 B 上那么你有两个选择把数据从 A 搬到 B或者搬过去一部分把代码从 B 搬到 A让计算在数据所在的机器上执行。Hadoop 的 MapReduce 模型选择的显然是第二条路。这个思想在 Google 最初的 MapReduce 论文里就写得非常直白“把计算移动到数据所在的位置而不是反过来。”原因也简单1GB 数据的网络传输可能需要几十秒甚至几分钟但一段几 MB 的 JAR 包和任务代码传输最多不过几秒钟。当数据规模到 PB 级别时搬数据更是不可能完成的任务。2.2 HDFS 块与本地化的对应关系HDFS 会把一个大文件拆分成默认 128MB老版本是 64MB的块每个块默认有 3 个副本分布在集群的不同机器上。当客户端向 YARN 提交一个 MapReduce 作业时MapTask 需要处理的是一个一个的输入分片InputSplit。一个输入分片通常对应一个 HDFS 块所以一个 Map 任务本质上就是去处理某一台 DataNode 上的某个块文件。“本地化”就是指这个 Map 任务被调度到的那个节点恰好保存了它要处理的那个块的副本。理想情况下任务运行在块副本所在的节点上直接从本地磁盘读取数据不走网络这就是 Node-Local 本地化。Hadoop 官方文档里对 MapTask 的本地化程度通常分三个等级Node-Local任务在数据块副本所在的节点上运行最优。Rack-Local任务与数据块副本在同一个机架的不同节点上次优。Off-Switch / 跨机架任务所在节点既没有副本也跟所有副本不在同一个机架最差。这个级别的数据读取要走核心交换机网络路径最长。在 MapTask 的日志和监控指标里你会看到类似于>
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进