当前位置: 首页 > news >正文

深入理解 Doris Compaction:提升查询性能的幕后功臣

在这里插入图片描述
在 Doris 的数据存储与查询体系里,Compaction 是保障查询效率、优化存储结构的关键机制。如果你好奇 Doris 如何在高频写入后仍能高效响应查询,或是想解决数据版本膨胀带来的性能问题,这篇关于 Compaction 的深度解析值得收藏 👇

一、为什么需要 Compaction?

Doris 采用类 LSM - Tree 的存储结构,每次数据导入会生成新的 Rowset(可理解为数据版本片段 ),每个rowset由0到n个sgement组成。segment实际对应这个磁盘上的一个文件。单个sgement文件是有序的。

存储文件目录结构

随着导入操作增多,Rowset 数量不断累积,会引发两大核心问题:

(一)查询效率下降

查询时,Doris 需要对多个 Rowset 执行 “多路归并” 操作来整合结果。Rowset 数量越多,归并的路数就越多,查询耗时呈几何级增长。例如,若一个查询需要合并 10 个 Rowset,归并过程就像同时梳理 10 条杂乱的线,难度和耗时远大于合并 2 - 3 个 Rowset。

(二)存储成本上升

大量零散的 Rowset 会占用更多磁盘空间,还可能存储重叠和无效数据。比如多次导入同一范围的数据,会生成多个有重叠的 Rowset,不仅浪费存储,还会让查询时的归并逻辑更复杂。

Compaction 的核心目标

  • 减少查询归并成本:将多个小 Rowset 合并为大 Rowset,降低查询时的合并路数。
  • 消除无效数据:将标记删除(Delete)、更新(Update)的数据真正清理,避免查询时的无效扫描。
  • 优化存储:在 Aggregate 模型中预聚合相同 Key 的数据,在 Unique 模型中保留最新版本,进一步提升查询效率。

compaction的粒度是tablet,下图是一个tablet compaction过程的示意图

tablet 的 compaction过程

二、Compaction 关键概念解析

1. Compaction Score:优先级调度指标

Compaction Score 是 Doris 判断 Tablet 做Compaction优先级的核心指标,值越高,优先级越高

(一)本质

反映查询时 Rowset 参与 “多路归并” 的路数。路数越多,查询效率越低,越需要优先compaction。

(二)计算逻辑

遍历 Tablet 的 Rowset,根据其数据重叠情况统计归并路数:

若某 Tablet 的 Rowset 分布如下:

"rowsets": ["[0-100] 3 DATA NONOVERLAPPING ...", // 无重叠,归并占 1 路 "[101-101] 2 DATA OVERLAPPING ...",  // 有重叠,归并占 2 路 "[102-102] 1 DATA NONOVERLAPPING ..." // 无重叠,归并占 1 路 
]
  • 无重叠 Rowset:如 [0-100] 范围的 Rowset 由 3 个Segment 组成,但是没有但是没有overlap,查询归并时仅占 1 路;

  • 有重叠 Rowset:如 [101-101] 范围的 Rowset 由 2 个Segment 组成,但是有但是有overlap,查询归并时占 2 路。

则 Compaction Score = 1(第一行) + 2(第二行) + 1(第三行) = 4

2. Base & Cumulative Compaction:分层合并策略

为了平衡 “压缩效率” 和 “数据合并成本”,Doris 采用分层压缩思路:

(1)Cumulative Compaction
  • 作用:优先合并新写入的小 Rowset,避免直接与大 Rowset 合并导致效率低下。新导入的零散数据(如实时写入的小批次数据 ),先通过Cumulative Compaction逐步 “攒大”,减少后续 Base Compaction 的压力。
(2)Base Compaction
  • 作用:当Cumulative Rowset 合并到一定规模后,再与 ** 历史大 Rowset(Base Rowset)** 合并,最终形成更紧凑的大 Rowset,彻底优化查询路数。
(3)Cumulative Point:分层 “临界点”

用来划分 “Cumulative Rowset” 和 “Base Rowset” 的边界。比如某 Tablet 的 Cumulative Point 为 293,意味着:

compaction图

  • Rowset 范围 293+ 做的是 Cumulative Compaction;

  • Rowset 范围 0-292 做的是 Base Compaction。

三、Compaction 工作流程:生产者 - 消费者模式

Doris 的 Compaction 流程遵循生产者 - 消费者模型,可拆解为 4 大核心步骤,每个步骤都蕴含精细的设计逻辑:

1. 扫描与优先级计算(生产者线程)

BE 的 Compaction 生产者线程定时(可配置扫描间隔)扫描所有 Tablet,执行以下操作:

(一)计算 Compaction Score

遍历 Tablet 的 Rowset,统计每个 Rowset 在查询时的归并路数,累加得到 Compaction Score,确定compaction优先级。

(二)分层任务调度

Doris 通过轮询策略平衡 Base 和 Cumulative Compaction 的资源占用:

  • 默认每 10 轮扫描选 1 次 Base Compaction 任务(处理历史大 Rowset 合并 );

  • 其余 9 轮选 Cumulative Compaction 任务(快速合并新写入的小 Rowset )。

    这样设计的原因是:Base Compaction 通常涉及更大数据量,资源消耗更高,需控制执行频率;而 Cumulative Compaction 处理小数据,可高频执行以快速优化查询。

2. 并发控制:避免磁盘过载

磁盘的 IO 带宽和处理能力是有限的,若同时执行过多 Compaction 任务,会导致磁盘性能雪崩(比如磁盘 IO 利用率瞬间 100%,其他读写操作阻塞 )。因此,Doris 会:

(一)检查当前任务数

查询磁盘当前运行的 Compaction 任务数,与配置的compaction的线程数对比。

(二)动态跳过机制

若任务数已达阈值,跳过该 Tablet,等待下一轮扫描;若未超限,允许任务继续,确保磁盘资源合理利用。

3. Rowset 筛选策略

并非所有 Rowset 都会被选中压缩,筛选逻辑聚焦两点,这直接影响 Compaction 的效率和效果:

(一)连续性优先

优先选择连续的 Rowset(如按时间或数据范围连续 ),因为零散的 Rowset 合并后,能减少查询时归并的 “碎片问题”。例如,连续的 Rowset 合并后,查询时可一次性归并,而零散 Rowset 可能需要多次跳转磁盘读取。

(二)数据量均衡

避免合并 “大小差距极大” 的 Rowset。在多路归并排序中,若 Rowset 数据量差距过大,归并时小 Rowset 会快速处理完,大 Rowset 仍需大量时间,整体效率会断崖式下跌。因此,筛选时会优先选数据量相近的 Rowset,保证归并过程的高效性。

4. 任务分发:分线程池执行

为了隔离 Base Compaction ·和 Cumulative Compaction 的资源,Doris 设计了两个独立线程池。

Base compaction线程池和cumulative compaction线程池分别从队列中取出compaction task任务后,执行多路归并排序:将多个 Rowset 的数据按顺序合并,生成一个新的大 Rowset。

Compaction工作流程图

四、总结:Compaction 是效率与成本的平衡艺术

理解 Compaction 的逻辑后,再面对 “查询变慢”“存储膨胀” 等问题时,就能从 “数据版本管理” 的视角切入,精准定位与解决。下次遇到 Doris 性能瓶颈,不妨先看看 Compaction 是否在 “默默加班”,是否因配置或数据模式问题导致其 “有心无力”~

如果觉得内容有帮助,欢迎点赞、在看、分享,让更多人了解 Doris 性能优化的幕后逻辑~ 有疑问或补充,也可在评论区交流,一起深入了解 Doris 技术细节 🌱

http://www.lryc.cn/news/604396.html

相关文章:

  • webpack-性能优化
  • 破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践录
  • 2025年6月电子学会青少年软件编程(C语言)等级考试试卷(二级)
  • C++ 中 NULL 与 nullptr 有什么区别?
  • RAG实战指南 Day 29:RAG系统成本控制与规模化
  • WebRTC核心组件技术解析:架构、作用与协同机制
  • mangoDB面试题及详细答案 117道(071-095)
  • Python深度挖掘:openpyxl与pandas高效数据处理实战指南
  • APM32芯得 EP.27 | 告别IDE,为APM32F411打造轻量级命令行开发工作流
  • 微服务消息队列之——RabbitMQ
  • .NET 10 中的新增功能系列文章2——ASP.NET Core 中的新增功能
  • PostGIS安装与pg_dump/pg_restore排错
  • flutter 记录一个奇怪的问题
  • 在 Mac 上用 Vagrant 安装 K8s
  • InfluxDB 3 数据库命名与创建全攻略:规范、限制与实战指南
  • 《零基础入门AI:传统机器学习核心算法解析(KNN、模型调优与朴素贝叶斯)》
  • GaussDB 数据库架构师(十二) 数据库对象修改审计设置
  • Redis学习------缓存穿透
  • llama factory本地部署常见问题
  • Git版本控制器
  • 人工智能与家庭:智能家居的便捷与隐患
  • gdb调试的限制和配置自动生成core
  • 2023 年 NOI 最后一题题解
  • 【C++篇】哈希扩展:位图和布隆过滤器+哈希切割
  • 【Lambda】flatMap使用案例
  • c++之基础B(第一课)
  • dify离线插件打包步骤
  • 在Trae中使用MoonBit月兔
  • 【编号65】广西地理基础数据(道路、水系、四级行政边界、地级城市、DEM等)
  • 在 Elasticsearch 8.19 和 9.1 中引入更强大、更具弹性和可观测性的 ES|QL