这学期开了大数据技术课,讲义的第一章讲 Hadoop。这篇是我按讲义整理的学习笔记,主要是把"Hadoop 到底是什么"这件事理清楚——它的三大组件分别解决什么问题,以及为什么 2.x 版本要推翻 1.x 的架构重新设计。

它从哪来:一个搜索引擎的存储危机

Hadoop 不是凭空设计出来的,它诞生于一个具体的工程问题。

最早是 Nutch 项目——目标是做一个全网搜索引擎,包含网页抓取、索引、查询。项目做着做着撞墙了:抓下来的网页数量往上亿涨,单机存不下,也索引不动

转机是 Google 在 2003 和 2004 年发的两篇论文:

  • GFS(Google File System)——解决海量网页怎么存
  • MapReduce——解决海量数据怎么算

Nutch 的开发者照着论文做了开源实现,也就是 HDFS 和 MapReduce,然后把这两部分从 Nutch 里剥离出来,独立成了 Hadoop 项目。2008 年 1 月,Hadoop 成为 Apache 顶级项目。

所以 Hadoop 从第一天起就是为"单机装不下"这个问题设计的——这决定了它后面所有的设计取舍

三大组件,各管一摊

狭义上的 Hadoop 就是那套软件本身,由三个核心组件构成:

组件全称解决什么
HDFSHadoop Distributed File System分布式文件系统——数据存哪
MapReduce分布式计算框架——数据怎么算
YARNYet Another Resource Negotiator集群资源管理——算的时候资源怎么分

这三者的关系可以这样理解:HDFS 把数据分散存到多台机器上,MapReduce 把计算任务也分散到多台机器上执行,而 YARN 负责决定"哪个任务用哪台机器的多少资源"。

顺带一提,YARN 是 2.x 才加进来的。1.x 时代没有独立的资源管理层,计算和资源调度是耦合在一起的——这正是 2.x 要大改的原因。

1.x 和 2.x:一次伤筋动骨的架构重构

1.x 的问题

1.x 的架构分两块:

文件系统侧:NameNode 主节点管元数据,SecondaryNameNode 辅助管理元数据,DataNode 从节点存实际数据。

计算侧:JobTracker 接收用户的计算任务并分配,TaskTracker 执行分到的任务。

问题出在 JobTracker 身上——它同时管两件事:任务调度资源管理。集群规模一大,JobTracker 就成了瓶颈,而且它一旦挂了整个集群都没法用。更要命的是,这套架构只支持 MapReduce 一种计算框架,想跑别的(比如 Spark)得另起炉灶。

2.x 的解法:把资源管理抽出来

2.x 做了两件关键的事:

第一,用 YARN 替换掉 JobTracker/TaskTracker。拆成两个角色:ResourceManager 负责资源分配,NodeManager 负责执行。职责分离之后,各自都能独立扩展。

第二,把计算框架变成可插拔的。YARN 只负责给资源,至于上面跑 MapReduce 还是 Spark 还是别的,它不关心。这一刀切下去,Hadoop 才从"一个计算框架"变成了"一个生态"。

四种部署架构

讲义里列了 2.x 之后的四种架构形态,复杂度递增:

架构特点
NameNode + ResourceManager 单节点最基础,两个主节点各一个,都有单点故障风险
NameNode 单节点 + ResourceManager 高可用用 ZooKeeper 实现 RM 高可用
NameNode 高可用 + ResourceManager 单节点两个 NameNode 互为主备,引入 JournalNode 管元数据
两者都高可用生产环境的标准形态,JournalNode 一般用奇数个

这里有个细节值得记住:JournalNode 要用奇数个。因为它靠"多数派"机制来保证一致性——3 个节点能容忍 1 个挂掉,5 个能容忍 2 个。偶数个不会带来额外容错能力,反而容易出现投票平局。

三个发行版,选哪个

Apache 的 Hadoop 是开源版本,但直接用它会遇到一个现实问题:版本升级、版本兼容、打补丁,都得自己来。于是有了商业公司封装的发行版:

发行版性质特点
Apache免费开源社区贡献者多、迭代快;但版本维护和兼容性要自己操心
Hortonworks免费开源核心产品 HDP,提供 Ambari 这一整套 Web 管理界面,能在浏览器里管理集群状态
Cloudera软件收费在 Apache 版本上打了自家补丁,解决了生态圈各软件的版本兼容问题,配 ClouderaManager 管理

学习阶段用 Apache 原版就够了——出问题自己能查,也不用跟商业授权打交道。

狭义与广义

最后是讲义里反复强调的一组概念区分:

狭义的 Hadoop = 那个软件本身,就是 HDFS + MapReduce + YARN。

广义的 Hadoop = 整个大数据生态圈。围绕这三个核心组件,长出了一大批周边工具:Hive(把 SQL 翻译成 MapReduce)、HBase(列式存储)、ZooKeeper(分布式协调)、Flume/Sqoop(数据采集)……它们不都属于 Hadoop 这个软件,但都建立在 Hadoop 之上。

所以当有人说"我会 Hadoop"时,得先问清楚——是会用 HDFS 存文件、会写 MapReduce 程序,还是整个生态圈都能搭起来用起来。这两者差别很大。

这一章是纯概念,但有两个地方我觉得比背定义重要。

一个是理解 Hadoop 的设计出发点。它的所有取舍都源于"单机装不下"这个前提——为什么要用 HDFS 做多副本、为什么 MapReduce 要设计成"移动计算而不是移动数据",答案都藏在这句话里。抓住这个前提,后面那一堆组件就不是零散的知识点了。

另一个是 2.x 那次重构的思路。把资源管理从计算框架里抽出来,Hadoop 才从一个 MapReduce 实现变成一个能跑各种框架的平台。这是"解耦"这个原则很典型的一次应用——把两个本来纠缠在一起的职责分开,各自都能独立演进。

至于讲义里列的那些高可用架构(NameNode 主备、JournalNode 奇数个、ResourceManager 双活),我看的时候一直在想一个问题:这些复杂度对小集群真的划算吗?多一层高可用就多一套要维护的组件,配置本身出错的概率可能比硬件故障还高。这个取舍我暂时没有答案,等后面做实验再体会。