Apache Doris 作为一款高性能的 MPP 分析型数据库,其存储架构的设计直接决定了其在大规模数据场景下的查询效率、写入性能与运维灵活性。本文将全方位深度解析 Doris 的数据存储机制,揭示其在工程实现中的设计与逻辑。
一、数据组织:从逻辑模型到物理存储的层级映射
Doris 的数据组织采用自上而下的层级细化模型,每一层都承担着特定的功能职责,共同支撑起整个系统的高效运行。这种层级结构不仅是数据存储的基础,更是读写优化、副本管理、运维操作的核心载体。
层级关系示意图:
1.1 逻辑层:业务建模的核心载体
- 表(Table):作为最高层级的逻辑单元,表直接映射业务实体,包含列定义、数据类型、主键 / 排序键、数据模型(Duplicate/Aggregate/Unique)等元信息。表的设计决定了后续存储与查询的优化方向,例如排序键的选择直接影响前缀索引的效率。
- 分区(Partition):基于业务字段(如时间、区域)对表进行逻辑划分,支持 RANGE 分区(适用于连续值,如时间范围)和 LIST 分区(适用于离散值,如地区编码)。分区是数据生命周期管理的核心单位,可独立配置存储介质(SSD/HDD)、TTL(生存时间)等策略,实现冷热数据的差异化管理。
1.2 物理层:分布式存储的核心单元
- 分桶(Bucket)/Tablet:分区的物理细分单元,通过对分区内数据按哈希(Hash)或随机(Random) 方式切分形成。每个 Tablet 是 Doris 中最小的物理存储单元,也是数据均衡、副本管理的基本单位。默认情况下,分桶数量由
BUCKETS 参数指定,建议根据单节点磁盘容量与并发查询需求设置(通常每个 Tablet 大小推荐控制在 1GB-10GB 之间)。 - 副本(Replica):为保证数据可靠性与高可用,每个 Tablet 会存储多个副本(默认 3 副本),副本分布在不同的 BE(Backend)节点上。副本之间通过保持一致性,支持自动修复与负载均衡。
1.3 版本与文件层:数据变更的载体
- Rowset:一次数据变更(如导入、删除、更新)产生的版本化数据集合,包含一个或多个 Segment 文件。Rowset 具有版本号(Version) 属性,通过多版本机制支持事务隔离与原子性提交(两阶段提交)。
- Segment:Rowset 拆分后的物理文件单元,默认大小为256MB。这一大小设计兼顾了并行处理效率(单个 Segment 可被单个线程处理)与元数据管理开销(过多小文件会增加内存负担)。
- Page:列式存储的最小 IO 单元,分为数据页(Data Page)与索引页(Index Page),默认大小 64KB。Page 是压缩、编码与缓存的基本单位,通过按需加载减少 IO 消耗。
二、Segment V2:自研列存文件格式的设计与实现
Doris 采用自研的 Segment V2 作为列存文件格式,其设计目标是在保证查询效率的同时,最小化存储开销与 IO 成本。Segment V2 采用三段式结构(数据区、索引区、Footer),并通过精细化的编码与压缩策略优化性能。
2.1 三段式结构解析
- Data Region(数据区):按列存储所有数据页,每列的 Page 连续排列。列存设计使得查询时可只加载所需列(投影优化),减少无效 IO。
- Index Region(索引区):集中存储该 Segment 关联的所有索引页,包括前缀索引、ZoneMap、Bitmap 等。索引区与数据区分离,便于查询时优先加载索引进行过滤。
- Footer(元数据区):记录全局元信息,包括:
- 基础统计:总行数、各列非空行数;
- 偏移信息:数据区与索引区各 Page 的起始偏移与长度;
- 编码压缩:各列采用的编码(如字典编码、RLE)与压缩算法(如 LZ4、ZSTD);
- 版本信息:Segment 格式版本与创建时间。
Footer 作为整个 Segment 的 “目录”,在读取时首先被加载,用于快速定位所需数据与索引页。
2.2 工程细节:Segment 大小与 Page 管理
- Segment 大小控制:默认 256MB 的设计基于以下考量:
- 并行处理:单个 Segment 可被一个线程独立处理,避免过大文件导致的并行度下降;
- 均衡分布:便于 Tablet 内的 Segment 在 BE 节点间均衡迁移;
- 元数据开销:单个 Segment 的元数据(Footer + 索引)约占文件大小的 0.1%-1%,256MB 对应的元数据约 256KB-2.5MB,可被内存高效缓存。
- Page 组织:每个列的 Page 按行号顺序排列,Footer 中的
Ordinal Index 记录行号到 Page 的映射(如行 0-1023 对应 Page 1),作为查询时的 “一级导航”。其他索引查找数据时,都要通过Ordinal Index查找数据Page的位置。
三、写入与 Compaction:事务一致性与存储优化
Doris 的写入流程与 Compaction 机制是保证数据一致性、优化存储布局的核心环节,其设计借鉴了 LSM-Tree 的思想,但针对列存与 OLAP 场景做了深度定制。
3.1 写入路径:从数据接收到底层落盘
- 前端分发:FE(Frontend)接收导入请求,解析并生成执行计划,分发至对应 BE 节点;
- 内存写入:BE 接收到数据后,先写入 MemTable(内存表,支持排序与主键去重);
- 刷盘(Flush):当 MemTable 达到阈值(默认 128MB 或 5 分钟),异步刷盘生成 Segment 文件,组成一个 Rowset;
- 事务提交:采用两阶段提交(2PC)确保所有副本刷盘完成,生成全局版本号(publish version),数据对外可见。
3.2 Compaction:合并小文件,优化查询效率
随着多次写入,Tablet 会产生大量小 Rowset,导致查询时需要扫描过多文件。Compaction 机制通过合并小 Rowset 解决这一问题,分为两种类型:
- Cumulative Compaction:合并最近的多个小 Rowset,生成中等大小的 Rowset,频率较高(可调整);
- Base Compaction:合并所有 Rowset 为一个大 Rowset,彻底清理无效版本与删除记录,频率较低(可调整)。
Compaction 与 LSM-Tree 的差异:
- LSM-Tree 通常按时间分层(如 Level 0、Level 1),而 Doris 按 Rowset 版本合并,更贴合多版本事务场景;
- LSM-Tree 读时可能需要合并多层数据,而 Doris 通过 MoW 与 Compaction 减少读时合并,降低查询放大。
更多Compaction相关内容可以参考:深入理解 Doris Compaction:提升查询性能的幕后功臣
四、读取与缓存:多级缓存加速查询
Doris 设计了多级 LRU 缓存体系,通过缓存热点数据与元信息,显著降低 IO 延迟,提升查询响应速度。
4.1 缓存层级与职责
- Page Cache:缓存数据页(Data Page)、索引页(Index Page)与 PKIndex 页,是最贴近查询的缓存层级,默认大小为机器内存的 30%;
- Metadata Cache:缓存 Segment 元数据(Footer)、Tablet Schema、版本信息等,避免频繁读取磁盘元数据;
- Cloud Cache:在存算分离场景下,缓存对象存储(如 S3)中的热数据,降低远程 IO 延迟。
每级缓存均可通过参数独立配置大小(如 page_cache_limit 控制 Page Cache 上限),并通过监控指标(如 doris_be_cache_hit_rate)观察命中率。
4.2 读取流程:按需加载,减少无效 IO
查询时的读取流程充分利用索引与缓存:
- 索引过滤:通过 ZoneMap、前缀索引等过滤无效 Segment 与数据页;
- 缓存检查:优先从 Page Cache 加载所需 Page,未命中则从磁盘或对象存储读取;
- 列裁剪:只加载查询涉及的列,跳过无关列;
- 数据解码:对加载的 Page 进行解压与解码,返回给计算层。
这种 “过滤→缓存→裁剪” 的流程,可将无效 IO 大幅降低。
五、总结:架构设计的 “OLAP 基因”
Doris 的存储架构每一处取舍都紧扣 OLAP 场景的核心需求 ——海量数据下的快速分析:
- 查询快:通过索引过滤、列存裁剪、缓存加速,将响应时间控制在秒级甚至毫秒级;
- 能写入:支持高吞吐批量导入,容忍一定的写入延迟以换取查询收益;
- 成本低:通过压缩、稀疏索引、冷热分层,降低存储与运维成本。
这套架构使得 Doris 在 TB 到 PB 级数据规模下,能够稳定支撑实时报表、用户画像、日志分析等典型 OLAP 场景,成为企业级数据分析的核心引擎。
往期推荐
Doris BE节点下线卡住?快速排障技巧全攻略!
Apache Doris 索引的全面剖析与使用指南
Apache Doris 湖仓一体:打破数据边界,解锁实时分析的终极答案
Doris vs ClickHouse 企业级实时分析引擎怎么选?
Doris查询报错-230?别慌,教你几招秒解!
Doris Tablet 损坏如何应对?能恢复数据吗?
Doris 导入慢该如何排查和优化
Doris 建表与分区问题全解析
完
●
数据极客圈子介绍
●
圈子1
Apache Doris社区是目前国内最活跃的开源社区(之一)。Apache Doris(Apache 顶级项目) 聚集了世界全国各地的用户与开发人员,致力于打造一个内容完整、持续成长的互联网开发者学习生态圈!
如果您对Apache Doris感兴趣,可以通过以下入口访问官方网站、社区论坛、GitHub和dev邮件组:
💡官网文档:https://doris.apache.org
💡社区论坛:https://ask.selectdb.com
💡GitHub:https://github.com/apache/doris
💡dev邮件组:dev@doris.apache.org
可以加作者微信(Faith_xzc)直接进Doris官方社区群
圈子2
PowerData是由一群数据从业人员,因为热爱凝聚在一起,以开源精神为基础,组成的数据开源社区。
社区群内会定期组织模拟面试、线上分享、行业研讨、线下Meetup、城市聚会、求职内推等活动,同时在社区群内你可以进行技术讨论、问题请教,结识更多志同道合的数据朋友。
社区整理了一份每日一题汇总及社区分享PPT,内容涵盖大数据组件、编程语言、数据结构与算法、企业真实面试题等各个领域,帮助您提升自我,成功上岸。
可以加作者微信(Faith_xzc)直接进PowrData官方社区群
叮咚✨ “数据极客圈” 向你敞开大门,走对圈子跟对人,行业大咖 “唠” 数据,实用锦囊天天有,就缺你咯!快快关注数据极客圈,共同成长!