1.2 Hadoop 核心概念与数据流视角 本节摘要:Hadoop 的三大组件 HDFS、MapReduce、YARN 分别承担存储、计算、资源调度。本节以"一次 300MB 日志文件的上传与统计"为回放案例,把 NameNode、DataNode、块、作业、任务、容器等核心概念按数据流动顺序全部串起来,形成后续各章共享的角色表。 用一次上传回放整个体系 空讲概念容易睡着,我们直接开演。场景:你在网关机执行一条命令,把 300 MB 的日志文件上传到 HDFS,随后提交一个词频统计作业。这条数据流的每一次转折,都是一组角色的登场时刻。
本节摘要:Hadoop 的三大组件 HDFS、MapReduce、YARN 分别承担存储、计算、资源调度。本节以"一次 300MB 日志文件的上传与统计"为回放案例,把 NameNode、DataNode、块、作业、任务、容器等核心概念按数据流动顺序全部串起来,形成后续各章共享的角色表。
空讲概念容易睡着,我们直接开演。场景:你在网关机执行一条命令,把 300 MB 的日志文件上传到 HDFS,随后提交一个词频统计作业。这条数据流的每一次转折,都是一组角色的登场时刻。
客户端并不直接把字节扔给集群,它先向 NameNode 发起 RPC:"我要在 /data/logs/ 下创建 access-2026-08-18.log,请给我写入路线"。NameNode 做三件事:检查路径是否冲突、校验权限、在命名空间里登记一个新文件条目(此刻还是"写入中"状态),然后返回给客户端一张"施工图"——第一个块该写到哪些 DataNode。
角色登场:NameNode,HDFS 的元数据管家,管理目录树、文件到块的映射、每个块存放在哪些 DataNode。注意它自己不存任何业务数据,只存"账本"。客户端是数据面入口,负责切分文件、建立写入管线。
客户端把 300 MB 文件按块大小(默认 128 MB)切成 3 块:前两块满 128 MB,第三块约 44 MB。对第一个块,客户端按 NameNode 给的节点列表(假设 dn1、dn2、dn4)建立写入管线:字节流先到 dn1,dn1 边落盘边转发给 dn2,dn2 再转发给 dn4;每个节点写满一个校验块单元(512 字节数据 + 4 字节校验)就向上游回 ACK。全管线确认后,客户端才向 NameNode 报告"块 1 写完",再申请块 2 的路线。
角色登场:DataNode,数据面工人,存块、回心跳、上报块报告、响应读写。块是 HDFS 的最小存储与调度单元,也是后面一切本地性计算的坐标。
文件写完,你提交词频作业。这条命令背后发生了一串事:客户端把程序 jar 与配置上传到 HDFS,向 ResourceManager 申请启动一个 MR-AppMaster;RM 在某个 NodeManager 上为它分配第一个容器(一段被隔离的内存与 CPU 配额),AppMaster 在容器里启动;AppMaster 随即向 RM 为每个 Map 任务讨要容器——并且附上"希望放在持有输入块的节点"的本地性提示。
角色登场:YARN 的四人组——ResourceManager(全集群资源记账与分配)、NodeManager(单机资源看管与容器执行)、AppMaster(每个作业一个,负责切分任务、申请资源、监控重试)、Container(资源的计量单位与运行隔离边界)。
Map 任务在容器里启动,逐行读本地块,输出中间键值对并写入本地磁盘(不是 HDFS);Shuffle 阶段 Reduce 任务通过 HTTP 从各 Map 端拉取属于自己分区的数据,排序归并;Reduce 计算完把结果 part-r-00000 写回 HDFS——回到旅程原点,只是数据从原始形态变成了加工形态。
角色登场:作业(Job)、任务(Task)、输入分片(InputSplit)——分片数默认等于块数,所以我们的文件会产生 3 个 Map 任务。

| 概念 | 所属组件 | 一句话职责 | 数据流视角 |
|---|---|---|---|
| NameNode | HDFS | 管目录树与块映射 | 写入发路线、读取发位置 |
| DataNode | HDFS | 存块、回心跳 | 旅程中的驿站 |
| 块 Block | HDFS | 128MB 存储单元 | 分块决定并行度 |
| 副本因子 | HDFS | 每块默认 3 份 | 容错与读取热点的平衡 |
| ResourceManager | YARN | 全局资源分配 | 旅程计算段的门票发放处 |
| NodeManager | YARN | 单机容器执行 | 驿站的场地管理员 |
| AppMaster | YARN | 作业代言人 | 为每个任务讨容器 |
| 容器 Container | YARN | 内存加vCore配额 | 任务运行的车厢 |
| 输入分片 Split | MR | 逻辑切分,默认等于块 | 有几分片就有几个 Map |
| 作业 Job | MR | 任务加配置的整体 | 一段计算旅程 |
新手常见的困惑:既然 MapReduce 要跑在 YARN 上,为什么算两个东西?答案是历史性的分工演化——早期 MapReduce 既管计算逻辑又管资源,导致集群同一时间只能跑一种框架的资源逻辑。YARN 把"资源"从"计算"里抽出来后,Spark、Tez 等新框架得以共享同一套资源池。这个演化故事在第 4 章展开。
另一个容易混淆的点:块是物理切分,分片是逻辑切分。块由 HDFS 在写入时固定,分片由计算框架在提交时计算,两者默认对齐(一个分片恰好一个块),但允许程序员按记录边界调整——比如一行 JSON 跨块时,分片会自动把边界回退到换行符处,保证记录完整。物理与逻辑解耦,是存储层与计算层能各自独立演化的关键。
再看一遍那张关系图,你会发现数据面的流动(块、中间结果、结果文件)与控制面的协调(NameNode 路线、RM 分配、AppMaster 编排)始终分离。Hadoop 全体系都在贯彻这个原则:数据走数据面,指令走控制面,两者只在关键节点交汇。
环境就绪后(1.3 节搭建),以下命令能让你"看见"上面所有概念:
# 1. 查看 HDFS 根目录 —— NameNode 响应的目录树 hdfs dfs -ls / # 2. 上传文件,观察切块 —— 客户端管线写入 hdfs dfs -put access-2026-08-18.log /data/logs/ # 3. 查看文件的块信息 —— 文件到块的映射与副本位置 hdfs fsck /data/logs/access-2026-08-18.log -files -blocks -locations # 典型输出(节选): # /data/logs/access-2026-08-18.log 314572800 bytes, 3 block(s): # blk_1073741825 134217728 repl=3 dn1:50010, dn2:50010, dn4:50010 # blk_1073741826 134217728 repl=3 dn2:50010, dn5:50010, dn8:50010 # blk_1073741827 46137344 repl=3 dn1:50010, dn3:50010, dn7:50010 # 4. 查看运行中的 YARN 应用 —— AppMaster 视角 yarn application -list # 典型输出: # application_1724000000000_0001 WORDCOUNT RUNNING default 1/3 ... # 5. 查看节点资源 —— NodeManager 上报的容器视图 yarn node -list -showDetails
第 3 条命令的输出最值得琢磨:三个块、每个 repl=3、分布在不同 DataNode——1.1 节地图上"存储带"的全部细节就躺在这一行里。
概念就位,下一节把环境立起来:三种部署模式怎么选、伪分布式怎么装。