考察点
Hive 架构是大数据岗的一面高频题,面试官想确认你不是只会写 SQL,而是知道 SQL 底下发生了什么。通常还会顺着追问:MR 和 Spark 引擎差在哪、CBO 优化器做了什么、为什么加了 map join 就不需要 reduce。
参考答案
整体架构:四个核心组件
Hive 本质上是一个编译器加执行框架,核心组件就四个:
- Driver:SQL 的入口,负责编译和执行调度,内部包含 Parser、Semantic Analyzer、Logical Plan、Optimizer、Physical Plan、Executor 这一整条流水线。
- Metastore:元数据服务,存表结构、分区信息、数据在 HDFS 上的路径,持久化在 MySQL 等关系库里。所有引擎(Hive、Spark、Presto)都可以共用一套 Metastore,这是湖仓一体的基础。
- 执行引擎:早期是 MapReduce(
hive.execution.engine=mr),后来是 Tez(DAG,复用容器),现在主流是 Spark。 - HDFS:实际数据存储,Hive 表就是一个 HDFS 目录,分区是子目录。
一条 SQL 变成任务的四个阶段
以 select dept, count(*) from emp where ds='20260701' group by dept 为例:
- 解析(Parse):用 ANTLR 把 SQL 字符串解析成抽象语法树 AST。语法错误在这一步就报了。
- 语义分析与逻辑计划:结合 Metastore 里的元数据,校验表和字段是否存在、类型是否匹配,然后把 AST 转成逻辑算子树(TableScan → Filter → Select → GroupBy)。这一步会做分区裁剪:where 里的
ds='20260701'会让 TableScan 只读那一个分区目录,不用扫全表。 - 逻辑优化(Optimizer):规则优化加代价优化。规则优化(RBO)包括谓词下推(把 Filter 压到 Scan 之前)、投影裁剪(只读需要的列)、子查询消除、常量折叠。代价优化(CBO)基于表统计信息(行数、大小、列的 NDV 直方图)决定 join 顺序和 join 策略。统计信息靠
analyze table xxx compute statistics采集,CBO 开启后如果统计信息缺失,代价模型反而会选错计划,这一点很多人忽略。 - 物理计划与执行:把逻辑计划翻译成引擎任务。MR 引擎下就是 Map 和 Reduce 两个阶段的串接;Tez/Spark 引擎下是 DAG,可以把多个 stage 组合起来,中间结果不一定落盘。
不同算子在 MR 上的实现方式
面试官最想听的就是这一段:
- Map 端算子:select、filter、map join 都在 map 阶段完成,没有 shuffle。
- Reduce 端算子:group by、distinct、reduce join(common join)、sort by、order by 都需要 shuffle。shuffle 按键分区,同组的记录进同一个 reduce,所以数据倾斜的本质是某个 key 的记录特别多,对应的 reduce 实例被拖死。
- order by 是全局排序,只有一个 reducer(除非开了严格模式限制),数据量大时慎用;
sort by + distribute by是分区排序,每个 reducer 内有序,用来替代全局排序。
为什么换引擎性能差几倍
MR 每个 job 的中间结果都写 HDFS,一条复杂 SQL 拆成好几个 job,光落盘就耗掉大量时间。Tez 和 Spark 把多 job 合成 DAG,中间结果走内存或本地磁盘,容器还能复用,省掉 JVM 反复启动的开销。同一条 SQL 从 MR 切到 Spark,普遍能快 2-5 倍,数据 shuffle 占比越高收益越大。
可能的追问
- Tez 和 Spark 引擎怎么选? Tez 是 Hive 原生集成,HiveServer2 上多租户场景稳;Spark 生态更广,如果团队本来就有 Spark 集群,用 Spark 引擎可以统一调度资源。
- 一条 SQL 会生成几个 job? 看逻辑计划里出现几次 shuffle 边界。每个需要 shuffle 的算子(join、group by、distinct 等)会切出一个 stage,可以用
explain看 stage 划分。 - HiveServer2 在架构里是什么角色? 它是 Driver 的服务化封装,接收 JDBC/Beeline 连接,管理会话,负责鉴权(Ranger 集成也在这层)。生产集群一般用高可用部署,前面挂 ZooKeeper 做服务发现。