Doris内存问题指南:监控、原理与高频OOM解决方案

做Doris运维或开发的同学,多少都踩过内存的坑:BE突然OOM、导入时内存暴涨、查询报"内存不足"...明明配置看着没问题,问题却反复出现?

今天这份指南,从内存分类、监控方法,到核心原理、高频问题解决,全流程覆盖,建议收藏备用

一、先搞懂:Doris的内存都用在哪?

要解决内存问题,先得明确Doris的内存分类和关键配置,避免盲目调参。

1. 内存分类:7类核心内存场景

Doris的内存消耗主要分散在7个场景,不同场景的异常对应不同问题:

标识 名称 核心说明
process BE总使用内存 整个BE进程的内存总占用
query_pool 查询内存 分执行层(如Join、聚合)和存储层(如读数据)
load 导入内存 核心是MemTable(导入数据暂存区),满了会刷盘
table_meta 元数据内存 存储Schema、Tablet、RowSet、列等元信息,版本多会膨胀
compaction 多版本合并内存 数据导入后多版本合并用的内存
snaphost 快照内存 主要用于副本克隆(clone),通常占用很少
column_pool 列缓存 加速列对象的申请与释放,执行线程会保留部分缓存
page_cache BE自有PageCahe 默认关闭,手动开启后缓存热点数据

2. 关键配置:BE与Session变量对照表

内存问题大多和配置不当有关,这两类配置是核心(建议保存备用):

2.1 BE配置(be.conf)
配置项 默认值 核心作用
vector_chunk_size 4096 Chunk分配器的预留字节限制
tc_use_memory_min 10737418240(10G) Tcmalloc最小保留内存,超此值,Doris才把空闲内存返还系统
mem_limit 80% BE可使用的机器总内存比例,混合部署推荐修改,防止OOM
disable_storage_page_cache true 是否关闭自有PageCache(默认关闭)
write_buffer_size 104857600(100M) 单个MemTable内存上限,超了触发刷盘
load_process_max_memory_limit_bytes 107374182400(100G) 导入总内存上限,与百分比取最小值生效
load_process_max_memory_limit_percent 60% 导入内存占BE总内存的比例,min(mem_limit * load_process_max_memory_limit_percent, load_process_max_memory_limit_bytes)
load_mem_limit 2147483648(2G) 单个导入实例接收端内存上限,到达这个限制,会触发刷盘逻辑,需配合Session变量load_mem_limit修改才能生效
2.2 Session变量
变量名 默认值 核心作用
exec_mem_limit 2147483648(2G) 单个查询实例instance的内存限制
load_mem_limit 0 单个导入任务内存限制,0时复用exec_mem_limit

二、内存监控:5种方法精准定位问题

监控是解决内存问题的前提,5种方法覆盖"宏观统计"到"堆栈分析",按需选用:

1. mem_tracker:整体内存统计(最常用)

  • 操作方式 :浏览器访问 http://BE_IP:BE_WEB_PORT/mem_tracker

  • 优势:直观展示各分类内存(如query_pool、load)的占用情况

  • 不足:部分内存未统计(非向量Compaction、存储层读内存)

2. Tcmalloc:最精准的内存统计

  • 操作方式 :浏览器访问 http://BE_IP:BE_WEB_PORT/memz

  • 核心指标解读

    • Bytes in use by application:实际被应用使用的内存(最关键)

    • Actual memory used:物理+交换分区的实际占用

  • 注意:统计的是"预留内存"而非"实时使用内存",需结合业务场景判断

3. metrics:批量监控(适合运维告警)

  • 操作方式 :执行命令 curl -XGET http://127.0.0.1:BE_WEB_PORT/varz | grep 'mem'

  • 优势:可提取关键指标接入监控系统(如Prometheus)

  • 不足:10秒更新一次,实时性一般,老版本仅支持部分统计

4. growth:内存增长堆栈(定位泄漏)

  • 操作方式:生成火焰图分析

    Bash 复制代码
    pprof --svg http://be_host:be_webport/pprof/growth >mem.svg
  • 用途:查看内存增长最快的函数调用栈,定位内存泄漏点

5. HEAP_PROFILE:详细堆栈分析(深度排查)

  • 操作步骤

    1. 设置环境变量并重启BE:

      Bash 复制代码
      export HEAPPROFILE=/tmp/doris_be.hprof
      ./bin/start_be.sh --daemon
    2. 生成堆栈图:

      Bash 复制代码
      pprof --svg lib/doris_be /tmp/doris_be.hprof.0012.heap > heap.svg 
    3. 排查后清理:unset HEAPPROFILE 并重启BE

  • 优势:最详细的内存使用堆栈,适合疑难内存问题

三、核心原理:3大高频内存消耗场景解析

内存问题不是偶然的,这3个场景是消耗内存的"重灾区",理解原理才能精准解决:

1. 导入:MemTable与刷盘逻辑

  • 内存消耗点:发送队列、MemTableFlush队列、SegmentWriter的PageBuffer

  • 关键逻辑 :导入数据先写入MemTable,达到write_buffer_sizeload_mem_limit触发刷盘,刷盘不及时会导致内存堆积

2. Compaction:多版本合并的内存消耗

  • 核心消耗点:Overlapping合并时需打开所有Segment,字典和Chunk占用内存最高

  • 关键限制

    • Cumulative Compaction最多合并1000个版本

    • Base Compaction最多合并5个版本

3. 查询:4类高频高内存操作

  • Join:构建右表哈希表时占用内存,大表广播、表顺序搞反易OOM

  • 聚合:高基数聚合需存储大量中间结果,内存占用陡增

  • TopN:N值过大时需缓存大量数据排序

  • 全量Sort:无索引的全表排序,内存不足会触发磁盘排序

四、高频问题:8类内存异常解决方案

这部分是核心干货,覆盖运维中最常遇到的内存问题,按"问题场景→排查步骤→解决方法"整理:

1. Compaction OOM(最棘手)

预警指标:FE监控doris_fe_tablet_max_compaction_score > 100

1.1 应急处理(先止损)
  1. 关闭自动Compaction:设置disable_auto_compaction=true并重启BE

  2. 重建表:INSERT INTO 新表 SELECT FROM 老表(规避历史版本问题)

  3. 恢复Compaction:改回配置并重启BE

1.2 根因解决
  • 场景A:单个分桶文件过多 排查:SHOW TABLET FROM 表名 → 查看Overlapping Segment数(建议≤100) 解决:① 增加分桶数 ② 缩小分区粒度(如月→天) ③ 调大write_buffer_size(并行导入少时用)

  • 场景B:版本过多 排查:① SHOW TABLET FROM 表名 LIMIT 1 看VersionCount ② 访问http://BE_IP:8040/api/compaction/show?tablet_id=XXX&schema_hash=XXX看未合并版本 解决:降低导入频率(如高频StreamLoad尽可能增大攒批)

  • 场景C:数据倾斜 排查:SHOW TABLETS FROM 表名 看各Tablet大小差异,数据多的Tablet中Segment数比较多,导致第一次Compaction消耗大量内存。 解决:重新建表,选择更均匀的分桶列

2. 导入OOM

2.1 高频场景:Insert Into Select From高并行
  • 现象:导入时load和column_pool内存暴涨

  • 解决:设置Session变量降低并行度

    SQL 复制代码
    set parallel_fragment_exec_instance_num=xxx; 
2.2 其他场景解决
问题原因 解决方法
导入频率过高(版本堆积) 减少RoutineLoad/Flink Load频率,攒批导入
聚合表导入产生大量小文件 调大write_buffer_size,减少小文件数量
无序导入写多Tablet 优化导入数据顺序,避免同时写多个Tablet

3. Join OOM

问题原因 解决方法
大表广播Join 禁用广播:set enable_broadcast_join=false,改用Shuffle Join
左右表顺序搞反 调整SQL,将小表作为右表(构建哈希表)
右表列过多 只查询必要列,避免全列构建哈希表

4. Sort/聚合 OOM

  • Sort OOM:避免无索引全量Sort

  • 聚合OOM:针对大数据聚合时,合理拆分

5. PageCache内存过高

  • 现象:开启PageCache后内存占用高

  • 解决:修改BE配置disable_storage_page_cache=true并重启BE

6. 元数据OOM

  • 原因:版本过多、列过多、Compaction不及时

  • 解决:① 降低导入频率减少版本 ② 拆分宽表(列过多时) ③ 调优Compaction参数加速合并

7. 混合部署内存失控

  • 问题:BE与其他服务混部时内存被抢占

  • 解决:① 手动设置mem_limit=分配给BE的内存比例(如50%) ② 不要用cgroup限制(无效)

8. 夜间11点内存暴涨

  • 原因:默认触发Tablet一致性检查(check_consistency_worker_count=1

  • 解决:修改BE配置check_consistency_worker_count=0并重启BE,关闭检查

你在Doris运维中遇到过哪些奇葩的内存问题?评论区分享你的踩坑经历,一起避坑~

相关推荐
九河云2 小时前
不同级别华为云代理商的增值服务内容与质量差异分析
大数据·服务器·人工智能·科技·华为云
阿里云大数据AI技术2 小时前
【跨国数仓迁移最佳实践 12】阿里云 MaxCompute 实现 BigQuery 10 万条 SQL 智能转写迁移
大数据·sql
Elastic 中国社区官方博客3 小时前
Elasticsearch:Microsoft Azure AI Foundry Agent Service 中用于提供可靠信息和编排的上下文引擎
大数据·人工智能·elasticsearch·microsoft·搜索引擎·全文检索·azure
DolphinScheduler社区3 小时前
结项报告完整版 | 为 Apache DolphinScheduler 添加 gRPC 插件
大数据·开源·apache·海豚调度·大数据工作流调度
学习吖4 小时前
vue中封装的函数常用方法(持续更新)
大数据·javascript·vue.js·ajax·前端框架
Saniffer_SH4 小时前
通过近期测试简单聊一下究竟是直接选择Nvidia Spark还是4090/5090 GPU自建环境
大数据·服务器·图像处理·人工智能·驱动开发·spark·硬件工程
字节跳动数据平台5 小时前
火山引擎多模态数据湖,破解智能驾驶数据处理瓶颈
大数据
weixin79893765432...5 小时前
React 性能优化
react.js·性能优化
龙亘川5 小时前
应急管理数字化转型深度解析:从政策到落地,AI + 大数据如何重塑安全防线(附白皮书 5 页核心干货)
大数据·人工智能·安全·智慧城市·ai + 应急·应急管理数字化·解读技术白皮书