前四阶段把 Hadoop 核心(HDFS / YARN / MapReduce + Common)讲完了。第五阶段展开 Hadoop 周边的生态系统和现代演进。本篇先讲生态——Hive、HBase、Pig 在 Hadoop 之上各自的角色。

Hadoop 生态常被介绍成"HDFS + YARN + MapReduce + 一堆工具"。这个描述对应了组件清单但完全没解释这些工具为什么存在。准确的说法是:Hive 是 SQL 编译器(把 SQL 翻译成 MapReduce/Tez/Spark 执行计划),不是计算引擎;HBase 是把随机读写放上 HDFS 的 LSM-Tree KV 存储,依赖 HDFS 做持久化但通过 RegionServer 提供低延迟访问;Pig 是脚本化的数据流编程语言,曾被 Yahoo 大规模使用;新项目通常转向 Spark,但 Pig 在 2025 年仍发布了 0.18.0,并未进入 Apache Attic。这三个工具各自填补 Hadoop 的一个能力空白——SQL 接口、随机读写、复杂数据流——但底层都跑在 HDFS + YARN 之上,不替代它们。

本篇只抓一个问题:Hive 的 SQL 编译流程是什么、HBase 怎么在 HDFS 之上实现毫秒级随机访问、Pig 的生态位为什么被 Spark 压缩。

Hive:SQL 编译器不是计算引擎

Hive(Facebook 2008 年开源)的设计目标是让熟悉 SQL 的分析师直接处理 HDFS 上的数据,不需要写 Java MapReduce 代码。Hive 的本质是一个 SQL 编译器——把 SQL 语句翻译成 MapReduce / Tez / Spark 作业。

Hive 的标准编译流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
1. Client 提交 SQL(hive CLI / beeline / JDBC)
2. Driver 解析 SQL 文本 → AST(抽象语法树)
3. 语义分析器检查表存在性、列存在性、类型匹配
- 从 Metastore 查表 schema
- 类型推导
4. 生成逻辑执行计划(Operator DAG)
- TableScan → Filter → Join → GroupBy → Select → FileSink
5. 逻辑优化(谓词下推、列裁剪、join 重排序)
6. 生成物理执行计划
- 选择 MapReduce / Tez / Spark 作为执行引擎
- 把 Operator DAG 切分成 Stage(按 Shuffle 边界)
7. 物理优化(map-side aggregation、broadcast join、动态分区裁剪)
8. 提交执行计划到 YARN

注意 Hive 自己不是计算引擎——它生成执行计划后由 MapReduce / Tez / Spark 执行。早期 Hive 只支持 MapReduce(Hive 0.x 时代),从 Hive 0.13 起支持 Tez(性能更好),从 Hive 1.1 起支持 Spark。现代 Hive 部署通常用 Tez 或 Spark 作为执行引擎;Hive 4.x 已移除 MapReduce 执行引擎。

Hive Metastore 是独立服务(Thrift Server),存储表 schema、分区、列统计、存储位置(HDFS 路径)。Metastore 后端通常是 MySQL / PostgreSQL。多个 Hive 客户端共享同一 Metastore。

Hive 的存储格式可以选:

1
2
3
4
5
6
TextFile          默认,纯文本
SequenceFile Hadoop 原生二进制
RCFile 早期列式存储(已淘汰)
ORC Hive 主推的列式格式(高效压缩 + 索引)
Parquet Impala 主推但 Hive 也支持
Avro schema 友好的行式存储

ORC + Snappy 是 Hive 生产环境的标配,相比 TextFile 节省 70%+ 存储和 I/O。

Hive 的主要定位仍是批处理与分析型 SQL(OLAP),但不能再概括成“没有事务”。标记为 transactional=true 的 ACID 表支持 INSERT、UPDATE、DELETE,MERGE 自 Hive 2.2 起可用;限制在于事务默认关闭、只支持特定表形态,而且 BEGIN / COMMIT / ROLLBACK 这类显式事务控制仍不完整。

HBase:在 HDFS 之上构建 KV 存储

HDFS 的设计目标是"大文件顺序读写",不适合随机读写——每条记录都是文件级 append,随机修改需要重写整个文件。但很多业务场景需要随机读写(用户画像、实时推荐、消息存储),HDFS 本身无法满足。

HBase(PowerSet 2007 年开源,灵感来自 Google Bigtable 2006 论文)填补了这个空白。HBase 在 HDFS 之上构建 LSM-Tree(Log-Structured Merge-Tree),通过 RegionServer 提供毫秒级随机读写。

HBase 的核心抽象:

1
2
3
4
5
6
Table:    按 rowkey 排序的 KV 存储
Region: Table 按 rowkey 范围切分的子表,每个 Region 由一个 RegionServer 服务
Column Family: 列族,预先定义,控制存储和缓存策略
Column Qualifier: 列限定符,动态添加(schema-less)
Cell: (rowkey, column family, column qualifier, timestamp) → value
Version: HBase 0.96+ 每个 cell 默认最多保留 1 个版本(可按列族调整)

HBase 的写入路径:

1
2
3
4
5
6
7
1. Client 通过 ZooKeeper 找到 RegionServer
2. Client → RegionServer: put(rowkey, cf:cq, value)
3. RegionServer 把操作写入 WAL(Write-Ahead Log,存 HDFS)
4. RegionServer 把数据写入 MemStore(内存)
5. RegionServer 立即返回成功(WAL 持久化保证)
6. MemStore 攒够阈值(默认 128MB)后 flush 为 HFile(HDFS 文件)
7. 多个 HFile 定期 compaction 合并(LSM-Tree 的核心)

这个写入路径的关键是"WAL 写 HDFS + 数据写内存"——WAL 保证宕机后数据可恢复(HDFS 多副本),内存写让延迟低(毫秒级)。这种"日志 + 内存 + 异步合并"是 LSM-Tree 的标准设计。

读取路径:

1
2
3
4
5
6
1. Client 通过 ZooKeeper 找到 RegionServer
2. Client → RegionServer: get(rowkey)
3. RegionServer 查 MemStore(最新写入)
4. RegionServer 查 BlockCache(最近读过的数据,LRU)
5. RegionServer 查 HFile(按 rowkey 范围定位 HFile,Bloom Filter 加速)
6. 合并三层结果返回给 Client

读取涉及多个层级,实际延迟取决于 BlockCache 命中率、RegionServer 负载、HFile 数量和网络位置。HBase 的目标是比直接扫 HDFS 更适合低延迟随机读写,但它不是 Redis / Memcached 这类纯内存 KV。

HBase 的 RegionServer 是有状态的——一个 Region 在同一时刻由一个 RegionServer 服务。RegionServer 宕机时,这些 Region 要等 Master 重新分配后恢复服务,停顿时间取决于 ZooKeeper 会话、WAL split、集群负载和配置。这种"Region 迁移窗口"需要客户端重试兜底。

Pig:脚本化数据流编程语言

Pig(Yahoo 2008 年开源)的设计目标是让数据工程师写"脚本"而不是"MapReduce Java 代码"处理 ETL。Pig Latin 是一种声明式数据流语言:

1
2
3
4
5
6
7
-- 经典的 Pig Latin 例子:统计每个用户的访问次数
visits = LOAD '/data/visits' USING PigStorage(',') AS (user:chararray, page:chararray, time:long);
grouped = GROUP visits BY user;
counts = FOREACH grouped GENERATE group AS user, COUNT(visits) AS visit_count;
top_users = ORDER counts BY visit_count DESC;
top_10 = LIMIT top_users 10;
DUMP top_10;

Pig 把这段脚本编译成一系列 MapReduce 作业,按依赖顺序串联执行。脚本里每个 FOREACH / GROUP / JOIN 对应一个或多个 MR Stage。

Pig 的优势是表达力比 SQL 强——支持复杂数据流(嵌套 FOREACH、COGROUP、多输入 JOIN)、用户自定义函数(UDF)方便、调试友好。Yahoo 在 2008-2012 年大规模使用 Pig 做 ETL。

Pig 的生态位被压缩,主要有三个原因:

第一,Spark 出现。Spark 的 RDD API + DataFrame 让 Pig 的脚本优势消失——Spark 用 Scala / Python / Java 写,性能比 Pig 快(内存优先),生态系统更广。Spark 2.x 引入的 Structured Streaming 和 Catalyst 优化器让 Spark 在 ETL 场景全面超越 Pig。

第二,Hive + Tez 让 SQL 性能追上 Pig。Hive 0.13 引入 Tez 后性能提升数倍,传统 SQL 已经能处理 Pig 的多数场景。分析师更愿意写 SQL 而不是 Pig Latin。

第三,Pig 的演进节奏显著放慢。0.17.0 到 0.18.0 间隔了 8 年,0.18.0 在 2025-09-15 发布,补上 Hadoop 3、Tez 0.10、Hive 3、Spark 3、HBase 2、Python 3 等兼容;这说明它不是 Attic 项目,但社区主流新工作负载已经迁移到 Spark。

现在 Pig 更多出现在存量 ETL 流水线和兼容性场景里,新项目通常不再首选 Pig。这是 Hadoop 生态里"生态位迁移"的典型例子——不是 Pig 设计错误,而是 Spark 和 SQL/Tez 体系覆盖了它的主要使用场景。

生态工具的共同模式

Hive、HBase、Pig(以及 Sqoop、Flume、Oozie、Mahout、HCatalog 等几十个工具)共享一组模式:

底层复用 Hadoop 基座,但方式不同。Hive 与 Pig 通常把计算作业提交给 MapReduce / Tez / Spark,再由 YARN 承载;HBase 是长驻在线存储系统,核心路径是 RegionServer 读写 HDFS 上的 WAL/HFile,不是 YARN 批处理引擎。Hadoop 提供了存储、权限、RPC、监控等基础设施,让上层工具不需要重复实现全部分布式系统基座。

接口层是多样化的——Hive 提供 SQL、HBase 提供 KV API、Pig 提供数据流语言、Sqoop 提供 RDBMS 同步、Oozie 提供工作流编排。每个工具针对特定使用场景,不试图成为"通用解决方案"。

Metastore 是共享元数据——Hive Metastore、HBase Catalog、Oozie Workflow Database 等共享元数据存储,让多个工具能协作(例如 Spark 通过 Hive Metastore 读 Hive 表 schema)。

执行引擎可以演化——Hive 与 Pig 能切换部分计算引擎。HBase 的主路径仍是 HDFS 或兼容 FileSystem;对象存储缺少原子 rename 等文件系统语义,必须借助额外实现与约束,不能把“HBase 跑在 S3”写成普通引擎替换。

实验:观察生态工具

实验状态:UNVERIFIED_RUNTIME。下面是验证步骤,本轮没有连接真实 Hive / HBase / Pig 集群执行。

提交一个 Hive 查询:

1
beeline -u jdbc:hive2://hive-server:10000 -e "SELECT COUNT(*) FROM user_visits WHERE visit_date='2026-07-26'"

观察 Hive 把 SQL 翻译成几个 Stage、每个 Stage 的 Map/Reduce Task 数、Shuffle 字节数。Hive 的 EXPLAIN 命令展示执行计划:

1
EXPLAIN SELECT COUNT(*) FROM user_visits WHERE visit_date='2026-07-26';

输出 Operator DAG 和 Stage 划分。

提交一个 HBase 操作:

1
2
3
4
5
hbase shell
> create 'test', 'cf'
> put 'test', 'row1', 'cf:a', 'value1'
> get 'test', 'row1'
> scan 'test'

观察 HBase 的 get / scan 响应时间和 Region 定位路径。打开 HBase Master Web UI(默认 16010 端口)查看 Region 分布、RegionServer 状态、HFile 大小。

提交一个 Pig 脚本(如果集群还装着 Pig):

1
pig -f visit_count.pig

观察 Pig 把脚本编译成多少 MR 作业。

模式提炼

Hadoop 生态体现的设计模式:

1
2
3
4
5
6
7
模式:分层抽象 + 接口稳定 + 实现可替换

- 底层提供存储和计算基座(HDFS + YARN)
- 上层工具针对特定场景提供接口(SQL / KV / 数据流)
- 接口与实现解耦,让底层引擎可以演化(MR → Tez → Spark)
- 共享元数据(Metastore)让多工具协作
- 工具按使用场景自然演化(成功的留存,被取代的淘汰)

这个模式不只是 Hadoop。Kubernetes 生态(CNCF Landscape)也是同样思路——底层是 K8s 容器编排,上层是无数工具(数据库 Operator、消息队列 Operator、Service Mesh、CI/CD 等),每个工具针对特定场景。数据库生态(PostgreSQL Extension、Oracle 数据集成工具)也类似。

云原生时代的数据栈(Snowflake / Databricks / Confluent)把这种模式推进了一步——不只是工具分层,整个 stack 都被云服务化。但底层抽象模式没变。

工程迁移表

Hadoop 生态概念 现代 stack 云原生对应
Hive(SQL on HDFS) Spark SQL / Presto / Trino Snowflake / BigQuery / Databricks SQL
HBase(KV on HDFS) Cassandra / DynamoDB DynamoDB / Cosmos DB / Spanner
Pig(数据流) Spark DataFrame dbt / Airflow + Spark
Sqoop(RDBMS 同步) Debezium / Kafka Connect Confluent / AWS DMS
Flume(日志采集) Fluentd / Filebeat Cloud Logging
Oozie(工作流) Airflow / Prefect Argo Workflows / Dagster
Mahout(机器学习) Spark MLlib / TensorFlow Kubeflow / SageMaker
HCatalog(元数据) Hive Metastore / Glue Catalog AWS Glue / DataHub

注意"现代 stack"和"云原生对应"两列。Hive 在现代 stack 里被 Spark SQL / Trino 取代(性能更好,SQL 兼容性更全)。但 Hive Metastore 仍然是元数据标准——Spark SQL、Trino、Presto 都通过 Hive Metastore 访问表 schema。这是 Hive 留下的最大遗产。

HBase 在云原生时代面临 DynamoDB / Cosmos DB / Spanner 的竞争——这些托管 KV 存储免运维,性能稳定。HBase 在自建集群场景仍然有价值(成本可控、定制化强),但在云上越来越少。

常见误解

误解一:“Hive 是计算引擎”。Hive 是 SQL 编译器,不是计算引擎。Hive 把 SQL 翻译成执行计划后由 MapReduce / Tez / Spark 执行。早期 Hive 与 MapReduce 强绑定,给外界"Hive = MapReduce SQL"的印象。现代 Hive 可以跑在 Tez / Spark 上,性能与传统印象有数量级差距。

误解二:“HBase 取代了 HDFS”。HBase 是在 HDFS 之上构建的——HBase 的所有持久化数据(WAL、HFile)都存在 HDFS。HBase 提供随机读写 API,但底层存储仍然是 HDFS。没有 HDFS 就没有 HBase。

误解三:“Pig 比 SQL 更强大所以应该选 Pig”。Pig 的数据流表达力确实比 SQL 强(更接近编程语言),但 Spark DataFrame + Scala / Python 完全可以表达 Pig 的所有场景,而且性能更好、生态更广。新项目应该选 Spark,不是 Pig。

误解四:“Hive / HBase / Pig 是独立技术”。这三个工具都依赖 Hadoop 基础设施——Hive 用 YARN 跑作业、用 HDFS 存数据;HBase 用 HDFS 存 HFile、用 ZooKeeper 做 Region 定位;Pig 用 YARN 跑 MapReduce。它们是 Hadoop 生态的一部分,不能脱离 Hadoop 独立部署(虽然现代版本有些可以脱离,但失去了大部分能力)。

误解五:“Hadoop 生态工具越多越好”。生态庞大是优势也是负担——每个工具有自己的学习曲线、配置、运维成本。生产环境应该精选少量工具(例如 HDFS + YARN + Hive + HBase),不试图用所有工具。"少即是多"在大数据栈设计里很重要。

练习

  1. 在 Hive 里执行 EXPLAIN SELECT count(*) FROM some_table GROUP BY some_column,观察 Hive 把 SQL 翻译成几个 Stage、每个 Stage 的算子树。然后切换执行引擎(set hive.execution.engine=tezspark),重新 EXPLAIN 对比差异。

  2. 在 HBase shell 里创建表、插入数据、扫描。打开 HBase Master Web UI 观察 Region 分布、RegionServer 状态。故意 kill 一个 RegionServer 进程,观察 ZooKeeper 检测 + Master 重新分配 Region 的过程。

  3. apache/hive 源码里找到 Driver.javaSemanticAnalyzer.javaMapRedTask.java(hive-exec 模块),观察 Hive SQL 编译的核心实现。在 apache/hbase 源码里找到 HRegionServer.javaHStore.java,观察 HBase 写入路径。

  4. 思考题:如果让 Hive 完全脱离 Hadoop(不用 YARN、不用 HDFS),它的设计需要怎么改造?这种"Hive on Cloud"现在有哪些实现(例如 Hive on AWS EMR、Hive on Azure HDInsight)?

系列导航

序号 主题 状态
00 导读:节点总会失败
01 HDFS 架构与三层切分
02 文件写入路径与流水线
03 文件读取路径与副本选择
04 NameNode 内存模型与启动恢复
05 HDFS HA 与脑裂防御
06 HDFS 3.x 演进与纠删码
07 YARN 架构与三方契约
08 YARN 资源模型、Container 与 NodeLabel
09 YARN 调度器对比:FIFO、Capacity、Fair
10 YARN 应用程序生命周期
11 YARN HA 与 Federation
12 YARN Timeline Service v2
13 MapReduce 编程模型与分而治之
14 MapReduce Shuffle 全流程
15 MRv2 on YARN ApplicationMaster 与 Task Attempt
16 Hadoop RPC 协议栈
17 序列化与压缩
18 Hadoop 安全 Kerberos Token ProxyUser
19 监控与运维 Metrics JMX 日志聚合 上一篇
20 Hadoop 生态 Hive HBase Pig 本篇
21 Hadoop 与对象存储 Kubernetes 演进对比 下一篇
22 Hadoop 设计遗产从 GFS MapReduce 到云原生

参考资料

  • Ashish Thusoo et al. Hive: A Warehousing Solution Over a Map-Reduce Framework. VLDB 2009.(Hive 设计论文)
  • Fay Chang et al. Bigtable: A Distributed Storage System for Structured Data. OSDI 2006.(HBase 设计原型)
  • Christopher Olston et al. Pig Latin: A Not-So-Foreign Language for Data Processing. SIGMOD 2008.(Pig Latin 设计论文)
  • Apache Hive 官方文档:https://hive.apache.org/
  • Apache HBase 官方文档:https://hbase.apache.org/book.html
  • Apache Pig 官方文档:https://pig.apache.org/docs/latest/
  • Tom White. Hadoop: The Definitive Guide. O’Reilly, 4th Edition 2015. Chapter 12-15 详述了 Hive / HBase / Pig 的设计与使用。
  • Eric Sammer. Hadoop Application Architectures. O’Reilly, 2015.(Hadoop 生态企业级架构实践)