大数据数仓存储与查询链路技术总结

大数据数仓存储与查询链路技术总结文档

本文梳理Hive元数据、SparkSQL、Trino、Doris、Parquet等常用组件的调用链路,区分不同业务场景下的架构差异,用于帮助对大数据技术不熟悉的小伙伴理解组件分层。

从MySQL开发到Spark实战 · 思维转换与入门教程

数仓整体系统架构图

文档约定:

  1. 分层固定为三层:计算引擎层、元数据层、存储层
  2. 每个场景独立流程图,只保留场景内用到组件,剔除无关内容,避免图面复杂;
  3. 本文档暂不深入湖仓一体的大量优化细节,重点区分【裸文件Hive表】与【Iceberg表】的本质差异。

1 名词解释

名词 释义
计算引擎 负责解析SQL、生成执行计划、执行过滤/聚合/关联计算。本文档涉及Trino、SparkSQL、HiveSQL、Apache Doris。 Trino:交互式查询引擎,本身不持久化数据,依赖外部元数据与存储; SparkSQL:支持批处理ETL+查询,可读写对象存储/HDFS; HiveSQL:传统Hive的SQL引擎; Doris:存储计算一体化OLAP引擎,支持内部表,也可通过外表读取外部存储上的文件。
元数据层 记录表结构、字段类型、分区信息、文件路径、分片信息。 Hive Metastore(HMS):最通用元数据服务,Hive/Spark/Trino/Doris外表共用; Doris内置元数据:Doris内部表自用,不依赖HMS。
存储层 存放物理数据载体。包含底层存储介质(HDFS、COS、S3、BE本地磁盘)+ 文件格式。
文件格式 单个数据文件内部的序列化组织方式,独立于上层表定义。 Parquet:列式存储,支持列裁剪、RowGroup级谓词下推; ORC:Hive原生列式格式,Hive事务支持更好。
分区表 Hive/Spark层面的表逻辑组织方式,按指定字段拆分为不同目录,查询时做分区剪枝,跳过无关目录。分区属于元数据定义,不修改Parquet/ORC文件内部结构。
Iceberg 表格式(不是文件格式),底层仍然使用Parquet。在裸Parquet之上增加独立快照、manifest、元数据文件,提供ACID写入、时间旅行、并发写入、schema演进能力。HMS仅记录Iceberg表的根路径,快照、文件清单由Iceberg自行管理。
裸Parquet表 普通Hive外部表,直接在HDFS/对象存储目录写入parquet文件,HMS只记录表和分区目录,没有额外的快照元数据。写入无事务保障。
StorageHandler Hive体系内的适配接口,用于HiveSQL读写不同文件格式;Spark复用该接口,Trino读取Hive Catalog时不使用StorageHandler。本文档流程图不单独画出,封装在HiveSQL引擎内部。

2 整体架构说明

2.1 三层架构综合流程图(总览)

仅用于理解三层边界,实际业务中一般不会同时全部组件一起使用。

graph LR subgraph 计算引擎 Trino[Trino] SparkSQL[SparkSQL] HiveSQL[HiveSQL] Doris[Apache Doris] end subgraph 元数据 HMS[Hive Metastore] DorisMeta[Doris内置元数据] end subgraph 存储 subgraph 文件格式 Parquet[Parquet] ORC[ORC] end HDFS[HDFS] COS[COS对象存储] S3[S3对象存储] DorisDisk[Doris BE本地磁盘] end Trino <--> HMS SparkSQL <--> HMS HiveSQL <--> HMS Doris <--> DorisMeta Doris -.-> HMS Trino --> Parquet SparkSQL --> Parquet HiveSQL --> ORC Doris --> DorisDisk Doris -.-> Parquet Parquet --> HDFS Parquet --> COS Parquet --> S3 ORC --> HDFS

2.2 通用查询时序(所有HMS托管外部表通用流程)

场景:Trino/SparkSQL查询HMS托管的外部Parquet表

sequenceDiagram participant CE as 计算引擎 participant Meta as 元数据(HMS) participant Store as 存储(HDFS/S3/COS) Note over CE,Store: 通用查询流程:HMS托管外部表 CE->>Meta: 请求表结构、分区列表、文件路径 Meta-->>CE: 返回元数据,引擎执行分区剪枝,过滤不满足条件分区 CE->>Store: 根据剩余文件路径发起文件读取请求 Store-->>CE: 返回Parquet原始字节流 Note over CE: 引擎内部解析Parquet Footer,执行列裁剪、RowGroup谓词下推 CE->>CE: 内存完成过滤、聚合、关联计算 CE-->>CE: 返回结果集给用户

2.3 存储和格式比较

Parquet / ORC / Avro / TextFile 对比表 > 说明:基于Hive/SparkSQL/Trino生态,从存储类型、编码特点、适用场景、优缺点整理,数仓运维视角。

特性 TextFile Avro Parquet ORC
存储类型 行式存储 行式存储 列式存储 列式存储
数据组织 纯文本,一行一条记录 二进制行存储,一条记录完整存放 按列拆分存储,同一列数据连续存放 列式存储,Hive原生优化列式
序列化方式 文本(UTF-8) Avro二进制序列化 Parquet二进制 ORC二进制
Schema支持 无内置schema,靠建表语句定义 自带schema,支持schema演进(增删字段、兼容旧数据) 自带schema,支持schema演进 自带schema,支持schema演进
压缩 可开启Gzip/Snappy;压缩效率差 压缩效果较好 压缩率高,同数据体积更小 压缩率高,Hive生态下压缩优化强
读取模式 读取必须加载整行;读少量字段也要读完整行 读取整行记录,无法只读取部分列 支持列裁剪,只读取查询用到的列;支持RowGroup级谓词下推 支持列裁剪,支持Stripe/Index谓词下推,内置轻量索引
写入性能 写入快,无需序列化 写入性能较好,CDC场景友好 批量写入性能不错,小批量写入容易产生小文件 Hive引擎写入性能最优
Hive事务支持 不支持 不支持 Hive事务支持一般 原生支持Hive ACID事务(Update/Delete)
跨引擎兼容性 极好,所有引擎都可读 很好,Spark/Hive/Trino通用 跨引擎兼容性最好,Spark默认格式,Hive/Trino/Doris外表都支持 Hive生态最优;跨引擎支持弱于Parquet
典型适用场景 原始日志临时落地、调试查看内容;临时小表 CDC数据接入、数据交换、需要频繁schema变更场景 通用离线数仓、湖仓(Iceberg/Hudi底层默认),多引擎共享数据 传统Hive数仓,需要Hive事务、Hive批量ETL场景
主要缺点 体积大,查询慢;无法谓词下推;容易脏数据 行式,查询大表只取少数列时IO开销大 Hive原生事务能力弱;元数据Footage略大 Trino/Spark读取性能略弱于Parquet,跨引擎通用性稍差

补充运维备注

  1. TextFile:可直接用cat查看文件内容,调试方便,但生产大表严禁使用,IO开销巨大。
  2. Avro虽然是行式,但schema内嵌在文件中,适合数据流转,多用于数据同步、CDC采集落地,不适合海量离线分析查询。
  3. Parquet:多引擎共用数仓首选,如果你的数据要同时给Spark、Trino、Doris外表查询,优先Parquet。Iceberg/Hudi底层默认采用Parquet。
  4. ORC:Hive专属优化,老Hive数仓、需要Hive内部做update/delete的场景优先选ORC;如果Trino为主查询引擎,优先Parquet。

3 分场景架构图+场景说明

规则:每个场景独立流程图,三层固定:计算引擎|元数据|存储;只保留当前场景用到组件。

场景1:Trino查询,HMS管理元数据,HDFS存储Parquet

业务场景:离线数仓Hive外部分区表,Trino做交互式查询,数据文件存HDFS,文件格式Parquet。 适用场景:分析师即时查询、报表查询,数据主要为离线批量写入。

graph LR subgraph 计算引擎 Trino[Trino] end subgraph 元数据 HMS[Hive Metastore
表结构、分区、HDFS文件路径] end subgraph 存储 subgraph 文件格式 Parquet[Parquet] end HDFS[HDFS分布式存储] end Trino <--> HMS Trino --> Parquet Parquet --> HDFS

链路说明

  1. Trino连接HMS,获取表定义、分区信息;
  2. 根据where条件做分区剪枝,过滤不需要扫描的HDFS目录;
  3. Trino读取HDFS上Parquet文件,引擎内部解析parquet,做列裁剪、RowGroup过滤;
  4. 内存计算后返回结果。

场景2:SparkSQL查询/ETL,HMS管理元数据,COS存储Parquet(裸Parquet Hive表)

业务场景:云上数仓,Spark负责ETL写入+查询,HMS管理元数据,数据存腾讯云COS对象存储,普通Hive外部分区表(裸Parquet,无Iceberg)。 适用场景:每日一次性批量追加数据,无并发写、无更新、不需要回滚。

graph LR subgraph 计算引擎 SparkSQL[SparkSQL] end subgraph 元数据 HMS[Hive Metastore
表结构、分区、COS文件路径] end subgraph 存储 subgraph 文件格式 Parquet[Parquet] end COS[COS对象存储] end SparkSQL <--> HMS SparkSQL --> Parquet Parquet --> COS

链路说明

  1. SparkSQL读写HMS,维护分区元数据;
  2. ETL任务生成Parquet文件写入COS;
  3. 查询时Spark读取COS上parquet文件,做分区剪枝和列式过滤。> > 风险点:裸Parquet表写入无事务,任务中途失败会产生残次文件;多任务同时写同一分区会产生脏数据,无法回滚。

场景3:Doris内部表查询,Doris自研元数据与本地存储

业务场景:Doris内部业务表,数据写入Doris BE节点本地磁盘,不依赖HMS、HDFS、对象存储、Parquet。 适用场景:高并发报表、实时指标、点查询,存储计算一体化。

graph LR subgraph 计算引擎 Doris[Apache Doris] end subgraph 元数据 DorisMeta[Doris内置元数据
表、分区、分片信息] end subgraph 存储 DorisDisk[Doris BE本地磁盘
Doris自研列式存储] end Doris <--> DorisMeta Doris --> DorisDisk

链路说明

  1. Doris自带计算、元数据管理、存储三层能力;
  2. 数据分片存BE本地磁盘,Doris内部完成分区、分片剪枝;
  3. 不依赖外部HMS,不使用Parquet。

场景4:Doris外表查询,HMS管理元数据,S3存储Parquet

业务场景:Doris通过Hive Catalog外表,直接查询S3上Hive外部Parquet表,Doris不存储原始数据。 适用场景:Doris直接分析湖侧原始数据,不需要把数据导入Doris内部。

graph LR subgraph 计算引擎 Doris[Apache Doris] end subgraph 元数据 HMS[Hive Metastore
表结构、分区、S3文件路径] end subgraph 存储 subgraph 文件格式 Parquet[Parquet] end S3[S3对象存储] end Doris <--> HMS Doris --> Parquet Parquet --> S3

链路说明

  1. Doris连接HMS获取表、分区信息;
  2. 分区剪枝后,Doris直接读取S3上Parquet文件;
  3. Doris仅做查询,不会修改S3上原始文件。

场景5:HiveSQL查询,HMS管理元数据,HDFS存储ORC

业务场景:传统Hive离线数仓,HiveSQL作为计算引擎,HDFS存储ORC格式。 适用场景:老Hive数仓,需要Hive原生事务(ACID V2)。

graph LR subgraph 计算引擎 HiveSQL[HiveSQL] end subgraph 元数据 HMS[Hive Metastore
表结构、分区、HDFS文件路径] end subgraph 存储 subgraph 文件格式 ORC[ORC] end HDFS[HDFS分布式存储] end HiveSQL <--> HMS HiveSQL --> ORC ORC --> HDFS

链路说明

  1. HiveSQL访问HMS获取元数据;
  2. Hive内部加载StorageHandler,读取HDFS上ORC文件;
  3. ORC对Hive引擎优化更好,原生支持Hive事务。

场景6:SparkSQL读写Iceberg表,HMS管理元数据,S3底层Parquet

业务场景:湖仓场景,Spark读写Iceberg表,底层物理文件依旧是Parquet,HMS只记录Iceberg表根路径。 适用场景:需要并发写入、数据回滚、时间旅行、部分数据更新(MERGE INTO)。

graph LR subgraph 计算引擎 SparkSQL[SparkSQL] end subgraph 元数据 HMS[Hive Metastore
Iceberg表根路径] end subgraph 存储 subgraph 文件格式 Parquet[Parquet] end S3[S3对象存储] end SparkSQL <--> HMS SparkSQL --> Parquet Parquet --> S3

链路说明 & 和场景2(裸Parquet)对比

底层物理文件都是Parquet,存储介质都是S3,HMS都参与。核心差别在元数据管理主体:

  1. 场景2(裸Parquet):HMS记录分区目录,没有快照。写入无事务,任务失败产生残次文件;无法回滚,不支持并发写同一分区。适合简单一次性追加。
  2. 场景6(Iceberg):HMS只存Iceberg表根路径;快照、manifest、文件清单全部由Iceberg自己维护。写入通过元数据指针原子切换,保证ACID;支持时间旅行、MERGE INTO更新、并发写入。> > 代价:增加Iceberg元数据维护成本,需要定时执行Compaction合并小文件、清理过期快照。

4 场景对比汇总表

序号 场景 计算引擎 元数据来源 存储介质 文件格式 适用场景 核心特点
1 Trino读Hive表HDFS Trino HMS HDFS Parquet 交互式报表查询 Trino联邦查询,只读外部Hive数据
2 SparkSQL读写裸Parquet Hive表,COS SparkSQL HMS COS Parquet 每日一次性批量追加 简单稳定,无事务,不支持更新回滚
3 Doris内部表 Doris Doris内置元数据 BE本地磁盘 Doris自研 高并发实时指标、报表 存储计算一体,不依赖外部元数据
4 Doris外表读取S3 Parquet Doris HMS S3 Parquet Doris直接查询湖数据 不导入数据,直接查询对象存储
5 HiveSQL读取ORC HDFS HiveSQL HMS HDFS ORC 传统Hive离线数仓 ORC适配Hive原生事务能力
6 SparkSQL读写Iceberg表 SparkSQL HMS S3 Parquet 湖仓,并发写入、更新、回滚 Parquet底层,Iceberg增加快照与事务能力

5 运维关注点小结

  1. 裸Hive分区表(场景1/2/5):运维重点关注分区生命周期、小文件治理、元数据同步;写入要避免多任务并发写同一分区。
  2. Iceberg表:除小文件外,额外关注快照过期清理、Compaction任务调度,防止元数据文件持续膨胀。
  3. Doris内部表:运维重点在BE节点磁盘、分片均衡、副本;Doris外表重点关注对象存储AK/SK权限。
  4. 跨引擎共用同一份HMS+Parquet文件:Trino、Spark、Hive可以读取同一份物理文件,需要保证字段类型、时区定义统一,避免解析不一致。

大数据数仓存储与查询链路技术总结
https://jycpp.github.io/2026/26-07-18-大数据数仓存储与查询链路技术总结.html
作者
Jet Yan
发布于
2026年7月18日
许可协议