深入 Hadoop 20 - Hadoop 生态 Hive HBase Pig
前四阶段把 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 取代。这三个工具各自填补 Hadoop 的一个能力空白——SQL 接口、随机读写、复杂数据流——但底层都跑在 HDFS + YARN 之上,不替代它们。
本篇只抓一个问题:Hive 的 SQL 编译流程是什么、HBase 怎么在 HDFS 之上实现毫秒级随机访问、Pig 为什么没有活下来。
Hive:SQL 编译器不是计算引擎
Hive(Facebook 2008 年开源)的设计目标是让熟悉 SQL 的分析师直接处理 HDFS 上的数据,不需要写 Java MapReduce 代码。Hive 的本质是一个 SQL 编译器——把 SQL 语句翻译成 MapReduce / Tez / Spark 作业。
Hive 的标准编译流程:
1 | |
注意 Hive 自己不是计算引擎——它生成执行计划后由 MapReduce / Tez / Spark 执行。早期 Hive 只支持 MapReduce(Hive 0.x 时代),从 Hive 0.13 起支持 Tez(性能更好),从 Hive 1.1 起支持 Spark。现代 Hive 部署通常用 Tez 或 Spark 作为执行引擎,MapReduce 已退居次要。
Hive Metastore 是独立服务(Thrift Server),存储表 schema、分区、列统计、存储位置(HDFS 路径)。Metastore 后端通常是 MySQL / PostgreSQL。多个 Hive 客户端共享同一 Metastore。
Hive 的存储格式可以选:
1 | |
ORC + Snappy 是 Hive 生产环境的标配,相比 TextFile 节省 70%+ 存储和 I/O。
Hive 的设计哲学是"批处理 SQL"——不是事务、不是实时查询,而是分析型查询(OLAP)。Hive SQL 不支持完整的 ANSI SQL(没有事务、没有索引、限制 UPDATE/DELETE),但优化了 SELECT / JOIN / GROUP BY / WINDOW 等分析操作。
HBase:在 HDFS 之上构建 KV 存储
HDFS 的设计目标是"大文件顺序读写",不适合随机读写——每条记录都是文件级 append,随机修改需要重写整个文件。但很多业务场景需要随机读写(用户画像、实时推荐、消息存储),HDFS 本身无法满足。
HBase(PowerSet 2007 年开源,灵感来自 Google Bigtable 2006 论文)填补了这个空白。HBase 在 HDFS 之上构建 LSM-Tree(Log-Structured Merge-Tree),通过 RegionServer 提供毫秒级随机读写。
HBase 的核心抽象:
1 | |
HBase 的写入路径:
1 | |
这个写入路径的关键是"WAL 写 HDFS + 数据写内存"——WAL 保证宕机后数据可恢复(HDFS 多副本),内存写让延迟低(毫秒级)。这种"日志 + 内存 + 异步合并"是 LSM-Tree 的标准设计。
读取路径:
1 | |
读取涉及多个层级,延迟在 1-10ms 之间(HBase 通常 P99 < 10ms)。这与 HDFS 直接读的 100ms+ 延迟相比有显著优势,但比 Redis / Memcached 这类纯内存 KV(亚毫秒级)仍然慢。
HBase 的 RegionServer 是有状态的——每个 Region 只能由一个 RegionServer 服务(不是多副本)。RegionServer 宕机时它服务的所有 Region 不可用几秒到几十秒,等 ZooKeeper 检测 + Master 重新分配 Region。这种"单点 RegionServer + 宕机切换"是 HBase 的固有不稳定性,需要应用层重试兜底。
Pig:脚本化数据流编程语言
Pig(Yahoo 2008 年开源)的设计目标是让数据工程师写"脚本"而不是"MapReduce Java 代码"处理 ETL。Pig Latin 是一种声明式数据流语言:
1 | |
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 的工程投入下降。Yahoo 内部 Pig 团队解散后,Apache Pig 项目维护缓慢,新特性几乎停滞。社区逐渐迁移到 Spark。
现在 Pig 几乎只在历史 Yahoo 系公司的存量 ETL 流水线里出现,新项目不再选 Pig。这是 Hadoop 生态里"工具自然淘汰"的典型例子——不是 Pig 设计错误,是它的生态位被 Spark 取代了。
生态工具的共同模式
Hive、HBase、Pig(以及 Sqoop、Flume、Oozie、Mahout、HCatalog 等几十个工具)共享一组模式:
底层是 HDFS + YARN——所有工具都跑在 HDFS 上存储,跑在 YARN 上计算。Hadoop 提供了存储和计算的统一基座,让上层工具不需要重复实现分布式系统基础设施。
接口层是多样化的——Hive 提供 SQL、HBase 提供 KV API、Pig 提供数据流语言、Sqoop 提供 RDBMS 同步、Oozie 提供工作流编排。每个工具针对特定使用场景,不试图成为"通用解决方案"。
Metastore 是共享元数据——Hive Metastore、HBase Catalog、Oozie Workflow Database 等共享元数据存储,让多个工具能协作(例如 Spark 通过 Hive Metastore 读 Hive 表 schema)。
执行引擎可替换——Hive 可以跑在 MapReduce / Tez / Spark 上,Pig 可以跑在 MapReduce / Tez 上,HBase 可以跑在 HDFS / S3 上。这种"接口稳定、实现可替换"让生态系统能逐步演化(MapReduce → Tez → Spark)而不需要重写工具。
实验:观察生态工具
提交一个 Hive 查询:
1 | |
观察 Hive 把 SQL 翻译成几个 Stage、每个 Stage 的 Map/Reduce Task 数、Shuffle 字节数。Hive 的 EXPLAIN 命令展示执行计划:
1 | |
输出 Operator DAG 和 Stage 划分。
提交一个 HBase 操作:
1 | |
观察 HBase 的毫秒级响应。打开 HBase Master Web UI(默认 16010 端口)查看 Region 分布、RegionServer 状态、HFile 大小。
提交一个 Pig 脚本(如果集群还装着 Pig):
1 | |
观察 Pig 把脚本编译成多少 MR 作业。
模式提炼
Hadoop 生态体现的设计模式:
1 | |
这个模式不只是 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),不试图用所有工具。"少即是多"在大数据栈设计里很重要。
练习
-
在 Hive 里执行
EXPLAIN SELECT count(*) FROM some_table GROUP BY some_column,观察 Hive 把 SQL 翻译成几个 Stage、每个 Stage 的算子树。然后切换执行引擎(set hive.execution.engine=tez或spark),重新 EXPLAIN 对比差异。 -
在 HBase shell 里创建表、插入数据、扫描。打开 HBase Master Web UI 观察 Region 分布、RegionServer 状态。故意 kill 一个 RegionServer 进程,观察 ZooKeeper 检测 + Master 重新分配 Region 的过程。
-
在
apache/hive源码里找到Driver.java、SemanticAnalyzer.java、MapRedTask.java(hive-exec 模块),观察 Hive SQL 编译的核心实现。在apache/hbase源码里找到HRegionServer.java、HStore.java,观察 HBase 写入路径。 -
思考题:如果让 Hive 完全脱离 Hadoop(不用 YARN、不用 HDFS),它的设计需要怎么改造?这种"Hive on Cloud"现在有哪些实现(例如 Hive on AWS EMR、Hive on Azure HDInsight)?
系列导航
| 序号 | 主题 | 状态 |
|---|---|---|
| 00-06 | HDFS 存储层 | 第一阶段(已完成) |
| 07-12 | YARN 资源管理层 | 第二阶段(已完成) |
| 13-15 | MapReduce 计算模型 | 第三阶段(已完成) |
| 16-19 | HA、安全与 Common 基础设施 | 第四阶段(已完成) |
| 20 | Hadoop 生态:Hive、HBase、Pig 的角色分工 | 本篇 |
| 21 | Hadoop vs 对象存储 + 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 生态企业级架构实践)
