1. Doris资源组管理概述
在OLAP数据库领域,资源隔离一直是个棘手的问题。我管理过多个Doris集群,最头疼的就是某个跑复杂报表的查询把整个集群CPU吃满,导致其他关键业务查询排队超时。直到Doris 1.2版本引入资源组功能,这个问题才有了系统级的解决方案。
资源组(Resource Group)本质上是一种软隔离机制,通过对查询任务进行分类和资源配额管理,实现以下核心目标:
- 防止"流氓查询"耗尽集群资源
- 保障高优先级业务的SLA
- 在多租户场景下实现资源公平分配
举个实际案例:某电商平台将Doris同时用于实时大屏(高优先级)、用户行为分析(中等优先级)和报表导出(低优先级)。通过资源组划分,确保大屏查询永远有足够资源,而导出作业不会影响线上业务。
2. 资源组核心配置详解
2.1 基础参数解析
创建资源组的基本语法如下:
sql复制CREATE RESOURCE GROUP group_name
TO
user1, user2@ip -- 绑定的用户列表
PROPERTIES (
"cpu_share" = "100", -- CPU权重
"memory_limit" = "30%", -- 内存上限
"concurrent_limit" = "20", -- 并发查询数
"max_query_cpu_time_ms" = "10000" -- 单查询CPU时间限制
);
关键参数说明:
- cpu_share:不是绝对值而是相对权重。比如组A配置100,组B配置50,那么当资源争用时,A组能获得2倍的CPU时间片。
- memory_limit:支持绝对值(如"10G")或百分比(如"30%")。实测发现百分比更实用,特别是在K8s环境。
- concurrent_limit:控制并发数而非线程数。一个复杂查询可能用多个线程,但只计为1个并发。
2.2 高级调优技巧
在千万级QPS的生产环境中,我们总结出这些经验:
- 混合负载优化:为短查询设置
"short_query" = "true",这类查询会跳过队列直接执行
sql复制ALTER RESOURCE GROUP adhoc SET PROPERTIES ("short_query" = "true");
- 内存溢出防护:通过
spill_mem_limit_threshold设置内存溢出阈值
sql复制ALTER RESOURCE GROUP etl
SET PROPERTIES ("spill_mem_limit_threshold" = "0.8"); -- 内存使用80%时触发spill
- 分级降级:配置多级fallback组应对突发流量
sql复制-- 主业务组
CREATE RESOURCE GROUP main
PROPERTIES ("cpu_share" = "200", "fallback_group" = "basic");
-- 降级组
CREATE RESOURCE GROUP basic
PROPERTIES ("cpu_share" = "50");
3. 多租户场景实战
3.1 租户隔离方案
某SaaS平台需要为每个客户创建独立资源组,核心配置包括:
- 按租户前缀路由查询
sql复制CREATE RESOURCE GROUP tenant_A
TO "A_*@*" -- 匹配A租户的所有用户
PROPERTIES ("memory_limit" = "10G");
- 动态调整配额(通过外部系统触发)
sql复制-- 白天给分析型租户更多资源
ALTER RESOURCE GROUP bi_tenant
SET PROPERTIES ("cpu_share" = "150");
-- 夜间给ETL租户加配额
ALTER RESOURCE GROUP etl_tenant
SET PROPERTIES ("memory_limit" = "40%");
3.2 监控与弹性伸缩
我们开发了自动化调控系统,关键逻辑包括:
- 实时采集资源组指标
sql复制SHOW RESOURCE GROUP USAGE; -- 获取CPU/内存使用率
- 基于Prometheus的告警规则示例:
yaml复制rules:
- alert: ResourceGroupOOM
expr: doris_be_resource_group_memory_bytes{type="used"} / doris_be_resource_group_memory_bytes{type="limit"} > 0.9
for: 5m
- 自动扩缩容流程:
- 检测到资源组持续超限
- 检查是否有空闲资源
- 执行动态调整(通过Doris Manager API)
4. 常见问题排查手册
4.1 配置不生效排查
现象:修改资源组参数后查询仍不受限
排查步骤:
- 确认FE配置开启资源组
ini复制enable_resource_group = true -- fe.conf关键参数
- 检查参数传播状态
sql复制SHOW PROC "/resource_groups"; -- 查看参数是否同步到BE
- 验证用户绑定关系
sql复制SHOW RESOURCE GROUP user1; -- 查看用户所属组
4.2 内存限制异常
典型报错:Memory limit exceeded for resource group
解决方案:
- 临时调增内存限额
sql复制ALTER RESOURCE GROUP urgent SET PROPERTIES ("memory_limit" = "50%");
- 优化查询(针对大查询)
sql复制-- 添加SQL提示
SELECT /*+ SET_VAR(exec_mem_limit=8589934592) */ * FROM large_table;
- 启用spill to disk
sql复制SET global enable_spilling = true;
4.3 性能调优案例
某金融客户遇到资源组导致的查询延迟增加,通过以下步骤优化:
- 分析等待队列
sql复制SHOW PROC "/current_queries"; -- 查看排队中的查询
- 调整调度算法参数
ini复制resource_group_cpu_share_soft_limit = 0.8 -- be.conf
- 为关键查询添加跳过标记
sql复制SELECT /*+ RESOURCE_GROUP(skip) */ * FROM time_critical_table;
5. 最佳实践总结
经过多个生产集群的验证,我们提炼出这些黄金准则:
-
分级设计:通常设置3层资源组
- 系统组(5%资源):存放内部表
- 关键业务组(60%):核心OLAP查询
- 弹性组(35%):临时分析任务
-
动态调整策略:
- 工作时间(9:00-18:00):OLAP组占70%
- 夜间(18:00-次日9:00):ETL组占60%
- 大促期间:预留组自动扩容
-
监控指标看板:
- 每个资源组的CPU使用率/排队数
- 内存使用量与spill次数
- 查询平均等待时间
-
防雪崩设计:
sql复制-- 设置全局fallback组
SET PROPERTIES ("default_resource_group" = "basic");
-- 配置熔断规则
ALTER RESOURCE GROUP api
SET PROPERTIES ("query_timeout" = "5000"); -- 5秒超时
最后分享一个真实教训:某次误将memory_limit设置为100G(超过物理内存),导致BE节点OOM崩溃。现在我们会强制添加校验规则:
sql复制-- 内存限制不能超过物理内存的80%
CREATE TRIGGER check_memory_limit
BEFORE ALTER ON RESOURCE GROUP
EXECUTE "validate_memory_limit()";
